# coding: utf-8

# (C) Copyright IBM Corp. 2021, 2022, 2023.
#
# 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.80.0-29334a73-20230925-151553

"""
The IBM Cloud Virtual Private Cloud (VPC) API can be used to programmatically provision
and manage virtual server instances, along with subnets, volumes, load balancers, and
more.

API Version: 2023-10-24
"""

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

from ibm_cloud_sdk_core import BaseService, DetailedResponse, get_query_param
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_list, convert_model, datetime_to_string, string_to_datetime

from .common import get_sdk_headers

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


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

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

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

        :param str version: The API version, in format `YYYY-MM-DD`. For the API
               behavior documented here, specify any date between `2023-10-10` and
               `2023-11-15`.
        """
        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 = '2023-10-24',
        authenticator: Authenticator = None,
        generation: int = 2,
    ) -> None:
        """
        Construct a new client for the vpc service.

        :param str version: The API version, in format `YYYY-MM-DD`. For the API
               behavior documented here, specify any date between `2023-10-10` and
               `2023-11-15`.

        :param Authenticator authenticator: The authenticator specifies the authentication mechanism.
               Get up to date information from https://github.com/IBM/python-sdk-core/blob/main/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.generation = generation
        self.version = version

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

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

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

        :param str start: (optional) A server-provided 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 with a `resource_group.id` property matching the specified
               identifier.
        :param bool classic_access: (optional) Filters the collection to VPCs with
               a `classic_access` property matching the specified value.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `VPCCollection` object
        """

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

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

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

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

        response = self.send(request, **kwargs)
        return response

    def create_vpc(
        self,
        *,
        address_prefix_management: str = None,
        classic_access: bool = None,
        dns: 'VPCDNSPrototype' = 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](https://cloud.ibm.com/docs/vpc?topic=vpc-configuring-address-prefixes)
               will be automatically created for each zone in this VPC. If `manual`, this
               VPC will be created with no default address prefixes.
               Since address prefixes are managed identically regardless of whether they
               were automatically created, the value is not preserved as a VPC property.
        :param bool classic_access: (optional) Indicates whether this VPC will 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 VPCDNSPrototype dns: (optional) The DNS configuration for this VPC.
               If unspecified, the system will assign DNS servers capable of resolving
               hosts and endpoint
               gateways within this VPC, and hosts on the internet.
        :param str name: (optional) The name for this VPC. The name must not be
               used by another VPC in the region. 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) will be
               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 dns is not None:
            dns = convert_model(dns)
        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,
            'dns': dns,
            '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'))
            del kwargs['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, **kwargs)
        return response

    def delete_vpc(
        self,
        id: str,
        *,
        if_match: str = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        Delete a VPC.

        This request deletes a VPC. This operation cannot be reversed.
        For this request to succeed:
        - Instances, subnets, public gateways, and endpoint gateways must not reside in
        this VPC
        - The VPC must not be providing DNS resolution for any other VPCs
        - If `dns.enable_hub` is `true`, `dns.resolution_binding_count` must be zero
        All security groups and network ACLs associated with the VPC are automatically
        deleted. All flow log collectors with `auto_delete` set to `true` targeting the
        VPC or any resource in the VPC are automatically deleted.

        :param str id: The VPC identifier.
        :param str if_match: (optional) If present, the request will fail if the
               specified ETag value does not match the resource's current ETag value.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse
        """

        if not id:
            raise ValueError('id must be provided')
        headers = {
            'If-Match': if_match,
        }
        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'))
            del kwargs['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, **kwargs)
        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 not id:
            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'))
            del kwargs['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, **kwargs)
        return response

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

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

        :param str id: The VPC identifier.
        :param VPCPatch vpc_patch: The VPC patch.
        :param str if_match: (optional) If present, the request will fail if the
               specified ETag value does not match the resource's current ETag value.
               Required if the request body includes an array.
        :param dict headers: 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 not id:
            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 = {
            'If-Match': if_match,
        }
        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'))
            del kwargs['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, **kwargs)
        return response

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

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

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

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

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

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

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

        response = self.send(request, **kwargs)
        return response

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

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

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

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

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

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

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

        response = self.send(request, **kwargs)
        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. Resources created in this VPC that allow a security group
        to be optionally specified will use this security group by default.

        :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 not id:
            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'))
            del kwargs['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, **kwargs)
        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-provided 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 not vpc_id:
            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'))
            del kwargs['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, **kwargs)
        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 range must not overlap with any existing address prefixes in
               the VPC or any of the following reserved address ranges:
                 - `127.0.0.0/8` (IPv4 loopback addresses)
                 - `161.26.0.0/16` (IBM services)
                 - `166.8.0.0/14` (Cloud Service Endpoints)
                 - `169.254.0.0/16` (IPv4 link-local addresses)
                 - `224.0.0.0/4` (IPv4 multicast addresses)
               The prefix length of the address prefix's CIDR must be between `/9`
               (8,388,608 addresses) and `/29` (8 addresses).
        :param ZoneIdentity zone: The zone this address prefix will reside in.
        :param bool is_default: (optional) Indicates whether this will be the
               default address prefix for this zone in this VPC. If `true`, the VPC must
               not have a default address prefix for this zone.
        :param str name: (optional) The name for this address prefix. The name must
               not be used by another address prefix for the VPC. 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 not vpc_id:
            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'))
            del kwargs['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, **kwargs)
        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 not vpc_id:
            raise ValueError('vpc_id must be provided')
        if not id:
            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'))
            del kwargs['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, **kwargs)
        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 not vpc_id:
            raise ValueError('vpc_id must be provided')
        if not id:
            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'))
            del kwargs['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, **kwargs)
        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 not vpc_id:
            raise ValueError('vpc_id must be provided')
        if not id:
            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'))
            del kwargs['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, **kwargs)
        return response

    def list_vpc_dns_resolution_bindings(
        self,
        vpc_id: str,
        *,
        sort: str = None,
        start: str = None,
        limit: int = None,
        name: str = None,
        vpc_crn: str = None,
        vpc_name: str = None,
        account_id: str = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        List all DNS resolution bindings for a VPC.

        This request lists all DNS resolution bindings for a VPC. A DNS resolution binding
        represents an association with another VPC for centralizing DNS name resolution.
        If the VPC specified by the identifier in the URL is a DNS hub VPC (has
        `dns.enable_hub` set to `true`) then there is one binding for each VPC bound to
        the hub VPC. The endpoint gateways in the bound VPCs can allow (using
        `allow_dns_resolution_binding`) the hub VPC to centralize resolution of their DNS
        names.
        If the VPC specified by the identifier in the URL is not a DNS hub VPC, then there
        is at most one binding (to a hub VPC). The endpoint gateways in the VPC specified
        by the identifier in the URL can allow (using `allow_dns_resolution_binding`) its
        hub VPC to centralize resolution of their DNS names.
        To make use of centralized DNS resolution, a VPC bound to a DNS hub VPC must
        delegate DNS resolution to its hub VPC by setting `dns.resolver.type` to
        `delegate`.
        The bindings will be sorted by their `created_at` property values, with newest
        bindings first. Bindings with identical `created_at` property values will in turn
        be sorted by ascending `name` property values.

        :param str vpc_id: The VPC identifier.
        :param str sort: (optional) Sorts the returned collection by the specified
               property name in ascending order. A `-` may be prepended to the name to
               sort in descending order. For example, the value `-created_at` sorts the
               collection by the `created_at` property in descending order, and the value
               `name` sorts it by the `name` property in ascending order.
        :param str start: (optional) A server-provided 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 a
               `name` property matching the exact specified name.
        :param str vpc_crn: (optional) Filters the collection to resources with a
               `vpc.crn` property matching the specified CRN.
        :param str vpc_name: (optional) Filters the collection to resources with a
               `vpc.name` property matching the exact specified name.
        :param str account_id: (optional) Filters the collection to resources with
               a `vpc.remote.account.id` property matching the specified account
               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 `VPCDNSResolutionBindingCollection` object
        """

        if not vpc_id:
            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_dns_resolution_bindings',
        )
        headers.update(sdk_headers)

        params = {
            'version': self.version,
            'generation': self.generation,
            'sort': sort,
            'start': start,
            'limit': limit,
            'name': name,
            'vpc.crn': vpc_crn,
            'vpc.name': vpc_name,
            'account.id': account_id,
        }

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
            del kwargs['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}/dns_resolution_bindings'.format(**path_param_dict)
        request = self.prepare_request(
            method='GET',
            url=url,
            headers=headers,
            params=params,
        )

        response = self.send(request, **kwargs)
        return response

    def create_vpc_dns_resolution_binding(
        self,
        vpc_id: str,
        vpc: 'VPCIdentity',
        *,
        name: str = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        Create a DNS resolution binding.

        This request creates a new DNS resolution binding from a DNS resolution binding
        prototype object. The prototype object is structured in the same way as a
        retrieved DNS resolution binding, and contains the information necessary to create
        the new DNS resolution binding.
        For this request to succeed, `dns.enable_hub` must be `false` for the VPC
        specified by the identifier in the URL, and the VPC must not already have a DNS
        resolution binding.
        See [About DNS sharing for VPE gateways](/docs/vpc?topic=vpc-hub-spoke-model) for
        more information.

        :param str vpc_id: The VPC identifier.
        :param VPCIdentity vpc: Another VPC to bind this VPC to for DNS resolution.
               The VPC must have
               `dns.enable_hub` set to `true`, and may be in a different account (subject
               to
               IAM policies).
               Additionally, the VPC specified in the URL (this VPC) must have
               `dns.enable_hub`
               set to `false` and a `dns.resolution_binding_count` of zero.
        :param str name: (optional) The name for this DNS resolution binding. The
               name must not be used by another DNS resolution binding for the VPC. 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 `VPCDNSResolutionBinding` object
        """

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

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

        data = {
            'vpc': vpc,
            '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'))
            del kwargs['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}/dns_resolution_bindings'.format(**path_param_dict)
        request = self.prepare_request(
            method='POST',
            url=url,
            headers=headers,
            params=params,
            data=data,
        )

        response = self.send(request, **kwargs)
        return response

    def delete_vpc_dns_resolution_binding(
        self,
        vpc_id: str,
        id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Delete a DNS resolution binding.

        This request deletes a DNS resolution binding. This operation cannot be reversed.
        A DNS resolution binding for a VPC with `dns.enable_hub` set to `true` cannot be
        deleted.

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

        if not vpc_id:
            raise ValueError('vpc_id must be provided')
        if not id:
            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_dns_resolution_binding',
        )
        headers.update(sdk_headers)

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

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
            del kwargs['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}/dns_resolution_bindings/{id}'.format(**path_param_dict)
        request = self.prepare_request(
            method='DELETE',
            url=url,
            headers=headers,
            params=params,
        )

        response = self.send(request, **kwargs)
        return response

    def get_vpc_dns_resolution_binding(
        self,
        vpc_id: str,
        id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Retrieve a DNS resolution binding.

        This request retrieves a single DNS resolution binding specified by the identifier
        in the URL.

        :param str vpc_id: The VPC identifier.
        :param str id: The DNS resolution binding 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 `VPCDNSResolutionBinding` object
        """

        if not vpc_id:
            raise ValueError('vpc_id must be provided')
        if not id:
            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_dns_resolution_binding',
        )
        headers.update(sdk_headers)

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

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
            del kwargs['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}/dns_resolution_bindings/{id}'.format(**path_param_dict)
        request = self.prepare_request(
            method='GET',
            url=url,
            headers=headers,
            params=params,
        )

        response = self.send(request, **kwargs)
        return response

    def update_vpc_dns_resolution_binding(
        self,
        vpc_id: str,
        id: str,
        vpcdns_resolution_binding_patch: 'VPCDNSResolutionBindingPatch',
        **kwargs,
    ) -> DetailedResponse:
        """
        Update a DNS resolution binding.

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

        :param str vpc_id: The VPC identifier.
        :param str id: The DNS resolution binding identifier.
        :param VPCDNSResolutionBindingPatch vpcdns_resolution_binding_patch: The
               DNS resolution binding 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 `VPCDNSResolutionBinding` object
        """

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

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

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

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
            del kwargs['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}/dns_resolution_bindings/{id}'.format(**path_param_dict)
        request = self.prepare_request(
            method='PATCH',
            url=url,
            headers=headers,
            params=params,
            data=data,
        )

        response = self.send(request, **kwargs)
        return response

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

        This request lists all routes in the VPC's default routing table. Each route is
        zone-specific and directs any packets matching its destination CIDR block to a
        `next_hop` IP address. The most specific route matching a packet's destination
        will be used. If multiple equally-specific routes exist, traffic will be
        distributed across them.

        :param str vpc_id: The VPC identifier.
        :param str zone_name: (optional) Filters the collection to resources with a
               `zone.name` property matching the exact specified name.
        :param str start: (optional) A server-provided 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 `RouteCollectionVPCContext` object

        Deprecated: this method is deprecated and may be removed in a future release.
        """

        logging.warning('A deprecated operation has been invoked: list_vpc_routes')

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

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

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
            del kwargs['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, **kwargs)
        return response

    def create_vpc_route(
        self,
        vpc_id: str,
        destination: str,
        zone: 'ZoneIdentity',
        *,
        action: str = None,
        name: str = None,
        next_hop: 'RoutePrototypeNextHop' = None,
        priority: int = 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 CIDR of the route. The host
               identifier in the CIDR must be zero.
               At most two routes per `zone` in a table can have the same `destination`
               and
               `priority`, and only if both routes have an `action` of `deliver` and the
               `next_hop` is an IP address.
        :param ZoneIdentity zone: The zone to apply the route to. (Traffic from
               subnets in this zone will be
               subject to this route.).
        :param str action: (optional) The action to perform with a packet matching
               the route:
               - `delegate`: delegate to system-provided routes
               - `delegate_vpc`: delegate to system-provided routes, ignoring
               Internet-bound routes
               - `deliver`: deliver the packet to the specified `next_hop`
               - `drop`: drop the packet.
        :param str name: (optional) The name for this route. The name must not be
               used by another route in the routing table. Names starting with `ibm-` are
               reserved for system-provided routes, and are not allowed. If unspecified,
               the name will be a hyphenated list of randomly-selected words.
        :param RoutePrototypeNextHop next_hop: (optional) If `action` is `deliver`,
               the next hop that packets will be delivered to. For other
               `action` values, it must be omitted or specified as `0.0.0.0`.
               At most two routes per `zone` in a table can have the same `destination`
               and `priority`,
               and only when each route has an `action` of `deliver` and `next_hop` is an
               IP address.
        :param int priority: (optional) The priority of this route. Smaller values
               have higher priority.
               If a routing table contains multiple routes with the same `zone` and
               `destination`, the route with the highest priority (smallest value) is
               selected. If two routes have the same `destination` and `priority`, traffic
               is distributed between them.
        :param dict headers: 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

        Deprecated: this method is deprecated and may be removed in a future release.
        """

        logging.warning('A deprecated operation has been invoked: create_vpc_route')

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

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

        data = {
            'destination': destination,
            'zone': zone,
            'action': action,
            'name': name,
            'next_hop': next_hop,
            'priority': priority,
        }
        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'))
            del kwargs['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, **kwargs)
        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

        Deprecated: this method is deprecated and may be removed in a future release.
        """

        logging.warning('A deprecated operation has been invoked: delete_vpc_route')

        if not vpc_id:
            raise ValueError('vpc_id must be provided')
        if not id:
            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'))
            del kwargs['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, **kwargs)
        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

        Deprecated: this method is deprecated and may be removed in a future release.
        """

        logging.warning('A deprecated operation has been invoked: get_vpc_route')

        if not vpc_id:
            raise ValueError('vpc_id must be provided')
        if not id:
            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'))
            del kwargs['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, **kwargs)
        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

        Deprecated: this method is deprecated and may be removed in a future release.
        """

        logging.warning('A deprecated operation has been invoked: update_vpc_route')

        if not vpc_id:
            raise ValueError('vpc_id must be provided')
        if not id:
            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'))
            del kwargs['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, **kwargs)
        return response

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

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

        :param str vpc_id: The VPC identifier.
        :param str start: (optional) A server-provided token determining what
               resource to start the page on.
        :param int limit: (optional) The number of resources to return on a page.
        :param bool is_default: (optional) Filters the collection to routing tables
               with an `is_default` property matching the specified value.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `RoutingTableCollection` object
        """

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

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

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

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

        response = self.send(request, **kwargs)
        return response

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

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

        :param str vpc_id: The VPC identifier.
        :param List[ResourceFilter] accept_routes_from: (optional) The filters
               specifying the resources that may create routes in this routing table.
               At present, only the `resource_type` filter is permitted, and only the
               `vpn_server` value is supported, but filter support is expected to expand
               in the future.
        :param str name: (optional) The name for this routing table. The name must
               not be used by another routing table in the VPC. If unspecified, the name
               will be a hyphenated list of randomly-selected words.
        :param bool route_direct_link_ingress: (optional) If set to `true`, this
               routing table will be used to route traffic that originates from [Direct
               Link](https://cloud.ibm.com/docs/dl) to this VPC. The VPC must not already
               have a routing table with this property set to `true`.
               Incoming traffic will be routed according to the routing table with one
               exception: routes with an `action` of `deliver` are treated as `drop`
               unless the `next_hop` is an IP address in a subnet in the route's `zone`
               that is able to accept traffic. Therefore, if an incoming packet matches a
               route with a `next_hop` of a VPN gateway connection, the packet will be
               dropped.
               If [Classic
               Access](https://cloud.ibm.com/docs/vpc?topic=vpc-setting-up-access-to-classic-infrastructure)
               is enabled for this VPC, and this property is set to `true`, its incoming
               traffic will also be routed according to this routing table.
        :param bool route_internet_ingress: (optional) If set to `true`, this
               routing table will be used to route traffic that originates from the
               internet. For this to succeed, the VPC must not already have a routing
               table with this property set to `true`.
               Incoming traffic will be routed according to the routing table with two
               exceptions:
               - Traffic destined for IP addresses associated with public gateways will
               not be
                 subject to routes in this routing table.
               - Routes with an `action` of `deliver` are treated as `drop` unless the
               `next_hop` is
                 an IP address in a subnet in the route's `zone` that is able to accept
               traffic.
                 Therefore, if an incoming packet matches a route with a `next_hop` of a
               VPN gateway
                 connection, the packet will be dropped.
        :param bool route_transit_gateway_ingress: (optional) If set to `true`,
               this routing table will be used to route traffic that originates from
               [Transit Gateway](https://cloud.ibm.com/docs/transit-gateway) to this VPC.
               The VPC must not already have a routing table with this property set to
               `true`.
               Incoming traffic will be routed according to the routing table with one
               exception: routes with an `action` of `deliver` are treated as `drop`
               unless the `next_hop` is an IP address in a subnet in the route's `zone`
               that is able to accept traffic. Therefore, if an incoming packet matches a
               route with a `next_hop` of a VPN gateway connection, the packet will be
               dropped.
        :param bool route_vpc_zone_ingress: (optional) If set to `true`, this
               routing table will be used to route traffic that originates from subnets in
               other zones in this VPC. The VPC must not already have a routing table with
               this property set to `true`.
               Incoming traffic will be routed according to the routing table with one
               exception: routes with an `action` of `deliver` are treated as `drop`
               unless the `next_hop` is an IP address in a subnet in the route's `zone`
               that is able to accept traffic. Therefore, if an incoming packet matches a
               route with a `next_hop` of a VPN gateway connection, the packet will be
               dropped.
        :param List[RoutePrototype] routes: (optional) The prototype objects for
               routes to create for this routing table. If unspecified, the routing table
               will be created with no routes.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `RoutingTable` object
        """

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

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

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

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

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

        response = self.send(request, **kwargs)
        return response

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

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

        :param str vpc_id: The VPC identifier.
        :param str id: The routing table identifier.
        :param str if_match: (optional) If present, the request will fail if the
               specified ETag value does not match the resource's current ETag value.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse
        """

        if not vpc_id:
            raise ValueError('vpc_id must be provided')
        if not id:
            raise ValueError('id must be provided')
        headers = {
            'If-Match': if_match,
        }
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='delete_vpc_routing_table',
        )
        headers.update(sdk_headers)

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

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
            del kwargs['headers']

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

        response = self.send(request, **kwargs)
        return response

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

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

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

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

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

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

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

        response = self.send(request, **kwargs)
        return response

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

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

        :param str vpc_id: The VPC identifier.
        :param str id: The routing table identifier.
        :param RoutingTablePatch routing_table_patch: The routing table patch.
        :param str if_match: (optional) If present, the request will fail if the
               specified ETag value does not match the resource's current ETag value.
               Required if the request body includes an array.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `RoutingTable` object
        """

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

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

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

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

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

        response = self.send(request, **kwargs)
        return response

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

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

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

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

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

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

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

        response = self.send(request, **kwargs)
        return response

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

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

        :param str vpc_id: The VPC identifier.
        :param str routing_table_id: The routing table identifier.
        :param str destination: The destination CIDR of the route. The host
               identifier in the CIDR must be zero.
               At most two routes per `zone` in a table can have the same `destination`
               and
               `priority`, and only if both routes have an `action` of `deliver` and the
               `next_hop` is an IP address.
        :param ZoneIdentity zone: The zone to apply the route to. (Traffic from
               subnets in this zone will be
               subject to this route.).
        :param str action: (optional) The action to perform with a packet matching
               the route:
               - `delegate`: delegate to system-provided routes
               - `delegate_vpc`: delegate to system-provided routes, ignoring
               Internet-bound routes
               - `deliver`: deliver the packet to the specified `next_hop`
               - `drop`: drop the packet.
        :param str name: (optional) The name for this route. The name must not be
               used by another route in the routing table. Names starting with `ibm-` are
               reserved for system-provided routes, and are not allowed. If unspecified,
               the name will be a hyphenated list of randomly-selected words.
        :param RoutePrototypeNextHop next_hop: (optional) If `action` is `deliver`,
               the next hop that packets will be delivered to. For other
               `action` values, it must be omitted or specified as `0.0.0.0`.
               At most two routes per `zone` in a table can have the same `destination`
               and `priority`,
               and only when each route has an `action` of `deliver` and `next_hop` is an
               IP address.
        :param int priority: (optional) The priority of this route. Smaller values
               have higher priority.
               If a routing table contains multiple routes with the same `zone` and
               `destination`, the route with the highest priority (smallest value) is
               selected. If two routes have the same `destination` and `priority`, traffic
               is distributed between them.
        :param dict headers: 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 not vpc_id:
            raise ValueError('vpc_id must be provided')
        if not routing_table_id:
            raise ValueError('routing_table_id must be provided')
        if destination is None:
            raise ValueError('destination must be provided')
        if zone is None:
            raise ValueError('zone must be provided')
        zone = convert_model(zone)
        if next_hop is not None:
            next_hop = convert_model(next_hop)
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='create_vpc_routing_table_route',
        )
        headers.update(sdk_headers)

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

        data = {
            'destination': destination,
            'zone': zone,
            'action': action,
            'name': name,
            'next_hop': next_hop,
            'priority': priority,
        }
        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'))
            del kwargs['headers']
        headers['Accept'] = 'application/json'

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

        response = self.send(request, **kwargs)
        return response

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

        This request deletes a VPC route. This operation cannot be reversed. Only VPC
        routes with an `origin` of `user` are allowed to be deleted.

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

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

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

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
            del kwargs['headers']

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

        response = self.send(request, **kwargs)
        return response

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

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

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

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

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

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

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

        response = self.send(request, **kwargs)
        return response

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

        This request updates a VPC route with the information provided in a route patch
        object. The patch object is structured in the same way as a retrieved VPC route
        and needs to contain only the information to be updated. Only VPC routes with an
        `origin` of `user` are allowed to be updated.

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

        if not vpc_id:
            raise ValueError('vpc_id must be provided')
        if not routing_table_id:
            raise ValueError('routing_table_id must be provided')
        if not id:
            raise ValueError('id must be provided')
        if route_patch is None:
            raise ValueError('route_patch must be provided')
        if isinstance(route_patch, RoutePatch):
            route_patch = convert_model(route_patch)
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='update_vpc_routing_table_route',
        )
        headers.update(sdk_headers)

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

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

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

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

        response = self.send(request, **kwargs)
        return response

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

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

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

        :param str start: (optional) A server-provided 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 with a `resource_group.id` property matching the specified
               identifier.
        :param str zone_name: (optional) Filters the collection to resources with a
               `zone.name` property matching the exact specified name.
        :param str vpc_id: (optional) Filters the collection to resources with a
               `vpc.id` property matching the specified identifier.
        :param str vpc_crn: (optional) Filters the collection to resources with a
               `vpc.crn` property matching the specified CRN.
        :param str vpc_name: (optional) Filters the collection to resources with a
               `vpc.name` property matching the exact specified name.
        :param str routing_table_id: (optional) Filters the collection to subnets
               with a `routing_table.id` property matching the specified identifier.
        :param str routing_table_name: (optional) Filters the collection to subnets
               with a `routing_table.name` property matching 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 `SubnetCollection` object
        """

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

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

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

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

        response = self.send(request, **kwargs)
        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'))
            del kwargs['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, **kwargs)
        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 bare metal server network
        interfaces, instance network interfaces, VPN gateways, or load balancers. A delete
        operation automatically detaches the subnet from any network ACLs, public
        gateways, or endpoint gateways. All flow log collectors with `auto_delete` set to
        `true` targeting the subnet or any resource in the subnet are automatically
        deleted.

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

        if not id:
            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'))
            del kwargs['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, **kwargs)
        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 not id:
            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'))
            del kwargs['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, **kwargs)
        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 not id:
            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'))
            del kwargs['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, **kwargs)
        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 not id:
            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'))
            del kwargs['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, **kwargs)
        return response

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

        This request replaces the existing network ACL for a subnet with the network ACL
        specified in the request body.

        :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 not id:
            raise ValueError('id must be provided')
        if network_acl_identity is None:
            raise ValueError('network_acl_identity must be provided')
        if isinstance(network_acl_identity, NetworkACLIdentity):
            network_acl_identity = convert_model(network_acl_identity)
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='replace_subnet_network_acl',
        )
        headers.update(sdk_headers)

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

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

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
            del kwargs['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, **kwargs)
        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 not id:
            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'))
            del kwargs['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, **kwargs)
        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 not id:
            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'))
            del kwargs['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, **kwargs)
        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 not id:
            raise ValueError('id must be provided')
        if public_gateway_identity is None:
            raise ValueError('public_gateway_identity must be provided')
        if isinstance(public_gateway_identity, PublicGatewayIdentity):
            public_gateway_identity = convert_model(public_gateway_identity)
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='set_subnet_public_gateway',
        )
        headers.update(sdk_headers)

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

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

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
            del kwargs['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, **kwargs)
        return response

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

        This request retrieves the routing table attached to the subnet specified by the
        identifier in the URL.

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

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

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

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

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

        response = self.send(request, **kwargs)
        return response

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

        This request replaces the existing routing table for a subnet with the routing
        table specified in the request body.
        For this request to succeed, the routing table `route_direct_link_ingress`,
        `route_transit_gateway_ingress`, and `route_vpc_zone_ingress` properties must be
        `false`.

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

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

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

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

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

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

        response = self.send(request, **kwargs)
        return response

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

        This request lists all reserved IPs in a subnet. A reserved IP resource will exist
        for every address in the subnet which is not available for use.

        :param str subnet_id: The subnet identifier.
        :param str start: (optional) A server-provided token determining what
               resource to start the page on.
        :param int limit: (optional) The number of resources to return on a page.
        :param str sort: (optional) Sorts the returned collection by the specified
               property name in ascending order. A `-` may be prepended to the name to
               sort in descending order. For example, the value `-created_at` sorts the
               collection by the `created_at` property in descending order, and the value
               `name` sorts it by the `name` property in ascending order.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `ReservedIPCollection` object
        """

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

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

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

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

        response = self.send(request, **kwargs)
        return response

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

        This request reserves an IP address in a subnet. If the provided prototype object
        includes an `address`, the address must not already be reserved.

        :param str subnet_id: The subnet identifier.
        :param str address: (optional) The IP address to reserve, which must not
               already be reserved on the subnet.
               If unspecified, an available address on the subnet will automatically be
               selected.
        :param bool auto_delete: (optional) Indicates whether this reserved IP
               member will be automatically deleted when either
               `target` is deleted, or the reserved IP is unbound. Must be `false` if the
               reserved IP is unbound.
        :param str name: (optional) The name for this reserved IP. The name must
               not be used by another reserved IP in the subnet. Names starting with
               `ibm-` are reserved for provider-owned resources, and are not allowed. If
               unspecified, the name will be a hyphenated list of randomly-selected words.
        :param ReservedIPTargetPrototype target: (optional) The target to bind this
               reserved IP to.  The target must be in the same VPC.
               At present, only endpoint gateway targets are supported.  The endpoint
               gateway must
               not be already bound to a reserved IP in the subnet's zone.
               If unspecified, the reserved IP will be created unbound.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `ReservedIP` object
        """

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

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

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

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

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

        response = self.send(request, **kwargs)
        return response

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

        This request releases a reserved IP. This operation cannot be reversed.
        For this request to succeed, the reserved IP must not be required by another
        resource, such as a bare metal server network interface or instance network
        interface for which it is the primary IP. A provider-owned reserved IP is not
        allowed to be deleted.

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

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

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

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
            del kwargs['headers']

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

        response = self.send(request, **kwargs)
        return response

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

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

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

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

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

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

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

        response = self.send(request, **kwargs)
        return response

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

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

        :param str subnet_id: The subnet identifier.
        :param str id: The reserved IP identifier.
        :param ReservedIPPatch reserved_ip_patch: The reserved IP patch.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `ReservedIP` object
        """

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

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

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

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

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

        response = self.send(request, **kwargs)
        return response

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

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

        This request lists all 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 Cloud Object Storage.

        :param str start: (optional) A server-provided 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 with a `resource_group.id` property matching the specified
               identifier.
        :param str name: (optional) Filters the collection to resources with a
               `name` property matching the exact specified name.
        :param List[str] status: (optional) Filters the collection to images with a
               `status` property matching one of the specified comma-separated values.
        :param str visibility: (optional) Filters the collection to images with a
               `visibility` property matching the specified value.
        :param dict headers: 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,
            'status': convert_list(status),
            'visibility': visibility,
        }

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

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

        response = self.send(request, **kwargs)
        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. If an image is being imported, a
        URL to the image file on object storage must be specified. If an image is being
        created from an existing volume, that volume must be specified.

        :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'))
            del kwargs['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, **kwargs)
        return response

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

        This request deletes an image. Any active image export jobs will be completed
        first. This operation cannot be reversed. A system-provided image is not allowed
        to be deleted. Additionally, an image cannot be deleted if it:
        - has a `status` of `deleting`
        - has a `status` of `pending` with a `status_reasons` code of
        `image_request_in_progress`
        - has `catalog_offering.managed` set to `true`.

        :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 not id:
            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'))
            del kwargs['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, **kwargs)
        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 not id:
            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'))
            del kwargs['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, **kwargs)
        return response

    def update_image(
        self,
        id: str,
        image_patch: 'ImagePatch',
        **kwargs,
    ) -> DetailedResponse:
        """
        Update an image.

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

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

        if not id:
            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'))
            del kwargs['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, **kwargs)
        return response

    def deprecate_image(
        self,
        id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Deprecate an image.

        This request deprecates an image, resulting in its `status` becoming `deprecated`
        and
        `deprecation_at` being set to the current date and time.
        The image must:
        - have a `status` of `available`
        - have `catalog_offering.managed` set to `false`
        - not have `deprecation_at` set
        The image must not have `deprecation_at` set, must have `catalog_offering.managed`
        set to
        `false`, and must have a `status` of `available`.
        A system-provided image is not allowed to be deprecated.

        :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 not id:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='deprecate_image',
        )
        headers.update(sdk_headers)

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

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
            del kwargs['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}/deprecate'.format(**path_param_dict)
        request = self.prepare_request(
            method='POST',
            url=url,
            headers=headers,
            params=params,
        )

        response = self.send(request, **kwargs)
        return response

    def obsolete_image(
        self,
        id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Obsolete an image.

        This request obsoletes an image, resulting in its `status` becoming `obsolete` and
        `obsolescence_at` being set to the current date and time.
        The image must:
        - have a `status` of `available` or `deprecated`
        - have `catalog_offering.managed` set to `false`
        - not have `deprecation_at` set in the future
        - not have `obsolescence_at` set
        A system-provided image is not allowed to be obsoleted.

        :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 not id:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='obsolete_image',
        )
        headers.update(sdk_headers)

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

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
            del kwargs['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}/obsolete'.format(**path_param_dict)
        request = self.prepare_request(
            method='POST',
            url=url,
            headers=headers,
            params=params,
        )

        response = self.send(request, **kwargs)
        return response

    def list_image_export_jobs(
        self,
        image_id: str,
        *,
        name: str = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        List all image export jobs.

        This request lists all export jobs for an image. Each job tracks the exporting of
        the image to another location, such as a bucket within cloud object storage.
        The jobs will be sorted by their `created_at` property values, with newest jobs
        first. Jobs with identical `created_at` property values will in turn be sorted by
        ascending
        `name` property values.

        :param str image_id: The image identifier.
        :param str name: (optional) Filters the collection to resources with a
               `name` property matching 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 `ImageExportJobUnpaginatedCollection` object
        """

        if not image_id:
            raise ValueError('image_id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='list_image_export_jobs',
        )
        headers.update(sdk_headers)

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

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

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

        response = self.send(request, **kwargs)
        return response

    def create_image_export_job(
        self,
        image_id: str,
        storage_bucket: 'CloudObjectStorageBucketIdentity',
        *,
        format: str = None,
        name: str = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        Create an image export job.

        This request creates and queues a new export job for the image specified in the
        URL using the image export job prototype object. The image must be owned by the
        account and be in the `available`, `deprecated`, `obsolete`, or `unusable` state.
        The prototype object is structured in the same way as a retrieved image export
        job, and contains the information necessary to create and queue the new image
        export job.

        :param str image_id: The image identifier.
        :param CloudObjectStorageBucketIdentity storage_bucket: The Cloud Object
               Storage bucket to export the image to. The bucket must exist and an IAM
               service authorization must grant `Image Service for VPC` of
               `VPC Infrastructure Services` writer access to the bucket.
        :param str format: (optional) The format to use for the exported image. If
               the image is encrypted, only `qcow2` is supported.
        :param str name: (optional) The name for this image export job. The name
               must not be used by another export job for the image. If unspecified, the
               name will be a hyphenated list of randomly-selected words prefixed with the
               first 16 characters of the parent image name.
               The exported image object name in Cloud Object Storage
               (`storage_object.name` in the response) will be based on this name. The
               object name will be unique within the bucket.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `ImageExportJob` object
        """

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

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

        data = {
            'storage_bucket': storage_bucket,
            'format': format,
            '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'))
            del kwargs['headers']
        headers['Accept'] = 'application/json'

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

        response = self.send(request, **kwargs)
        return response

    def delete_image_export_job(
        self,
        image_id: str,
        id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Delete an image export job.

        This request deletes an image export job. This operation cannot be reversed. If
        the job has not completed, the job will be canceled, and the incomplete exported
        image object deleted. If the job has completed, the exported image object will not
        be deleted.

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

        if not image_id:
            raise ValueError('image_id must be provided')
        if not id:
            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_export_job',
        )
        headers.update(sdk_headers)

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

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
            del kwargs['headers']

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

        response = self.send(request, **kwargs)
        return response

    def get_image_export_job(
        self,
        image_id: str,
        id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Retrieve an image export job.

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

        :param str image_id: The image identifier.
        :param str id: The image export job 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 `ImageExportJob` object
        """

        if not image_id:
            raise ValueError('image_id must be provided')
        if not id:
            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_export_job',
        )
        headers.update(sdk_headers)

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

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

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

        response = self.send(request, **kwargs)
        return response

    def update_image_export_job(
        self,
        image_id: str,
        id: str,
        image_export_job_patch: 'ImageExportJobPatch',
        **kwargs,
    ) -> DetailedResponse:
        """
        Update an image export job.

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

        :param str image_id: The image identifier.
        :param str id: The image export job identifier.
        :param ImageExportJobPatch image_export_job_patch: The image export job
               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 `ImageExportJob` object
        """

        if not image_id:
            raise ValueError('image_id must be provided')
        if not id:
            raise ValueError('id must be provided')
        if image_export_job_patch is None:
            raise ValueError('image_export_job_patch must be provided')
        if isinstance(image_export_job_patch, ImageExportJobPatch):
            image_export_job_patch = convert_model(image_export_job_patch)
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='update_image_export_job',
        )
        headers.update(sdk_headers)

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

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

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

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

        response = self.send(request, **kwargs)
        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-provided 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'))
            del kwargs['headers']
        headers['Accept'] = 'application/json'

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

        response = self.send(request, **kwargs)
        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 not name:
            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'))
            del kwargs['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, **kwargs)
        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-provided 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'))
            del kwargs['headers']
        headers['Accept'] = 'application/json'

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

        response = self.send(request, **kwargs)
        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, in OpenSSH format
               (consisting of three space-separated fields: the algorithm name,
               base64-encoded key, and a comment). The algorithm and comment fields may be
               omitted, as only the key field is imported.
               Keys of type `rsa` may be 2048 or 4096 bits in length, however 4096 is
               recommended. Keys of type `ed25519` are 256 bits in length.
        :param str name: (optional) The name for this key. The name must not be
               used by another key in the region. 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) will be
               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'))
            del kwargs['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, **kwargs)
        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 not id:
            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'))
            del kwargs['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, **kwargs)
        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 not id:
            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'))
            del kwargs['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, **kwargs)
        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 not id:
            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'))
            del kwargs['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, **kwargs)
        return response

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

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

        This request lists provisionable [instance
        profiles](https://cloud.ibm.com/docs/vpc?topic=vpc-profiles) in the region. An
        instance profile specifies the performance characteristics and pricing model for
        an instance.

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

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

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

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

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

        response = self.send(request, **kwargs)
        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 not name:
            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'))
            del kwargs['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, **kwargs)
        return response

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

        This request lists all instance templates in the region.

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

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

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

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

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

        response = self.send(request, **kwargs)
        return response

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

        This request creates a new instance template. The prototype object is structured
        in the same way as a retrieved instance template, and contains the information
        necessary to provision a new instance from the template.
        If a `source_template` is specified in the prototype object, its contents are
        copied into the new template prior to copying any other properties provided in the
        prototype object.

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

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

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

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

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

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

        response = self.send(request, **kwargs)
        return response

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

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

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

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

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

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
            del kwargs['headers']

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

        response = self.send(request, **kwargs)
        return response

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

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

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

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

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

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

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

        response = self.send(request, **kwargs)
        return response

    def update_instance_template(
        self,
        id: str,
        instance_template_patch: 'InstanceTemplatePatch',
        **kwargs,
    ) -> DetailedResponse:
        """
        Update an instance template.

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

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

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

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

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

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

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

        response = self.send(request, **kwargs)
        return response

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

        This request lists all instances in the region.

        :param str start: (optional) A server-provided 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 with a `resource_group.id` property matching the specified
               identifier.
        :param str name: (optional) Filters the collection to resources with a
               `name` property matching the exact specified name.
        :param str vpc_id: (optional) Filters the collection to resources with a
               `vpc.id` property matching the specified identifier.
        :param str vpc_crn: (optional) Filters the collection to resources with a
               `vpc.crn` property matching the specified CRN.
        :param str vpc_name: (optional) Filters the collection to resources with a
               `vpc.name` property matching the exact specified name.
        :param str dedicated_host_id: (optional) Filters the collection to
               instances with a `dedicated_host.id` property matching the specified
               identifier.
        :param str dedicated_host_crn: (optional) Filters the collection to
               instances with a `dedicated_host.crn` property matching the specified CRN.
        :param str dedicated_host_name: (optional) Filters the collection to
               instances with a `dedicated_host.name` property matching the exact
               specified name.
        :param str placement_group_id: (optional) Filters the collection to
               instances with a `placement_target.id` property matching the specified
               placement group identifier.
        :param str placement_group_crn: (optional) Filters the collection to
               instances with a `placement_target.crn` property matching the specified
               placement group CRN.
        :param str placement_group_name: (optional) Filters the collection to
               instances with a `placement_target.name` property matching the exact
               specified placement group name.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `InstanceCollection` object
        """

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

        params = {
            'version': self.version,
            'generation': self.generation,
            'start': start,
            'limit': limit,
            'resource_group.id': resource_group_id,
            'name': name,
            'vpc.id': vpc_id,
            'vpc.crn': vpc_crn,
            'vpc.name': vpc_name,
            'dedicated_host.id': dedicated_host_id,
            'dedicated_host.crn': dedicated_host_crn,
            'dedicated_host.name': dedicated_host_name,
            'placement_group.id': placement_group_id,
            'placement_group.crn': placement_group_crn,
            'placement_group.name': placement_group_name,
        }

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

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

        response = self.send(request, **kwargs)
        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'))
            del kwargs['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, **kwargs)
        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 instance network interfaces are implicitly disassociated. All
        flow log collectors with `auto_delete` set to `true` targeting the instance and/or
        the instance network interfaces are automatically deleted.

        :param str id: The virtual server 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 not id:
            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'))
            del kwargs['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, **kwargs)
        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 virtual server 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 not id:
            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'))
            del kwargs['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, **kwargs)
        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 virtual server 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 not id:
            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'))
            del kwargs['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, **kwargs)
        return response

    def get_instance_initialization(
        self,
        id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Retrieve initialization configuration for an instance.

        This request retrieves configuration used to initialize the instance, such as SSH
        keys and the Windows administrator password. These can subsequently be changed on
        the instance and therefore may not be current.

        :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 not id:
            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'))
            del kwargs['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, **kwargs)
        return response

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

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

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

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

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

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

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
            del kwargs['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, **kwargs)
        return response

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

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

        :param str instance_id: The virtual server instance identifier.
        :param str console_type: The instance console type for which this token may
               be used.
        :param bool force: (optional) Indicates whether to disconnect an existing
               serial console session as the serial console cannot be shared.  This has no
               effect on VNC consoles.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `InstanceConsoleAccessToken` object
        """

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

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

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

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

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

        response = self.send(request, **kwargs)
        return response

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

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

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

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

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

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

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

        response = self.send(request, **kwargs)
        return response

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

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

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

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

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

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

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

        response = self.send(request, **kwargs)
        return response

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

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

        :param str instance_id: The virtual server instance identifier.
        :param str id: The instance disk identifier.
        :param InstanceDiskPatch instance_disk_patch: The instance disk patch.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `InstanceDisk` object
        """

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

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

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

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

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

        response = self.send(request, **kwargs)
        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. An instance network
        interface is an abstract representation of a network device and attaches an
        instance to a single subnet. Each network interface on an instance can attach to
        any subnet in the zone, including subnets that are already attached to the
        instance. Multiple network interfaces on the instance may also attach to the same
        subnet.

        :param str instance_id: The virtual server 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 not instance_id:
            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'))
            del kwargs['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, **kwargs)
        return response

    def create_instance_network_interface(
        self,
        instance_id: str,
        subnet: 'SubnetIdentity',
        *,
        allow_ip_spoofing: bool = None,
        name: str = None,
        primary_ip: 'NetworkInterfaceIPPrototype' = None,
        security_groups: List['SecurityGroupIdentity'] = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        Create a network interface on an instance.

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

        :param str instance_id: The virtual server instance identifier.
        :param SubnetIdentity subnet: The associated subnet.
        :param bool allow_ip_spoofing: (optional) Indicates whether source IP
               spoofing is allowed on this instance network interface.
        :param str name: (optional) The name for the instance network interface.
               The name must not be used by another network interface on the virtual
               server instance. If unspecified, the name will be a hyphenated list of
               randomly-selected words.
        :param NetworkInterfaceIPPrototype primary_ip: (optional) The primary IP
               address to bind to the instance network interface. This can be
               specified using an existing reserved IP, or a prototype object for a new
               reserved IP.
               If an existing reserved IP or a prototype object with an address is
               specified, it must
               be available on the instance network interface's subnet. Otherwise, an
               available address on the subnet will be automatically selected and
               reserved.
        :param List[SecurityGroupIdentity] security_groups: (optional) The security
               groups to use for this instance network interface. If unspecified, the
               VPC's default security group 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 `NetworkInterface` object
        """

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

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

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

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

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

        response = self.send(request, **kwargs)
        return response

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

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

        :param str instance_id: The virtual server instance identifier.
        :param str id: The instance 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 not instance_id:
            raise ValueError('instance_id must be provided')
        if not id:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='delete_instance_network_interface',
        )
        headers.update(sdk_headers)

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

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
            del kwargs['headers']

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

        response = self.send(request, **kwargs)
        return response

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

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

        :param str instance_id: The virtual server instance identifier.
        :param str id: The instance 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 not instance_id:
            raise ValueError('instance_id must be provided')
        if not id:
            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'))
            del kwargs['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, **kwargs)
        return response

    def update_instance_network_interface(
        self,
        instance_id: str,
        id: str,
        network_interface_patch: 'NetworkInterfacePatch',
        **kwargs,
    ) -> DetailedResponse:
        """
        Update an instance network interface.

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

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

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

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

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

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

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

        response = self.send(request, **kwargs)
        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 an instance network interface.

        This request lists all floating IPs associated with an instance network interface.

        :param str instance_id: The virtual server instance identifier.
        :param str network_interface_id: The instance 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 not instance_id:
            raise ValueError('instance_id must be provided')
        if not network_interface_id:
            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'))
            del kwargs['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, **kwargs)
        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 an instance network interface.

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

        :param str instance_id: The virtual server instance identifier.
        :param str network_interface_id: The instance 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 not instance_id:
            raise ValueError('instance_id must be provided')
        if not network_interface_id:
            raise ValueError('network_interface_id must be provided')
        if not id:
            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'))
            del kwargs['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, **kwargs)
        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 retrieves a specified floating IP address if it is associated with
        the instance network interface and instance specified in the URL.

        :param str instance_id: The virtual server instance identifier.
        :param str network_interface_id: The instance 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 not instance_id:
            raise ValueError('instance_id must be provided')
        if not network_interface_id:
            raise ValueError('network_interface_id must be provided')
        if not id:
            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'))
            del kwargs['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, **kwargs)
        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 an instance network interface.

        This request associates the specified floating IP with the specified instance
        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 provided, is ignored.

        :param str instance_id: The virtual server instance identifier.
        :param str network_interface_id: The instance 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 not instance_id:
            raise ValueError('instance_id must be provided')
        if not network_interface_id:
            raise ValueError('network_interface_id must be provided')
        if not id:
            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'))
            del kwargs['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, **kwargs)
        return response

    def list_instance_network_interface_ips(
        self,
        instance_id: str,
        network_interface_id: str,
        *,
        start: str = None,
        limit: int = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        List the primary reserved IP for an instance network interface.

        This request lists the primary reserved IP for an instance network interface.

        :param str instance_id: The virtual server instance identifier.
        :param str network_interface_id: The instance network interface identifier.
        :param str start: (optional) A server-provided 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 `ReservedIPCollectionInstanceNetworkInterfaceContext` object
        """

        if not instance_id:
            raise ValueError('instance_id must be provided')
        if not network_interface_id:
            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_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'))
            del kwargs['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}/ips'.format(**path_param_dict)
        request = self.prepare_request(
            method='GET',
            url=url,
            headers=headers,
            params=params,
        )

        response = self.send(request, **kwargs)
        return response

    def get_instance_network_interface_ip(
        self,
        instance_id: str,
        network_interface_id: str,
        id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Retrieve the primary reserved IP.

        This request retrieves the primary reserved IP for an instance network interface.

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

        if not instance_id:
            raise ValueError('instance_id must be provided')
        if not network_interface_id:
            raise ValueError('network_interface_id must be provided')
        if not id:
            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_ip',
        )
        headers.update(sdk_headers)

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

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
            del kwargs['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}/ips/{id}'.format(**path_param_dict)
        request = self.prepare_request(
            method='GET',
            url=url,
            headers=headers,
            params=params,
        )

        response = self.send(request, **kwargs)
        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 virtual server 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 not instance_id:
            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'))
            del kwargs['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, **kwargs)
        return response

    def create_instance_volume_attachment(
        self,
        instance_id: str,
        volume: 'VolumeAttachmentPrototypeVolume',
        *,
        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, connecting a volume to an instance. For this request to succeed, the
        specified volume must not be busy. 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.

        :param str instance_id: The virtual server instance identifier.
        :param VolumeAttachmentPrototypeVolume volume: An existing volume to attach
               to the instance, or a prototype object for a new volume.
        :param bool delete_volume_on_instance_delete: (optional) Indicates whether
               deleting the instance will also delete the attached volume.
        :param str name: (optional) The name for this volume attachment. The name
               must not be used by another volume attachment on the instance. 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 not instance_id:
            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'))
            del kwargs['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, **kwargs)
        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. This operation cannot be reversed, but a
        new volume attachment may subsequently be created for the volume.  For this
        request to succeed, the volume must not be busy.

        :param str instance_id: The virtual server 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 not instance_id:
            raise ValueError('instance_id must be provided')
        if not id:
            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'))
            del kwargs['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, **kwargs)
        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 virtual server 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 not instance_id:
            raise ValueError('instance_id must be provided')
        if not id:
            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'))
            del kwargs['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, **kwargs)
        return response

    def update_instance_volume_attachment(
        self,
        instance_id: str,
        id: str,
        volume_attachment_patch: 'VolumeAttachmentPatch',
        **kwargs,
    ) -> DetailedResponse:
        """
        Update a volume attachment.

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

        :param str instance_id: The virtual server 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 not instance_id:
            raise ValueError('instance_id must be provided')
        if not id:
            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'))
            del kwargs['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, **kwargs)
        return response

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

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

        This request lists all instance groups in the region.

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

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

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

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

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

        response = self.send(request, **kwargs)
        return response

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

        This request creates a new instance group.

        :param InstanceTemplateIdentity instance_template: Instance template to use
               when creating new instances.
               Instance groups are not compatible with instance templates that specify
               `true` for
               `default_trusted_profile.auto_link`.
        :param List[SubnetIdentity] subnets: The subnets to use when creating new
               instances.
        :param int application_port: (optional) The port to use for new load
               balancer pool members created by this instance group. The load balancer
               pool member will receive load balancer traffic on this port, unless the
               load balancer listener is using a port range. (Traffic received on a
               listener using a port range will be sent to members using the same port the
               listener received it on.)
               This port will also be used for health checks unless the port property of
               `health_monitor` property is specified.
               This property must be specified if and only if `load_balancer_pool` has
               been specified.
        :param LoadBalancerIdentity load_balancer: (optional) The load balancer
               associated with the specified load balancer pool.
               Required if `load_balancer_pool` is specified. The load balancer must have
               `instance_groups_supported` set to `true`.
        :param LoadBalancerPoolIdentity load_balancer_pool: (optional) If
               specified, this instance group will manage the load balancer pool. A pool
               member
               will be created for each instance created by this group.  The specified
               load
               balancer pool must not be used by another instance group in the VPC.
               If specified, `load_balancer` and `application_port` must also be
               specified.
        :param int membership_count: (optional) The number of instances in the
               instance group.
        :param str name: (optional) The name for this instance group. The name must
               not be used by another instance group in the region. 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) will be
               used.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `InstanceGroup` object
        """

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

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

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

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

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

        response = self.send(request, **kwargs)
        return response

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

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

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

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

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

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
            del kwargs['headers']

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

        response = self.send(request, **kwargs)
        return response

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

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

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

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

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

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

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

        response = self.send(request, **kwargs)
        return response

    def update_instance_group(
        self,
        id: str,
        instance_group_patch: 'InstanceGroupPatch',
        **kwargs,
    ) -> DetailedResponse:
        """
        Update an instance group.

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

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

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

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

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

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

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

        response = self.send(request, **kwargs)
        return response

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

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

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

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

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

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
            del kwargs['headers']

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

        response = self.send(request, **kwargs)
        return response

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

        This request lists all managers for an instance group.

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

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

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

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

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

        response = self.send(request, **kwargs)
        return response

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

        This request creates a new instance group manager.

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

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

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

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

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

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

        response = self.send(request, **kwargs)
        return response

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

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

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

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

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

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
            del kwargs['headers']

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

        response = self.send(request, **kwargs)
        return response

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

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

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

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

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

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

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

        response = self.send(request, **kwargs)
        return response

    def update_instance_group_manager(
        self,
        instance_group_id: str,
        id: str,
        instance_group_manager_patch: 'InstanceGroupManagerPatch',
        **kwargs,
    ) -> DetailedResponse:
        """
        Update an instance group manager.

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

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

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

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

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

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

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

        response = self.send(request, **kwargs)
        return response

    def list_instance_group_manager_actions(
        self,
        instance_group_id: str,
        instance_group_manager_id: str,
        *,
        start: str = None,
        limit: int = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        List all actions for an instance group manager.

        This request lists all instance group actions for an instance group manager.

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

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

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

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

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

        response = self.send(request, **kwargs)
        return response

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

        This request creates a new instance group manager action.

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

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

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

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

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

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

        response = self.send(request, **kwargs)
        return response

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

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

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

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

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

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
            del kwargs['headers']

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

        response = self.send(request, **kwargs)
        return response

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

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

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

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

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

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

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

        response = self.send(request, **kwargs)
        return response

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

        This request updates an instance group manager action.

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

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

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

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

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

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

        response = self.send(request, **kwargs)
        return response

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

        This request lists all policies for an instance group manager.

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

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

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

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

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

        response = self.send(request, **kwargs)
        return response

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

        This request creates a new instance group manager policy.

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

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

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

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

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

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

        response = self.send(request, **kwargs)
        return response

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

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

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

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

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

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
            del kwargs['headers']

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

        response = self.send(request, **kwargs)
        return response

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

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

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

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

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

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

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

        response = self.send(request, **kwargs)
        return response

    def update_instance_group_manager_policy(
        self,
        instance_group_id: str,
        instance_group_manager_id: str,
        id: str,
        instance_group_manager_policy_patch: 'InstanceGroupManagerPolicyPatch',
        **kwargs,
    ) -> DetailedResponse:
        """
        Update an instance group manager policy.

        This request updates an instance group manager policy.

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

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

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

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

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

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

        response = self.send(request, **kwargs)
        return response

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

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

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

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

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

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
            del kwargs['headers']

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

        response = self.send(request, **kwargs)
        return response

    def list_instance_group_memberships(
        self,
        instance_group_id: str,
        *,
        start: str = None,
        limit: int = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        List all memberships for an instance group.

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

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

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

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

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

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

        response = self.send(request, **kwargs)
        return response

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

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

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

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

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

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
            del kwargs['headers']

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

        response = self.send(request, **kwargs)
        return response

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

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

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

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

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

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

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

        response = self.send(request, **kwargs)
        return response

    def update_instance_group_membership(
        self,
        instance_group_id: str,
        id: str,
        instance_group_membership_patch: 'InstanceGroupMembershipPatch',
        **kwargs,
    ) -> DetailedResponse:
        """
        Update an instance group membership.

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

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

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

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

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

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

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

        response = self.send(request, **kwargs)
        return response

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

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

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

        :param str start: (optional) A server-provided 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 with a `resource_group.id` property matching the specified
               identifier.
        :param str zone_name: (optional) Filters the collection to resources with a
               `zone.name` property matching the exact specified name.
        :param str name: (optional) Filters the collection to resources with a
               `name` property matching the exact specified name.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `DedicatedHostGroupCollection` object
        """

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

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

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

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

        response = self.send(request, **kwargs)
        return response

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

        This request creates a new dedicated host group.

        :param str class_: The dedicated host profile class for hosts in this
               group.
        :param str family: The dedicated host profile family for hosts in this
               group.
        :param ZoneIdentity zone: The zone this dedicated host group will reside
               in.
        :param str name: (optional) The name for this dedicated host group. The
               name must not be used by another dedicated host group in the region. 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) will be
               used.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `DedicatedHostGroup` object
        """

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

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

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

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

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

        response = self.send(request, **kwargs)
        return response

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

        This request deletes a dedicated host group.

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

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

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

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
            del kwargs['headers']

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

        response = self.send(request, **kwargs)
        return response

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

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

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

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

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

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

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

        response = self.send(request, **kwargs)
        return response

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

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

        :param str id: The dedicated host group identifier.
        :param DedicatedHostGroupPatch dedicated_host_group_patch: The dedicated
               host group patch.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `DedicatedHostGroup` object
        """

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

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

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

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

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

        response = self.send(request, **kwargs)
        return response

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

        This request lists provisionable [dedicated host
        profiles](https://cloud.ibm.com/docs/vpc?topic=vpc-dh-profiles) in the region. A
        dedicated host profile specifies the hardware characteristics for a dedicated
        host.

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

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

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

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

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

        response = self.send(request, **kwargs)
        return response

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

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

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

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

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

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

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

        response = self.send(request, **kwargs)
        return response

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

        This request lists all dedicated hosts in the region.

        :param str dedicated_host_group_id: (optional) Filters the collection to
               dedicated hosts with a `group.id` property matching the specified
               identifier.
        :param str start: (optional) A server-provided 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 with a `resource_group.id` property matching the specified
               identifier.
        :param str zone_name: (optional) Filters the collection to resources with a
               `zone.name` property matching the exact specified name.
        :param str name: (optional) Filters the collection to resources with a
               `name` property matching the exact specified name.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `DedicatedHostCollection` object
        """

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

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

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

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

        response = self.send(request, **kwargs)
        return response

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

        This request creates a new dedicated host.

        :param DedicatedHostPrototype dedicated_host_prototype: The dedicated host
               prototype object.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `DedicatedHost` object
        """

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

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

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

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

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

        response = self.send(request, **kwargs)
        return response

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

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

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

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

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

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

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

        response = self.send(request, **kwargs)
        return response

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

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

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

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

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

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

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

        response = self.send(request, **kwargs)
        return response

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

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

        :param str dedicated_host_id: The dedicated host identifier.
        :param str id: The dedicated host disk identifier.
        :param DedicatedHostDiskPatch dedicated_host_disk_patch: The dedicated host
               disk patch.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `DedicatedHostDisk` object
        """

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

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

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

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

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

        response = self.send(request, **kwargs)
        return response

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

        This request deletes a dedicated host.

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

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

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

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
            del kwargs['headers']

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

        response = self.send(request, **kwargs)
        return response

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

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

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

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

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

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

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

        response = self.send(request, **kwargs)
        return response

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

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

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

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

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

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

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

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

        response = self.send(request, **kwargs)
        return response

    #########################
    # Backup policies
    #########################

    def list_backup_policies(
        self,
        *,
        start: str = None,
        limit: int = None,
        resource_group_id: str = None,
        name: str = None,
        tag: str = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        List all backup policies.

        This request lists all backup policies in the region. Backup policies control
        which sources are selected for backup and include a set of backup policy plans
        that provide the backup schedules and deletion triggers.

        :param str start: (optional) A server-provided 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 with a `resource_group.id` property matching the specified
               identifier.
        :param str name: (optional) Filters the collection to resources with a
               `name` property matching the exact specified name.
        :param str tag: (optional) Filters the collection to resources with an item
               in the `tags` property matching the exact specified tag.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `BackupPolicyCollection` object
        """

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

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

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

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

        response = self.send(request, **kwargs)
        return response

    def create_backup_policy(
        self,
        match_user_tags: List[str],
        *,
        match_resource_types: List[str] = None,
        name: str = None,
        plans: List['BackupPolicyPlanPrototype'] = None,
        resource_group: 'ResourceGroupIdentity' = None,
        scope: 'BackupPolicyScopePrototype' = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        Create a backup policy.

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

        :param List[str] match_user_tags: The user tags this backup policy will
               apply to. Resources that have both a matching user tag and a matching type
               will be subject to the backup policy.
        :param List[str] match_resource_types: (optional) The resource types this
               backup policy will apply to. Resources that have both a matching type and a
               matching user tag will be subject to the backup policy.
        :param str name: (optional) The name for this backup policy. The name must
               not be used by another backup policy in the region. If unspecified, the
               name will be a hyphenated list of randomly-selected words.
        :param List[BackupPolicyPlanPrototype] plans: (optional) The prototype
               objects for backup plans to be created for this backup 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) will be
               used.
        :param BackupPolicyScopePrototype scope: (optional) The scope to use for
               this backup policy.
               If unspecified, the policy will be scoped to the account.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `BackupPolicy` object
        """

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

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

        data = {
            'match_user_tags': match_user_tags,
            'match_resource_types': match_resource_types,
            'name': name,
            'plans': plans,
            'resource_group': resource_group,
            'scope': scope,
        }
        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'))
            del kwargs['headers']
        headers['Accept'] = 'application/json'

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

        response = self.send(request, **kwargs)
        return response

    def list_backup_policy_jobs(
        self,
        backup_policy_id: str,
        *,
        status: str = None,
        backup_policy_plan_id: str = None,
        start: str = None,
        limit: int = None,
        sort: str = None,
        source_id: str = None,
        target_snapshots_id: str = None,
        target_snapshots_crn: str = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        List all jobs for a backup policy.

        This request retrieves all jobs for a backup policy. A backup job represents the
        execution of a backup policy plan for a resource matching the policy's criteria.

        :param str backup_policy_id: The backup policy identifier.
        :param str status: (optional) Filters the collection to backup policy jobs
               with a `status` property matching the specified value.
        :param str backup_policy_plan_id: (optional) Filters the collection to
               backup policy jobs with a `backup_policy_plan.id` property matching the
               specified identifier.
        :param str start: (optional) A server-provided token determining what
               resource to start the page on.
        :param int limit: (optional) The number of resources to return on a page.
        :param str sort: (optional) Sorts the returned collection by the specified
               property name in ascending order. A `-` may be prepended to the name to
               sort in descending order. For example, the value `-created_at` sorts the
               collection by the `created_at` property in descending order, and the value
               `name` sorts it by the `name` property in ascending order.
        :param str source_id: (optional) Filters the collection to backup policy
               jobs with a `source.id` property matching the specified identifier.
        :param str target_snapshots_id: (optional) Filters the collection to backup
               policy jobs with an item in the `target_snapshots` property with an `id`
               property matching the specified identifier.
        :param str target_snapshots_crn: (optional) Filters the collection to
               backup policy jobs with an item in the `target_snapshots` property with a
               `crn` property matching the specified CRN.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `BackupPolicyJobCollection` object
        """

        if not backup_policy_id:
            raise ValueError('backup_policy_id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='list_backup_policy_jobs',
        )
        headers.update(sdk_headers)

        params = {
            'version': self.version,
            'generation': self.generation,
            'status': status,
            'backup_policy_plan.id': backup_policy_plan_id,
            'start': start,
            'limit': limit,
            'sort': sort,
            'source.id': source_id,
            'target_snapshots[].id': target_snapshots_id,
            'target_snapshots[].crn': target_snapshots_crn,
        }

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

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

        response = self.send(request, **kwargs)
        return response

    def get_backup_policy_job(
        self,
        backup_policy_id: str,
        id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Retrieve a backup policy job.

        This request retrieves a single backup policy job specified by the identifier in
        the URL.

        :param str backup_policy_id: The backup policy identifier.
        :param str id: The backup policy job 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 `BackupPolicyJob` object
        """

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

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

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

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

        response = self.send(request, **kwargs)
        return response

    def list_backup_policy_plans(
        self,
        backup_policy_id: str,
        *,
        name: str = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        List all plans for a backup policy.

        This request retrieves all plans for a backup policy. Backup plans provide the
        backup schedule and deletion triggers.

        :param str backup_policy_id: The backup policy identifier.
        :param str name: (optional) Filters the collection to resources with a
               `name` property matching 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 `BackupPolicyPlanCollection` object
        """

        if not backup_policy_id:
            raise ValueError('backup_policy_id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='list_backup_policy_plans',
        )
        headers.update(sdk_headers)

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

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

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

        response = self.send(request, **kwargs)
        return response

    def create_backup_policy_plan(
        self,
        backup_policy_id: str,
        cron_spec: str,
        *,
        active: bool = None,
        attach_user_tags: List[str] = None,
        clone_policy: 'BackupPolicyPlanClonePolicyPrototype' = None,
        copy_user_tags: bool = None,
        deletion_trigger: 'BackupPolicyPlanDeletionTriggerPrototype' = None,
        name: str = None,
        remote_region_policies: List['BackupPolicyPlanRemoteRegionPolicyPrototype'] = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        Create a plan for a backup policy.

        This request creates a new backup policy plan from a backup policy plan prototype
        object. The prototype object is structured in the same way as a retrieved backup
        policy plan, and contains the information necessary to create the new backup
        policy plan.
        Backups created by this plan will use the resource group of the source being
        backed up.
        Backups created by this plan will use the plan's name truncated to 46 characters,
        followed by a unique 16-character suffix.

        :param str backup_policy_id: The backup policy identifier.
        :param str cron_spec: The cron specification for the backup schedule. The
               backup policy jobs
               (which create and delete backups for this plan) will not start until this
               time, and may start for up to 90 minutes after this time.
               All backup schedules for plans in the same policy must be at least an hour
               apart.
        :param bool active: (optional) Indicates whether the plan is active.
        :param List[str] attach_user_tags: (optional) User tags to attach to each
               backup (snapshot) created by this plan. If unspecified, no user tags will
               be attached.
        :param BackupPolicyPlanClonePolicyPrototype clone_policy: (optional)
        :param bool copy_user_tags: (optional) Indicates whether to copy the
               source's user tags to the created backups (snapshots).
        :param BackupPolicyPlanDeletionTriggerPrototype deletion_trigger:
               (optional)
        :param str name: (optional) The name for this backup policy plan. The name
               must not be used by another plan for the backup policy. If unspecified, the
               name will be a hyphenated list of randomly-selected words.
        :param List[BackupPolicyPlanRemoteRegionPolicyPrototype]
               remote_region_policies: (optional) The policies for additional backups in
               remote regions.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `BackupPolicyPlan` object
        """

        if not backup_policy_id:
            raise ValueError('backup_policy_id must be provided')
        if cron_spec is None:
            raise ValueError('cron_spec must be provided')
        if clone_policy is not None:
            clone_policy = convert_model(clone_policy)
        if deletion_trigger is not None:
            deletion_trigger = convert_model(deletion_trigger)
        if remote_region_policies is not None:
            remote_region_policies = [convert_model(x) for x in remote_region_policies]
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='create_backup_policy_plan',
        )
        headers.update(sdk_headers)

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

        data = {
            'cron_spec': cron_spec,
            'active': active,
            'attach_user_tags': attach_user_tags,
            'clone_policy': clone_policy,
            'copy_user_tags': copy_user_tags,
            'deletion_trigger': deletion_trigger,
            'name': name,
            'remote_region_policies': remote_region_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'))
            del kwargs['headers']
        headers['Accept'] = 'application/json'

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

        response = self.send(request, **kwargs)
        return response

    def delete_backup_policy_plan(
        self,
        backup_policy_id: str,
        id: str,
        *,
        if_match: str = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        Delete a backup policy plan.

        This request deletes a backup policy plan. This operation cannot be reversed. Any
        backups that have been created by the plan will remain but will no longer be
        subject to the plan's deletion trigger. Any running jobs associated with the plan
        will run to completion before the plan is deleted.
        If the request is accepted, the backup policy plan `status` will be set to
        `deleting`. Once deletion processing completes, the backup policy plan will no
        longer be retrievable.

        :param str backup_policy_id: The backup policy identifier.
        :param str id: The backup policy plan identifier.
        :param str if_match: (optional) If present, the request will fail if the
               specified ETag value does not match the resource's current ETag value.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `BackupPolicyPlan` object
        """

        if not backup_policy_id:
            raise ValueError('backup_policy_id must be provided')
        if not id:
            raise ValueError('id must be provided')
        headers = {
            'If-Match': if_match,
        }
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='delete_backup_policy_plan',
        )
        headers.update(sdk_headers)

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

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

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

        response = self.send(request, **kwargs)
        return response

    def get_backup_policy_plan(
        self,
        backup_policy_id: str,
        id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Retrieve a backup policy plan.

        This request retrieves a single backup policy plan specified by the identifier in
        the URL.

        :param str backup_policy_id: The backup policy identifier.
        :param str id: The backup policy plan 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 `BackupPolicyPlan` object
        """

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

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

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

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

        response = self.send(request, **kwargs)
        return response

    def update_backup_policy_plan(
        self,
        backup_policy_id: str,
        id: str,
        backup_policy_plan_patch: 'BackupPolicyPlanPatch',
        *,
        if_match: str = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        Update a backup policy plan.

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

        :param str backup_policy_id: The backup policy identifier.
        :param str id: The backup policy plan identifier.
        :param BackupPolicyPlanPatch backup_policy_plan_patch: The backup policy
               plan patch.
        :param str if_match: (optional) If present, the request will fail if the
               specified ETag value does not match the resource's current ETag value.
               Required if the request body includes an array.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `BackupPolicyPlan` object
        """

        if not backup_policy_id:
            raise ValueError('backup_policy_id must be provided')
        if not id:
            raise ValueError('id must be provided')
        if backup_policy_plan_patch is None:
            raise ValueError('backup_policy_plan_patch must be provided')
        if isinstance(backup_policy_plan_patch, BackupPolicyPlanPatch):
            backup_policy_plan_patch = convert_model(backup_policy_plan_patch)
        headers = {
            'If-Match': if_match,
        }
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='update_backup_policy_plan',
        )
        headers.update(sdk_headers)

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

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

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

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

        response = self.send(request, **kwargs)
        return response

    def delete_backup_policy(
        self,
        id: str,
        *,
        if_match: str = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        Delete a backup policy.

        This request deletes a backup policy. This operation cannot be reversed.
        If the request is accepted, the backup policy `status` will be set to `deleting`.
        Once deletion processing completes, the backup policy will no longer be
        retrievable.

        :param str id: The backup policy identifier.
        :param str if_match: (optional) If present, the request will fail if the
               specified ETag value does not match the resource's current ETag value.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `BackupPolicy` object
        """

        if not id:
            raise ValueError('id must be provided')
        headers = {
            'If-Match': if_match,
        }
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='delete_backup_policy',
        )
        headers.update(sdk_headers)

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

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
            del kwargs['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 = '/backup_policies/{id}'.format(**path_param_dict)
        request = self.prepare_request(
            method='DELETE',
            url=url,
            headers=headers,
            params=params,
        )

        response = self.send(request, **kwargs)
        return response

    def get_backup_policy(
        self,
        id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Retrieve a backup policy.

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

        :param str id: The backup 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 `BackupPolicy` object
        """

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

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

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
            del kwargs['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 = '/backup_policies/{id}'.format(**path_param_dict)
        request = self.prepare_request(
            method='GET',
            url=url,
            headers=headers,
            params=params,
        )

        response = self.send(request, **kwargs)
        return response

    def update_backup_policy(
        self,
        id: str,
        backup_policy_patch: 'BackupPolicyPatch',
        *,
        if_match: str = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        Update a backup policy.

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

        :param str id: The backup policy identifier.
        :param BackupPolicyPatch backup_policy_patch: The backup policy patch.
        :param str if_match: (optional) If present, the request will fail if the
               specified ETag value does not match the resource's current ETag value.
               Required if the request body includes an array.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `BackupPolicy` object
        """

        if not id:
            raise ValueError('id must be provided')
        if backup_policy_patch is None:
            raise ValueError('backup_policy_patch must be provided')
        if isinstance(backup_policy_patch, BackupPolicyPatch):
            backup_policy_patch = convert_model(backup_policy_patch)
        headers = {
            'If-Match': if_match,
        }
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='update_backup_policy',
        )
        headers.update(sdk_headers)

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

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

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
            del kwargs['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 = '/backup_policies/{id}'.format(**path_param_dict)
        request = self.prepare_request(
            method='PATCH',
            url=url,
            headers=headers,
            params=params,
            data=data,
        )

        response = self.send(request, **kwargs)
        return response

    #########################
    # Placement groups
    #########################

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

        This request lists all placement groups in the region.

        :param str start: (optional) A server-provided 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 `PlacementGroupCollection` object
        """

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

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

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

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

        response = self.send(request, **kwargs)
        return response

    def create_placement_group(
        self,
        strategy: str,
        *,
        name: str = None,
        resource_group: 'ResourceGroupIdentity' = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        Create a placement group.

        This request creates a new placement group.

        :param str strategy: The strategy for this placement group
               - `host_spread`: place on different compute hosts
               - `power_spread`: place on compute hosts that use different power sources
               The enumerated values for this property may expand in the future. When
               processing this property, check for and log unknown values. Optionally halt
               processing and surface the error, or bypass the placement group on which
               the unexpected strategy was encountered.
        :param str name: (optional) The name for this placement group. The name
               must not be used by another placement group in the region. 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) will be
               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 `PlacementGroup` object
        """

        if strategy is None:
            raise ValueError('strategy 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_placement_group',
        )
        headers.update(sdk_headers)

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

        data = {
            'strategy': strategy,
            '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'))
            del kwargs['headers']
        headers['Accept'] = 'application/json'

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

        response = self.send(request, **kwargs)
        return response

    def delete_placement_group(
        self,
        id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Delete a placement group.

        This request deletes a placement group. This operation cannot be reversed. For
        this request to succeed, the placement group must not be associated with an
        instance.

        :param str id: The placement 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 not id:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='delete_placement_group',
        )
        headers.update(sdk_headers)

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

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
            del kwargs['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 = '/placement_groups/{id}'.format(**path_param_dict)
        request = self.prepare_request(
            method='DELETE',
            url=url,
            headers=headers,
            params=params,
        )

        response = self.send(request, **kwargs)
        return response

    def get_placement_group(
        self,
        id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Retrieve a placement group.

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

        :param str id: The placement 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 `PlacementGroup` object
        """

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

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

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
            del kwargs['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 = '/placement_groups/{id}'.format(**path_param_dict)
        request = self.prepare_request(
            method='GET',
            url=url,
            headers=headers,
            params=params,
        )

        response = self.send(request, **kwargs)
        return response

    def update_placement_group(
        self,
        id: str,
        placement_group_patch: 'PlacementGroupPatch',
        **kwargs,
    ) -> DetailedResponse:
        """
        Update a placement group.

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

        :param str id: The placement group identifier.
        :param PlacementGroupPatch placement_group_patch: The placement 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 `PlacementGroup` object
        """

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

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

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

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
            del kwargs['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 = '/placement_groups/{id}'.format(**path_param_dict)
        request = self.prepare_request(
            method='PATCH',
            url=url,
            headers=headers,
            params=params,
            data=data,
        )

        response = self.send(request, **kwargs)
        return response

    #########################
    # Bare metal servers
    #########################

    def list_bare_metal_server_profiles(
        self,
        *,
        start: str = None,
        limit: int = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        List all bare metal server profiles.

        This request lists all [bare metal server
        profiles](https://cloud.ibm.com/docs/vpc?topic=vpc-bare-metal-servers-profile)
        available in the region. A bare metal server profile specifies the performance
        characteristics and pricing model for a bare metal server.

        :param str start: (optional) A server-provided 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 `BareMetalServerProfileCollection` object
        """

        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='list_bare_metal_server_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'))
            del kwargs['headers']
        headers['Accept'] = 'application/json'

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

        response = self.send(request, **kwargs)
        return response

    def get_bare_metal_server_profile(
        self,
        name: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Retrieve a bare metal server profile.

        This request retrieves a single bare metal server profile specified by the name in
        the URL.

        :param str name: The bare metal server 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 `BareMetalServerProfile` object
        """

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

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

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
            del kwargs['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 = '/bare_metal_server/profiles/{name}'.format(**path_param_dict)
        request = self.prepare_request(
            method='GET',
            url=url,
            headers=headers,
            params=params,
        )

        response = self.send(request, **kwargs)
        return response

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

        This request lists all bare metal servers in the region.

        :param str start: (optional) A server-provided 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 with a `resource_group.id` property matching the specified
               identifier.
        :param str name: (optional) Filters the collection to resources with a
               `name` property matching the exact specified name.
        :param str vpc_id: (optional) Filters the collection to resources with a
               `vpc.id` property matching the specified identifier.
        :param str vpc_crn: (optional) Filters the collection to resources with a
               `vpc.crn` property matching the specified CRN.
        :param str vpc_name: (optional) Filters the collection to resources with a
               `vpc.name` property matching 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 `BareMetalServerCollection` object
        """

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

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

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

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

        response = self.send(request, **kwargs)
        return response

    def create_bare_metal_server(
        self,
        initialization: 'BareMetalServerInitializationPrototype',
        primary_network_interface: 'BareMetalServerPrimaryNetworkInterfacePrototype',
        profile: 'BareMetalServerProfileIdentity',
        zone: 'ZoneIdentity',
        *,
        enable_secure_boot: bool = None,
        name: str = None,
        network_interfaces: List['BareMetalServerNetworkInterfacePrototype'] = None,
        resource_group: 'ResourceGroupIdentity' = None,
        trusted_platform_module: 'BareMetalServerTrustedPlatformModulePrototype' = None,
        vpc: 'VPCIdentity' = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        Create a bare metal server.

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

        :param BareMetalServerInitializationPrototype initialization:
        :param BareMetalServerPrimaryNetworkInterfacePrototype
               primary_network_interface: The primary bare metal server network interface
               to create.
        :param BareMetalServerProfileIdentity profile: The
               [profile](https://cloud.ibm.com/docs/vpc?topic=vpc-bare-metal-servers-profile)
               to use for this bare metal server.
        :param ZoneIdentity zone: The zone this bare metal server will reside in.
        :param bool enable_secure_boot: (optional) Indicates whether secure boot is
               enabled. If enabled, the image must support secure boot or the server will
               fail to boot.
        :param str name: (optional) The name for this bare metal server. The name
               must not be used by another bare metal server in the region. If
               unspecified, the name will be a hyphenated list of randomly-selected words.
               The system hostname will be based on this name.
        :param List[BareMetalServerNetworkInterfacePrototype] network_interfaces:
               (optional) The additional bare metal server network interfaces to create.
        :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) will be
               used.
        :param BareMetalServerTrustedPlatformModulePrototype
               trusted_platform_module: (optional)
        :param VPCIdentity vpc: (optional) The VPC this bare metal server will
               reside in.
               If specified, it must match the VPC for the subnets that the network
               interfaces of
               the bare metal server are attached to.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `BareMetalServer` object
        """

        if initialization is None:
            raise ValueError('initialization must be provided')
        if primary_network_interface is None:
            raise ValueError('primary_network_interface must be provided')
        if profile is None:
            raise ValueError('profile must be provided')
        if zone is None:
            raise ValueError('zone must be provided')
        initialization = convert_model(initialization)
        primary_network_interface = convert_model(primary_network_interface)
        profile = convert_model(profile)
        zone = convert_model(zone)
        if network_interfaces is not None:
            network_interfaces = [convert_model(x) for x in network_interfaces]
        if resource_group is not None:
            resource_group = convert_model(resource_group)
        if trusted_platform_module is not None:
            trusted_platform_module = convert_model(trusted_platform_module)
        if vpc is not None:
            vpc = convert_model(vpc)
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='create_bare_metal_server',
        )
        headers.update(sdk_headers)

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

        data = {
            'initialization': initialization,
            'primary_network_interface': primary_network_interface,
            'profile': profile,
            'zone': zone,
            'enable_secure_boot': enable_secure_boot,
            'name': name,
            'network_interfaces': network_interfaces,
            'resource_group': resource_group,
            'trusted_platform_module': trusted_platform_module,
            'vpc': vpc,
        }
        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'))
            del kwargs['headers']
        headers['Accept'] = 'application/json'

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

        response = self.send(request, **kwargs)
        return response

    def create_bare_metal_server_console_access_token(
        self,
        bare_metal_server_id: str,
        console_type: str,
        *,
        force: bool = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        Create a console access token for a bare metal server.

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

        :param str bare_metal_server_id: The bare metal server identifier.
        :param str console_type: The bare metal server console type for which this
               token may be used
               Must be `serial` for bare metal servers with a `cpu.architecture` of
               `s390x`.
        :param bool force: (optional) Indicates whether to disconnect an existing
               serial console session as the serial console cannot be shared.  This has no
               effect on VNC consoles.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `BareMetalServerConsoleAccessToken` object
        """

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

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

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

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

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

        response = self.send(request, **kwargs)
        return response

    def list_bare_metal_server_disks(
        self,
        bare_metal_server_id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        List all disks on a bare metal server.

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

        :param str bare_metal_server_id: The bare metal server 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 `BareMetalServerDiskCollection` object
        """

        if not bare_metal_server_id:
            raise ValueError('bare_metal_server_id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='list_bare_metal_server_disks',
        )
        headers.update(sdk_headers)

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

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

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

        response = self.send(request, **kwargs)
        return response

    def get_bare_metal_server_disk(
        self,
        bare_metal_server_id: str,
        id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Retrieve a bare metal server disk.

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

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

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

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

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

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

        response = self.send(request, **kwargs)
        return response

    def update_bare_metal_server_disk(
        self,
        bare_metal_server_id: str,
        id: str,
        bare_metal_server_disk_patch: 'BareMetalServerDiskPatch',
        **kwargs,
    ) -> DetailedResponse:
        """
        Update a bare metal server disk.

        This request updates the bare metal server disk with the information in a provided
        patch.

        :param str bare_metal_server_id: The bare metal server identifier.
        :param str id: The bare metal server disk identifier.
        :param BareMetalServerDiskPatch bare_metal_server_disk_patch: The bare
               metal server disk patch.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `BareMetalServerDisk` object
        """

        if not bare_metal_server_id:
            raise ValueError('bare_metal_server_id must be provided')
        if not id:
            raise ValueError('id must be provided')
        if bare_metal_server_disk_patch is None:
            raise ValueError('bare_metal_server_disk_patch must be provided')
        if isinstance(bare_metal_server_disk_patch, BareMetalServerDiskPatch):
            bare_metal_server_disk_patch = convert_model(bare_metal_server_disk_patch)
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='update_bare_metal_server_disk',
        )
        headers.update(sdk_headers)

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

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

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

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

        response = self.send(request, **kwargs)
        return response

    def list_bare_metal_server_network_interfaces(
        self,
        bare_metal_server_id: str,
        *,
        start: str = None,
        limit: int = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        List all network interfaces on a bare metal server.

        This request lists all network interfaces on a bare metal server. A bare metal
        server network interface is an abstract representation of a network device and
        attaches a bare metal server to a single subnet. Each network interface on a bare
        metal server can attach to any subnet in the zone, including subnets that are
        already attached to the bare metal server.

        :param str bare_metal_server_id: The bare metal server identifier.
        :param str start: (optional) A server-provided 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 `BareMetalServerNetworkInterfaceCollection` object
        """

        if not bare_metal_server_id:
            raise ValueError('bare_metal_server_id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='list_bare_metal_server_network_interfaces',
        )
        headers.update(sdk_headers)

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

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

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

        response = self.send(request, **kwargs)
        return response

    def create_bare_metal_server_network_interface(
        self,
        bare_metal_server_id: str,
        bare_metal_server_network_interface_prototype: 'BareMetalServerNetworkInterfacePrototype',
        **kwargs,
    ) -> DetailedResponse:
        """
        Create a network interface on a bare metal server.

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

        :param str bare_metal_server_id: The bare metal server identifier.
        :param BareMetalServerNetworkInterfacePrototype
               bare_metal_server_network_interface_prototype: The bare metal server
               network interface 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 `BareMetalServerNetworkInterface` object
        """

        if not bare_metal_server_id:
            raise ValueError('bare_metal_server_id must be provided')
        if bare_metal_server_network_interface_prototype is None:
            raise ValueError('bare_metal_server_network_interface_prototype must be provided')
        if isinstance(bare_metal_server_network_interface_prototype, BareMetalServerNetworkInterfacePrototype):
            bare_metal_server_network_interface_prototype = convert_model(bare_metal_server_network_interface_prototype)
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='create_bare_metal_server_network_interface',
        )
        headers.update(sdk_headers)

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

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

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

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

        response = self.send(request, **kwargs)
        return response

    def delete_bare_metal_server_network_interface(
        self,
        bare_metal_server_id: str,
        id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Delete a bare metal server network interface.

        This request deletes a bare metal server network interface. This operation cannot
        be reversed. Any floating IPs associated with the bare metal server network
        interface are implicitly disassociated.  The primary bare metal server network
        interface is not allowed to be deleted.

        :param str bare_metal_server_id: The bare metal server identifier.
        :param str id: The bare metal server 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 not bare_metal_server_id:
            raise ValueError('bare_metal_server_id must be provided')
        if not id:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='delete_bare_metal_server_network_interface',
        )
        headers.update(sdk_headers)

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

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
            del kwargs['headers']

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

        response = self.send(request, **kwargs)
        return response

    def get_bare_metal_server_network_interface(
        self,
        bare_metal_server_id: str,
        id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Retrieve a bare metal server network interface.

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

        :param str bare_metal_server_id: The bare metal server identifier.
        :param str id: The bare metal server 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 `BareMetalServerNetworkInterface` object
        """

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

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

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

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

        response = self.send(request, **kwargs)
        return response

    def update_bare_metal_server_network_interface(
        self,
        bare_metal_server_id: str,
        id: str,
        bare_metal_server_network_interface_patch: 'BareMetalServerNetworkInterfacePatch',
        **kwargs,
    ) -> DetailedResponse:
        """
        Update a bare metal server network interface.

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

        :param str bare_metal_server_id: The bare metal server identifier.
        :param str id: The bare metal server network interface identifier.
        :param BareMetalServerNetworkInterfacePatch
               bare_metal_server_network_interface_patch: The bare metal server network
               interface patch.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `BareMetalServerNetworkInterface` object
        """

        if not bare_metal_server_id:
            raise ValueError('bare_metal_server_id must be provided')
        if not id:
            raise ValueError('id must be provided')
        if bare_metal_server_network_interface_patch is None:
            raise ValueError('bare_metal_server_network_interface_patch must be provided')
        if isinstance(bare_metal_server_network_interface_patch, BareMetalServerNetworkInterfacePatch):
            bare_metal_server_network_interface_patch = convert_model(bare_metal_server_network_interface_patch)
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='update_bare_metal_server_network_interface',
        )
        headers.update(sdk_headers)

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

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

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

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

        response = self.send(request, **kwargs)
        return response

    def list_bare_metal_server_network_interface_floating_ips(
        self,
        bare_metal_server_id: str,
        network_interface_id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        List all floating IPs associated with a bare metal server network interface.

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

        :param str bare_metal_server_id: The bare metal server identifier.
        :param str network_interface_id: The bare metal server 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 not bare_metal_server_id:
            raise ValueError('bare_metal_server_id must be provided')
        if not network_interface_id:
            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_bare_metal_server_network_interface_floating_ips',
        )
        headers.update(sdk_headers)

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

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

        path_param_keys = ['bare_metal_server_id', 'network_interface_id']
        path_param_values = self.encode_path_vars(bare_metal_server_id, network_interface_id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/bare_metal_servers/{bare_metal_server_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, **kwargs)
        return response

    def remove_bare_metal_server_network_interface_floating_ip(
        self,
        bare_metal_server_id: str,
        network_interface_id: str,
        id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Disassociate a floating IP from a bare metal server network interface.

        This request disassociates the specified floating IP from the specified bare metal
        server network interface.

        :param str bare_metal_server_id: The bare metal server identifier.
        :param str network_interface_id: The bare metal server 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 not bare_metal_server_id:
            raise ValueError('bare_metal_server_id must be provided')
        if not network_interface_id:
            raise ValueError('network_interface_id must be provided')
        if not id:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='remove_bare_metal_server_network_interface_floating_ip',
        )
        headers.update(sdk_headers)

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

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
            del kwargs['headers']

        path_param_keys = ['bare_metal_server_id', 'network_interface_id', 'id']
        path_param_values = self.encode_path_vars(bare_metal_server_id, network_interface_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/bare_metal_servers/{bare_metal_server_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, **kwargs)
        return response

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

        This request retrieves a specified floating IP if it is associated with the bare
        metal server network interface specified in the URL.

        :param str bare_metal_server_id: The bare metal server identifier.
        :param str network_interface_id: The bare metal server 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 not bare_metal_server_id:
            raise ValueError('bare_metal_server_id must be provided')
        if not network_interface_id:
            raise ValueError('network_interface_id must be provided')
        if not id:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='get_bare_metal_server_network_interface_floating_ip',
        )
        headers.update(sdk_headers)

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

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

        path_param_keys = ['bare_metal_server_id', 'network_interface_id', 'id']
        path_param_values = self.encode_path_vars(bare_metal_server_id, network_interface_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/bare_metal_servers/{bare_metal_server_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, **kwargs)
        return response

    def add_bare_metal_server_network_interface_floating_ip(
        self,
        bare_metal_server_id: str,
        network_interface_id: str,
        id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Associate a floating IP with a bare metal server network interface.

        This request associates the specified floating IP with the specified bare metal
        server network interface. If `enable_infrastructure_nat` is `false`, this adds the
        IP to any existing associations. If `enable_infrastructure_nat` is `true`, this
        replaces 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 provided, is ignored.

        :param str bare_metal_server_id: The bare metal server identifier.
        :param str network_interface_id: The bare metal server 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 not bare_metal_server_id:
            raise ValueError('bare_metal_server_id must be provided')
        if not network_interface_id:
            raise ValueError('network_interface_id must be provided')
        if not id:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='add_bare_metal_server_network_interface_floating_ip',
        )
        headers.update(sdk_headers)

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

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

        path_param_keys = ['bare_metal_server_id', 'network_interface_id', 'id']
        path_param_values = self.encode_path_vars(bare_metal_server_id, network_interface_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/bare_metal_servers/{bare_metal_server_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, **kwargs)
        return response

    def list_bare_metal_server_network_interface_ips(
        self,
        bare_metal_server_id: str,
        network_interface_id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        List the primary reserved IP for a bare metal server network interface.

        This request lists the primary reserved IP for a bare metal server network
        interface.

        :param str bare_metal_server_id: The bare metal server identifier.
        :param str network_interface_id: The bare metal server 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 `ReservedIPCollectionBareMetalServerNetworkInterfaceContext` object
        """

        if not bare_metal_server_id:
            raise ValueError('bare_metal_server_id must be provided')
        if not network_interface_id:
            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_bare_metal_server_network_interface_ips',
        )
        headers.update(sdk_headers)

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

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

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

        response = self.send(request, **kwargs)
        return response

    def get_bare_metal_server_network_interface_ip(
        self,
        bare_metal_server_id: str,
        network_interface_id: str,
        id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Retrieve the primary reserved IP.

        This request retrieves the primary reserved IP for a bare metal server network
        interface.

        :param str bare_metal_server_id: The bare metal server identifier.
        :param str network_interface_id: The bare metal server network interface
               identifier.
        :param str id: The reserved IP identifier.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `ReservedIP` object
        """

        if not bare_metal_server_id:
            raise ValueError('bare_metal_server_id must be provided')
        if not network_interface_id:
            raise ValueError('network_interface_id must be provided')
        if not id:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='get_bare_metal_server_network_interface_ip',
        )
        headers.update(sdk_headers)

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

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

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

        response = self.send(request, **kwargs)
        return response

    def delete_bare_metal_server(
        self,
        id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Delete a bare metal server.

        This request deletes a bare metal server. This operation cannot be reversed. Any
        floating IPs associated with the bare metal server network interfaces are
        implicitly disassociated.

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

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

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

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
            del kwargs['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 = '/bare_metal_servers/{id}'.format(**path_param_dict)
        request = self.prepare_request(
            method='DELETE',
            url=url,
            headers=headers,
            params=params,
        )

        response = self.send(request, **kwargs)
        return response

    def get_bare_metal_server(
        self,
        id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Retrieve a bare metal server.

        This request retrieves a single bare metal server specified by the identifier in
        the URL.

        :param str id: The bare metal server 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 `BareMetalServer` object
        """

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

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

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
            del kwargs['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 = '/bare_metal_servers/{id}'.format(**path_param_dict)
        request = self.prepare_request(
            method='GET',
            url=url,
            headers=headers,
            params=params,
        )

        response = self.send(request, **kwargs)
        return response

    def update_bare_metal_server(
        self,
        id: str,
        bare_metal_server_patch: 'BareMetalServerPatch',
        **kwargs,
    ) -> DetailedResponse:
        """
        Update a bare metal server.

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

        :param str id: The bare metal server identifier.
        :param BareMetalServerPatch bare_metal_server_patch: The bare metal server
               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 `BareMetalServer` object
        """

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

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

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

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
            del kwargs['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 = '/bare_metal_servers/{id}'.format(**path_param_dict)
        request = self.prepare_request(
            method='PATCH',
            url=url,
            headers=headers,
            params=params,
            data=data,
        )

        response = self.send(request, **kwargs)
        return response

    def get_bare_metal_server_initialization(
        self,
        id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Retrieve initialization configuration for a bare metal server.

        This request retrieves configuration used to initialize the bare metal server,
        such as the image used, SSH keys, and any configured usernames and passwords.
        These can subsequently be changed on the server and therefore may not be current.

        :param str id: The bare metal server 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 `BareMetalServerInitialization` object
        """

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

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

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
            del kwargs['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 = '/bare_metal_servers/{id}/initialization'.format(**path_param_dict)
        request = self.prepare_request(
            method='GET',
            url=url,
            headers=headers,
            params=params,
        )

        response = self.send(request, **kwargs)
        return response

    def restart_bare_metal_server(
        self,
        id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Restart a bare metal server.

        This request restarts a bare metal server.  It will run immediately regardless of
        the state of the server.

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

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

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

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
            del kwargs['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 = '/bare_metal_servers/{id}/restart'.format(**path_param_dict)
        request = self.prepare_request(
            method='POST',
            url=url,
            headers=headers,
            params=params,
        )

        response = self.send(request, **kwargs)
        return response

    def start_bare_metal_server(
        self,
        id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Start a bare metal server.

        This request starts a bare metal server.  It will run immediately provided the
        server is stopped.

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

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

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

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
            del kwargs['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 = '/bare_metal_servers/{id}/start'.format(**path_param_dict)
        request = self.prepare_request(
            method='POST',
            url=url,
            headers=headers,
            params=params,
        )

        response = self.send(request, **kwargs)
        return response

    def stop_bare_metal_server(
        self,
        id: str,
        type: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Stop a bare metal server.

        This request stops a bare metal server. It will run immediately provided the
        server is running. Note: A soft stop may not complete as it relies on the
        operating system to perform the operation.

        :param str id: The bare metal server identifier.
        :param str type: The type of stop operation:
               - `soft`: signal running operating system to quiesce and shutdown cleanly
               - `hard`: immediately stop the server.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse
        """

        if not id:
            raise ValueError('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='stop_bare_metal_server',
        )
        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'))
            del kwargs['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 = '/bare_metal_servers/{id}/stop'.format(**path_param_dict)
        request = self.prepare_request(
            method='POST',
            url=url,
            headers=headers,
            params=params,
            data=data,
        )

        response = self.send(request, **kwargs)
        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](https://cloud.ibm.com/docs/vpc?topic=vpc-block-storage-profiles)
        available in the region. A volume profile specifies the performance
        characteristics and pricing model for a volume.

        :param str start: (optional) A server-provided 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'))
            del kwargs['headers']
        headers['Accept'] = 'application/json'

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

        response = self.send(request, **kwargs)
        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 not name:
            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'))
            del kwargs['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, **kwargs)
        return response

    def list_volumes(
        self,
        *,
        start: str = None,
        limit: int = None,
        name: str = None,
        attachment_state: str = None,
        encryption: str = None,
        operating_system_family: str = None,
        operating_system_architecture: 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-provided 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 a
               `name` property matching the exact specified name.
        :param str attachment_state: (optional) Filters the collection to volumes
               with an `attachment_state` property matching the specified value.
        :param str encryption: (optional) Filters the collection to resources with
               an `encryption` property matching the specified value.
        :param str operating_system_family: (optional) Filters the collection to
               resources with an `operating_system.family` property matching the specified
               operating system family.
               This parameter also supports the values `null` and `not:null` which filter
               the collection to resources which have no operating system or any operating
               system, respectively.
        :param str operating_system_architecture: (optional) Filters the collection
               to resources with an `operating_system.architecture` property matching the
               specified operating system architecture.
               This parameter also supports the values `null` and `not:null` which filter
               the collection to resources which have no operating system or any operating
               system, respectively.
        :param str zone_name: (optional) Filters the collection to resources with a
               `zone.name` property matching 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,
            'attachment_state': attachment_state,
            'encryption': encryption,
            'operating_system.family': operating_system_family,
            'operating_system.architecture': operating_system_architecture,
            'zone.name': zone_name,
        }

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

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

        response = self.send(request, **kwargs)
        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'))
            del kwargs['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, **kwargs)
        return response

    def delete_volume(
        self,
        id: str,
        *,
        if_match: str = None,
        **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 str if_match: (optional) If present, the request will fail if the
               specified ETag value does not match the resource's current ETag value.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse
        """

        if not id:
            raise ValueError('id must be provided')
        headers = {
            'If-Match': if_match,
        }
        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'))
            del kwargs['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, **kwargs)
        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 not id:
            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'))
            del kwargs['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, **kwargs)
        return response

    def update_volume(
        self,
        id: str,
        volume_patch: 'VolumePatch',
        *,
        if_match: str = None,
        **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 str if_match: (optional) If present, the request will fail if the
               specified ETag value does not match the resource's current ETag value.
               Required if the request body includes an array.
        :param dict headers: 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 not id:
            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 = {
            'If-Match': if_match,
        }
        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'))
            del kwargs['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, **kwargs)
        return response

    #########################
    # Snapshots
    #########################

    def delete_snapshots(
        self,
        source_volume_id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Delete a filtered collection of snapshots.

        This request deletes all snapshots created from a specific source volume.

        :param str source_volume_id: Filters the collection to resources with a
               `source_volume.id` property matching the specified identifier.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse
        """

        if not source_volume_id:
            raise ValueError('source_volume_id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='delete_snapshots',
        )
        headers.update(sdk_headers)

        params = {
            'version': self.version,
            'generation': self.generation,
            'source_volume.id': source_volume_id,
        }

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
            del kwargs['headers']

        url = '/snapshots'
        request = self.prepare_request(
            method='DELETE',
            url=url,
            headers=headers,
            params=params,
        )

        response = self.send(request, **kwargs)
        return response

    def list_snapshots(
        self,
        *,
        start: str = None,
        limit: int = None,
        tag: str = None,
        resource_group_id: str = None,
        name: str = None,
        source_volume_id: str = None,
        source_volume_crn: str = None,
        source_image_id: str = None,
        source_image_crn: str = None,
        sort: str = None,
        backup_policy_plan_id: str = None,
        copies_id: str = None,
        copies_name: str = None,
        copies_crn: str = None,
        copies_remote_region_name: str = None,
        source_snapshot_id: str = None,
        source_snapshot_remote_region_name: str = None,
        source_volume_remote_region_name: str = None,
        source_image_remote_region_name: str = None,
        clones_zone_name: str = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        List all snapshots.

        This request lists all snapshots in the region. A snapshot preserves the data of a
        volume at the time the snapshot is created.

        :param str start: (optional) A server-provided token determining what
               resource to start the page on.
        :param int limit: (optional) The number of resources to return on a page.
        :param str tag: (optional) Filters the collection to resources with an item
               in the `tags` property matching the exact specified tag.
        :param str resource_group_id: (optional) Filters the collection to
               resources with a `resource_group.id` property matching the specified
               identifier.
        :param str name: (optional) Filters the collection to resources with a
               `name` property matching the exact specified name.
        :param str source_volume_id: (optional) Filters the collection to resources
               with a `source_volume.id` property matching the specified identifier.
        :param str source_volume_crn: (optional) Filters the collection to
               resources with a `source_volume.crn` property matching the specified CRN.
        :param str source_image_id: (optional) Filters the collection to resources
               with a `source_image.id` property matching the specified identifier.
               This parameter also supports the values `null` and `not:null` which filter
               the collection to resources which have no source image or any existent
               source image, respectively.
        :param str source_image_crn: (optional) Filters the collection to resources
               with a `source_image.crn` property matching the specified CRN.
               This parameter also supports the values `null` and `not:null` which filter
               the collection to resources which have no source image or any existent
               source image, respectively.
        :param str sort: (optional) Sorts the returned collection by the specified
               property name in ascending order. A `-` may be prepended to the name to
               sort in descending order. For example, the value `-created_at` sorts the
               collection by the `created_at` property in descending order, and the value
               `name` sorts it by the `name` property in ascending order.
        :param str backup_policy_plan_id: (optional) Filters the collection to
               backup policy jobs with a `backup_policy_plan.id` property matching the
               specified identifier.
        :param str copies_id: (optional) Filters the collection to snapshots with
               an item in the `copies` property with an `id` property matching the
               specified identifier.
        :param str copies_name: (optional) Filters the collection to snapshots with
               an item in the `copies` property with a `name` property matching the exact
               specified name.
        :param str copies_crn: (optional) Filters the collection to snapshots with
               an item in the `copies` property with an `id` property matching the
               specified CRN.
        :param str copies_remote_region_name: (optional) Filters the collection to
               snapshots with an item in the `copies` property with a
               `remote.region.name` property matching the exact specified name.
        :param str source_snapshot_id: (optional) Filters the collection to
               resources with a `source_snapshot.id` property matching the specified
               identifier.
        :param str source_snapshot_remote_region_name: (optional) Filters the
               collection to resources with a `source_snapshot.remote.region.name`
               property matching the exact specified name.
        :param str source_volume_remote_region_name: (optional) Filters the
               collection to resources with a `source_volume.remote.region.name` property
               matching the exact specified name.
        :param str source_image_remote_region_name: (optional) Filters the
               collection to resources with a `source_image.remote.region.name` property
               matching the exact specified name.
        :param str clones_zone_name: (optional) Filters the collection to snapshots
               with an item in the `clones` property with a `zone.name` property matching
               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 `SnapshotCollection` object
        """

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

        params = {
            'version': self.version,
            'generation': self.generation,
            'start': start,
            'limit': limit,
            'tag': tag,
            'resource_group.id': resource_group_id,
            'name': name,
            'source_volume.id': source_volume_id,
            'source_volume.crn': source_volume_crn,
            'source_image.id': source_image_id,
            'source_image.crn': source_image_crn,
            'sort': sort,
            'backup_policy_plan.id': backup_policy_plan_id,
            'copies[].id': copies_id,
            'copies[].name': copies_name,
            'copies[].crn': copies_crn,
            'copies[].remote.region.name': copies_remote_region_name,
            'source_snapshot.id': source_snapshot_id,
            'source_snapshot.remote.region.name': source_snapshot_remote_region_name,
            'source_volume.remote.region.name': source_volume_remote_region_name,
            'source_image.remote.region.name': source_image_remote_region_name,
            'clones[].zone.name': clones_zone_name,
        }

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

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

        response = self.send(request, **kwargs)
        return response

    def create_snapshot(
        self,
        snapshot_prototype: 'SnapshotPrototype',
        **kwargs,
    ) -> DetailedResponse:
        """
        Create a snapshot.

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

        :param SnapshotPrototype snapshot_prototype: The snapshot 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 `Snapshot` object
        """

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

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

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

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

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

        response = self.send(request, **kwargs)
        return response

    def delete_snapshot(
        self,
        id: str,
        *,
        if_match: str = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        Delete a snapshot.

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

        :param str id: The snapshot identifier.
        :param str if_match: (optional) If present, the request will fail if the
               specified ETag value does not match the resource's current ETag value.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse
        """

        if not id:
            raise ValueError('id must be provided')
        headers = {
            'If-Match': if_match,
        }
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='delete_snapshot',
        )
        headers.update(sdk_headers)

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

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
            del kwargs['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 = '/snapshots/{id}'.format(**path_param_dict)
        request = self.prepare_request(
            method='DELETE',
            url=url,
            headers=headers,
            params=params,
        )

        response = self.send(request, **kwargs)
        return response

    def get_snapshot(
        self,
        id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Retrieve a snapshot.

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

        :param str id: The snapshot 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 `Snapshot` object
        """

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

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

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
            del kwargs['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 = '/snapshots/{id}'.format(**path_param_dict)
        request = self.prepare_request(
            method='GET',
            url=url,
            headers=headers,
            params=params,
        )

        response = self.send(request, **kwargs)
        return response

    def update_snapshot(
        self,
        id: str,
        snapshot_patch: 'SnapshotPatch',
        *,
        if_match: str = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        Update a snapshot.

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

        :param str id: The snapshot identifier.
        :param SnapshotPatch snapshot_patch: The snapshot patch.
        :param str if_match: (optional) If present, the request will fail if the
               specified ETag value does not match the resource's current ETag value.
               Required if the request body includes an array.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `Snapshot` object
        """

        if not id:
            raise ValueError('id must be provided')
        if snapshot_patch is None:
            raise ValueError('snapshot_patch must be provided')
        if isinstance(snapshot_patch, SnapshotPatch):
            snapshot_patch = convert_model(snapshot_patch)
        headers = {
            'If-Match': if_match,
        }
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='update_snapshot',
        )
        headers.update(sdk_headers)

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

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

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
            del kwargs['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 = '/snapshots/{id}'.format(**path_param_dict)
        request = self.prepare_request(
            method='PATCH',
            url=url,
            headers=headers,
            params=params,
            data=data,
        )

        response = self.send(request, **kwargs)
        return response

    def list_snapshot_clones(
        self,
        id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        List all clones for a snapshot.

        This request lists all clones for a snapshot. Use a clone to quickly restore a
        snapshot within the clone's zone.

        :param str id: The snapshot 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 `SnapshotCloneCollection` object
        """

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

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

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
            del kwargs['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 = '/snapshots/{id}/clones'.format(**path_param_dict)
        request = self.prepare_request(
            method='GET',
            url=url,
            headers=headers,
            params=params,
        )

        response = self.send(request, **kwargs)
        return response

    def delete_snapshot_clone(
        self,
        id: str,
        zone_name: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Delete a snapshot clone.

        This request deletes a snapshot clone. This operation cannot be reversed, but an
        equivalent clone may be recreated from the snapshot.

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

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

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

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
            del kwargs['headers']

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

        response = self.send(request, **kwargs)
        return response

    def get_snapshot_clone(
        self,
        id: str,
        zone_name: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Retrieve a snapshot clone.

        This request retrieves a single clone specified by the snapshot identifier and
        zone name in the URL.

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

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

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

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

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

        response = self.send(request, **kwargs)
        return response

    def create_snapshot_clone(
        self,
        id: str,
        zone_name: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Create a clone for a snapshot.

        This request creates a new clone for a snapshot in the specified zone. A request
        body is not required, and if provided, is ignored. If the snapshot already has a
        clone in the zone, it is returned.

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

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

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

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

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

        response = self.send(request, **kwargs)
        return response

    #########################
    # Shares
    #########################

    def list_share_profiles(
        self,
        *,
        start: str = None,
        limit: int = None,
        sort: str = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        List all file share profiles.

        This request lists all [file share
        profiles](https://cloud.ibm.com/docs/vpc?topic=vpc-file-storage-profiles)
        available in the region. A file share profile specifies the performance
        characteristics and pricing model for a file share.

        :param str start: (optional) A server-provided token determining what
               resource to start the page on.
        :param int limit: (optional) The number of resources to return on a page.
        :param str sort: (optional) Sorts the returned collection by the specified
               property name in ascending order. A `-` may be prepended to the name to
               sort in descending order. For example, the value `-created_at` sorts the
               collection by the `created_at` property in descending order, and the value
               `name` sorts it by the `name` property in ascending order.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `ShareProfileCollection` object
        """

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

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

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

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

        response = self.send(request, **kwargs)
        return response

    def get_share_profile(
        self,
        name: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Retrieve a file share profile.

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

        :param str name: The file share 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 `ShareProfile` object
        """

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

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

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
            del kwargs['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 = '/share/profiles/{name}'.format(**path_param_dict)
        request = self.prepare_request(
            method='GET',
            url=url,
            headers=headers,
            params=params,
        )

        response = self.send(request, **kwargs)
        return response

    def list_shares(
        self,
        *,
        start: str = None,
        limit: int = None,
        resource_group_id: str = None,
        name: str = None,
        sort: str = None,
        replication_role: str = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        List all file shares.

        This request lists all file shares in the region.

        :param str start: (optional) A server-provided 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 with a `resource_group.id` property matching the specified
               identifier.
        :param str name: (optional) Filters the collection to resources with a
               `name` property matching the exact specified name.
        :param str sort: (optional) Sorts the returned collection by the specified
               property name in ascending order. A `-` may be prepended to the name to
               sort in descending order. For example, the value `-created_at` sorts the
               collection by the `created_at` property in descending order, and the value
               `name` sorts it by the `name` property in ascending order.
        :param str replication_role: (optional) Filters the collection to file
               shares with a `replication_role` property matching the specified value.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `ShareCollection` object
        """

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

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

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

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

        response = self.send(request, **kwargs)
        return response

    def create_share(
        self,
        share_prototype: 'SharePrototype',
        **kwargs,
    ) -> DetailedResponse:
        """
        Create a file share.

        This request provisions new file shares from a share prototype object. The new
        file shares can be a standalone share, a replica share, or both a source and
        replica share.
        The prototype object is structured in the same way as a retrieved share, and
        contains the information necessary to provision the new file shares.

        :param SharePrototype share_prototype: The file share 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 `Share` object
        """

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

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

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

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

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

        response = self.send(request, **kwargs)
        return response

    def delete_share(
        self,
        id: str,
        *,
        if_match: str = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        Delete a file share.

        This request deletes a share. This operation cannot be reversed. A share cannot be
        deleted if it:
        - has share mount targets
        - has a `lifecycle_state` of `updating`
        - has a replication operation in progress
        If the request is accepted, the share `lifecycle_state` will be set to `deleting`.
        Once deletion processing completes, it will no longer be retrievable.

        :param str id: The file share identifier.
        :param str if_match: (optional) If present, the request will fail if the
               specified ETag value does not match the resource's current ETag value.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `Share` object
        """

        if not id:
            raise ValueError('id must be provided')
        headers = {
            'If-Match': if_match,
        }
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='delete_share',
        )
        headers.update(sdk_headers)

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

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
            del kwargs['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 = '/shares/{id}'.format(**path_param_dict)
        request = self.prepare_request(
            method='DELETE',
            url=url,
            headers=headers,
            params=params,
        )

        response = self.send(request, **kwargs)
        return response

    def get_share(
        self,
        id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Retrieve a file share.

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

        :param str id: The file share 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 `Share` object
        """

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

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

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
            del kwargs['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 = '/shares/{id}'.format(**path_param_dict)
        request = self.prepare_request(
            method='GET',
            url=url,
            headers=headers,
            params=params,
        )

        response = self.send(request, **kwargs)
        return response

    def update_share(
        self,
        id: str,
        share_patch: 'SharePatch',
        *,
        if_match: str = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        Update a file share.

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

        :param str id: The file share identifier.
        :param SharePatch share_patch: The file share patch.
        :param str if_match: (optional) If present, the request will fail if the
               specified ETag value does not match the resource's current ETag value.
               Required if the request body includes an array.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `Share` object
        """

        if not id:
            raise ValueError('id must be provided')
        if share_patch is None:
            raise ValueError('share_patch must be provided')
        if isinstance(share_patch, SharePatch):
            share_patch = convert_model(share_patch)
        headers = {
            'If-Match': if_match,
        }
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='update_share',
        )
        headers.update(sdk_headers)

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

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

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
            del kwargs['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 = '/shares/{id}'.format(**path_param_dict)
        request = self.prepare_request(
            method='PATCH',
            url=url,
            headers=headers,
            params=params,
            data=data,
        )

        response = self.send(request, **kwargs)
        return response

    def failover_share(
        self,
        share_id: str,
        *,
        fallback_policy: str = None,
        timeout: int = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        Failover to replica file share.

        This request triggers a failover to the replica file share specified by the
        identifier in the URL. The failover cannot be started if a source share or the
        replica share has a `lifecycle_state` of `updating`, or has a replication
        operation in progress.
        If `fallback_policy` is specified as `split`, and the request is accepted but the
        failover operation cannot be performed, a split will be triggered.

        :param str share_id: The file share identifier.
        :param str fallback_policy: (optional) The action to take if the failover
               request is accepted but cannot be performed or times out:
               - `fail`: Fail the operation, resulting in the replication relationship
               being unchanged.
               - `split`: Split the replica from its source, resulting in two individual
               read-write
                   file shares. Because the final sync was not completed, the replica may
               be
                   out-of-date. This occurs in disaster recovery scenarios where the
               source is known to
                   be unreachable.
        :param int timeout: (optional) The failover timeout in seconds.
               If the timeout is reached, the `fallback_policy` will be triggered.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse
        """

        if not share_id:
            raise ValueError('share_id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='failover_share',
        )
        headers.update(sdk_headers)

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

        data = {
            'fallback_policy': fallback_policy,
            'timeout': timeout,
        }
        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'))
            del kwargs['headers']

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

        response = self.send(request, **kwargs)
        return response

    def list_share_mount_targets(
        self,
        share_id: str,
        *,
        name: str = None,
        start: str = None,
        limit: int = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        List all mount targets for a file share.

        This request retrieves all share mount targets for a file share. A share mount
        target is a network endpoint at which a file share may be mounted. The file share
        can be mounted by clients in the same VPC and zone after creating share mount
        targets.
        The share mount targets will be sorted by their `created_at` property values, with
        newest targets first.

        :param str share_id: The file share identifier.
        :param str name: (optional) Filters the collection to resources with a
               `name` property matching the exact specified name.
        :param str start: (optional) A server-provided 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 `ShareMountTargetCollection` object
        """

        if not share_id:
            raise ValueError('share_id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='list_share_mount_targets',
        )
        headers.update(sdk_headers)

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

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

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

        response = self.send(request, **kwargs)
        return response

    def create_share_mount_target(
        self,
        share_id: str,
        share_mount_target_prototype: 'ShareMountTargetPrototype',
        **kwargs,
    ) -> DetailedResponse:
        """
        Create a mount target for a file share.

        This request creates a new share mount target from a share mount target prototype
        object.
        The prototype object is structured in the same way as a retrieved share mount
        target, and contains the information necessary to provision the new file share
        mount target.

        :param str share_id: The file share identifier.
        :param ShareMountTargetPrototype share_mount_target_prototype: The share
               mount target 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 `ShareMountTarget` object
        """

        if not share_id:
            raise ValueError('share_id must be provided')
        if share_mount_target_prototype is None:
            raise ValueError('share_mount_target_prototype must be provided')
        if isinstance(share_mount_target_prototype, ShareMountTargetPrototype):
            share_mount_target_prototype = convert_model(share_mount_target_prototype)
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='create_share_mount_target',
        )
        headers.update(sdk_headers)

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

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

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

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

        response = self.send(request, **kwargs)
        return response

    def delete_share_mount_target(
        self,
        share_id: str,
        id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Delete a share mount target.

        This request deletes a share mount target. This operation cannot be reversed.
        If the request is accepted, the share mount target `lifecycle_state` will be set
        to
        `deleting`. Once deletion processing completes, it will no longer be retrievable.

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

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

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

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

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

        response = self.send(request, **kwargs)
        return response

    def get_share_mount_target(
        self,
        share_id: str,
        id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Retrieve a share mount target.

        This request retrieves a single share mount target specified by the identifier in
        the URL.

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

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

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

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

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

        response = self.send(request, **kwargs)
        return response

    def update_share_mount_target(
        self,
        share_id: str,
        id: str,
        share_mount_target_patch: 'ShareMountTargetPatch',
        **kwargs,
    ) -> DetailedResponse:
        """
        Update a share mount target.

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

        :param str share_id: The file share identifier.
        :param str id: The share mount target identifier.
        :param ShareMountTargetPatch share_mount_target_patch: The share mount
               target 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 `ShareMountTarget` object
        """

        if not share_id:
            raise ValueError('share_id must be provided')
        if not id:
            raise ValueError('id must be provided')
        if share_mount_target_patch is None:
            raise ValueError('share_mount_target_patch must be provided')
        if isinstance(share_mount_target_patch, ShareMountTargetPatch):
            share_mount_target_patch = convert_model(share_mount_target_patch)
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='update_share_mount_target',
        )
        headers.update(sdk_headers)

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

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

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

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

        response = self.send(request, **kwargs)
        return response

    def delete_share_source(
        self,
        share_id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Split the source file share from a replica share.

        This request removes the replication relationship between a source share and the
        replica share specified by the identifier in the URL. The replication relationship
        cannot be removed if a source share or the replica share has a `lifecycle_state`
        of `updating`, or has a replication operation in progress.
        This operation cannot be reversed.

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

        if not share_id:
            raise ValueError('share_id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='delete_share_source',
        )
        headers.update(sdk_headers)

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

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
            del kwargs['headers']

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

        response = self.send(request, **kwargs)
        return response

    def get_share_source(
        self,
        share_id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Retrieve the source file share for a replica file share.

        This request retrieves the source file share associated with the replica file
        share specified by the identifier in the URL.

        :param str share_id: The file share 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 `ShareReference` object
        """

        if not share_id:
            raise ValueError('share_id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='get_share_source',
        )
        headers.update(sdk_headers)

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

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

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

        response = self.send(request, **kwargs)
        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'))
            del kwargs['headers']
        headers['Accept'] = 'application/json'

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

        response = self.send(request, **kwargs)
        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 not name:
            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'))
            del kwargs['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, **kwargs)
        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 not region_name:
            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'))
            del kwargs['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, **kwargs)
        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 not region_name:
            raise ValueError('region_name must be provided')
        if not name:
            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'))
            del kwargs['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, **kwargs)
        return response

    #########################
    # Virtual network interfaces
    #########################

    def list_virtual_network_interfaces(
        self,
        *,
        start: str = None,
        limit: int = None,
        resource_group_id: str = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        List all virtual network interfaces.

        This request lists all virtual network interfaces in the region. A virtual network
        interface is a logical abstraction of a virtual network interface in a subnet, and
        may be attached to a target resource.
        The virtual network interfaces will be sorted by their `created_at` property
        values, with newest virtual network interfaces first. Virtual network interfaces
        with identical
        `created_at` property values will in turn be sorted by ascending `name` property
        values.

        :param str start: (optional) A server-provided 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 with a `resource_group.id` property matching the specified
               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 `VirtualNetworkInterfaceCollection` object
        """

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

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

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

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

        response = self.send(request, **kwargs)
        return response

    def get_virtual_network_interface(
        self,
        id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Retrieve a virtual network interface.

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

        :param str id: The virtual 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 `VirtualNetworkInterface` object
        """

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

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

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
            del kwargs['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 = '/virtual_network_interfaces/{id}'.format(**path_param_dict)
        request = self.prepare_request(
            method='GET',
            url=url,
            headers=headers,
            params=params,
        )

        response = self.send(request, **kwargs)
        return response

    def update_virtual_network_interface(
        self,
        id: str,
        virtual_network_interface_patch: 'VirtualNetworkInterfacePatch',
        **kwargs,
    ) -> DetailedResponse:
        """
        Update a virtual network interface.

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

        :param str id: The virtual network interface identifier.
        :param VirtualNetworkInterfacePatch virtual_network_interface_patch: The
               virtual network interface patch.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `VirtualNetworkInterface` object
        """

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

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

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

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
            del kwargs['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 = '/virtual_network_interfaces/{id}'.format(**path_param_dict)
        request = self.prepare_request(
            method='PATCH',
            url=url,
            headers=headers,
            params=params,
            data=data,
        )

        response = self.send(request, **kwargs)
        return response

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

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

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

        :param str start: (optional) A server-provided 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 with a `resource_group.id` property matching the specified
               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 `PublicGatewayCollection` object
        """

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

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

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

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

        response = self.send(request, **kwargs)
        return response

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

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

        :param VPCIdentity vpc: The VPC this public gateway will reside in.
        :param ZoneIdentity zone: The zone this public gateway will reside in.
        :param PublicGatewayFloatingIPPrototype floating_ip: (optional)
        :param str name: (optional) The name for this public gateway. The name must
               not be used by another public gateway in the 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) will be
               used.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `PublicGateway` object
        """

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

        params = {
            'version': self.version,
            'generation': self.generation,
        }

        data = {
            'vpc': vpc,
            'zone': zone,
            'floating_ip': floating_ip,
            'name': name,
            'resource_group': resource_group,
        }
        data = {k: v for (k, v) in data.items() if v is not None}
        data = json.dumps(data)
        headers['content-type'] = 'application/json'

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
            del kwargs['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, **kwargs)
        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 not id:
            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'))
            del kwargs['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, **kwargs)
        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 not id:
            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'))
            del kwargs['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, **kwargs)
        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 not id:
            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'))
            del kwargs['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, **kwargs)
        return response

    #########################
    # Floating IPs
    #########################

    def list_floating_ips(
        self,
        *,
        start: str = None,
        limit: int = None,
        resource_group_id: str = None,
        sort: str = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        List all floating IPs.

        This request lists all floating IPs in the region. Floating IPs allow inbound and
        outbound traffic from the Internet to an instance.

        :param str start: (optional) A server-provided 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 with a `resource_group.id` property matching the specified
               identifier.
        :param str sort: (optional) Sorts the returned collection by the specified
               property name in ascending order. A `-` may be prepended to the name to
               sort in descending order. For example, the value `-created_at` sorts the
               collection by the `created_at` property in descending order, and the value
               `name` sorts it by the `name` property in ascending order.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `FloatingIPCollection` object
        """

        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='list_floating_ips',
        )
        headers.update(sdk_headers)

        params = {
            'version': self.version,
            'generation': self.generation,
            'start': start,
            'limit': limit,
            'resource_group.id': resource_group_id,
            'sort': sort,
        }

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
            del kwargs['headers']
        headers['Accept'] = 'application/json'

        url = '/floating_ips'
        request = self.prepare_request(
            method='GET',
            url=url,
            headers=headers,
            params=params,
        )

        response = self.send(request, **kwargs)
        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'))
            del kwargs['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, **kwargs)
        return response

    def delete_floating_ip(
        self,
        id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Delete 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 not id:
            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'))
            del kwargs['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, **kwargs)
        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 not id:
            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'))
            del kwargs['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, **kwargs)
        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 not id:
            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'))
            del kwargs['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, **kwargs)
        return response

    #########################
    # Network ACLs
    #########################

    def list_network_acls(
        self,
        *,
        start: str = None,
        limit: int = None,
        resource_group_id: str = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        List all network ACLs.

        This request lists all network ACLs in the region. A network ACL defines a set of
        packet filtering (5-tuple) rules for all traffic in and out of a subnet. Both
        allow and deny rules can be defined, and rules are stateless such that reverse
        traffic in response to allowed traffic is not automatically permitted.

        :param str start: (optional) A server-provided 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 with a `resource_group.id` property matching the specified
               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 `NetworkACLCollection` object
        """

        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='list_network_acls',
        )
        headers.update(sdk_headers)

        params = {
            'version': self.version,
            'generation': self.generation,
            'start': start,
            'limit': limit,
            'resource_group.id': resource_group_id,
        }

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
            del kwargs['headers']
        headers['Accept'] = 'application/json'

        url = '/network_acls'
        request = self.prepare_request(
            method='GET',
            url=url,
            headers=headers,
            params=params,
        )

        response = self.send(request, **kwargs)
        return response

    def create_network_acl(
        self,
        network_acl_prototype: 'NetworkACLPrototype',
        **kwargs,
    ) -> DetailedResponse:
        """
        Create a network ACL.

        This request creates a new stateless 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: 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 None:
            raise ValueError('network_acl_prototype must be provided')
        if 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'))
            del kwargs['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, **kwargs)
        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 not id:
            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'))
            del kwargs['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, **kwargs)
        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 not id:
            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'))
            del kwargs['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, **kwargs)
        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 not id:
            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'))
            del kwargs['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, **kwargs)
        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-provided 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 a
               `direction` property matching the specified value.
        :param dict headers: 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 not network_acl_id:
            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'))
            del kwargs['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, **kwargs)
        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 not network_acl_id:
            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'))
            del kwargs['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, **kwargs)
        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 not network_acl_id:
            raise ValueError('network_acl_id must be provided')
        if not id:
            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'))
            del kwargs['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, **kwargs)
        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 not network_acl_id:
            raise ValueError('network_acl_id must be provided')
        if not id:
            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'))
            del kwargs['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, **kwargs)
        return response

    def update_network_acl_rule(
        self,
        network_acl_id: str,
        id: str,
        network_acl_rule_patch: 'NetworkACLRulePatch',
        **kwargs,
    ) -> DetailedResponse:
        """
        Update a network ACL rule.

        This request updates a rule with the information in a provided rule patch. The
        rule patch object contains only the information to be updated. The request will
        fail if the information is not applicable to the rule's protocol.

        :param str network_acl_id: The network ACL identifier.
        :param str id: The rule identifier.
        :param NetworkACLRulePatch network_acl_rule_patch: The network ACL rule
               patch.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `NetworkACLRule` object
        """

        if not network_acl_id:
            raise ValueError('network_acl_id must be provided')
        if not id:
            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'))
            del kwargs['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, **kwargs)
        return response

    #########################
    # Security groups
    #########################

    def list_security_groups(
        self,
        *,
        start: str = None,
        limit: int = None,
        resource_group_id: str = None,
        vpc_id: str = None,
        vpc_crn: str = None,
        vpc_name: str = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        List all security groups.

        This request lists all security groups in the region. Security groups provide a
        way to apply IP filtering rules to instances in the associated VPC. With security
        groups, all traffic is denied by default, and rules added to security groups
        define which traffic the security group permits. Security group rules are stateful
        such that reverse traffic in response to allowed traffic is automatically
        permitted.

        :param str start: (optional) A server-provided 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 with a `resource_group.id` property matching the specified
               identifier.
        :param str vpc_id: (optional) Filters the collection to resources with a
               `vpc.id` property matching the specified identifier.
        :param str vpc_crn: (optional) Filters the collection to resources with a
               `vpc.crn` property matching the specified CRN.
        :param str vpc_name: (optional) Filters the collection to resources with a
               `vpc.name` property matching the exact specified name.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `SecurityGroupCollection` object
        """

        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='list_security_groups',
        )
        headers.update(sdk_headers)

        params = {
            'version': self.version,
            'generation': self.generation,
            'start': start,
            'limit': limit,
            'resource_group.id': resource_group_id,
            'vpc.id': vpc_id,
            'vpc.crn': vpc_crn,
            'vpc.name': vpc_name,
        }

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
            del kwargs['headers']
        headers['Accept'] = 'application/json'

        url = '/security_groups'
        request = self.prepare_request(
            method='GET',
            url=url,
            headers=headers,
            params=params,
        )

        response = self.send(request, **kwargs)
        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
        resources in that VPC can be added to the security group.

        :param VPCIdentity vpc: The VPC this security group will reside in.
        :param str name: (optional) The name for this security group. The name must
               not be used by another security group for the 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) will be
               used.
        :param List[SecurityGroupRulePrototype] rules: (optional) The 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'))
            del kwargs['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, **kwargs)
        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 security group targets or 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 not id:
            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'))
            del kwargs['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, **kwargs)
        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 not id:
            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'))
            del kwargs['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, **kwargs)
        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 not id:
            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'))
            del kwargs['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, **kwargs)
        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 not security_group_id:
            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'))
            del kwargs['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, **kwargs)
        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 will 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 not security_group_id:
            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'))
            del kwargs['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, **kwargs)
        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 not security_group_id:
            raise ValueError('security_group_id must be provided')
        if not id:
            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'))
            del kwargs['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, **kwargs)
        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 not security_group_id:
            raise ValueError('security_group_id must be provided')
        if not id:
            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'))
            del kwargs['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, **kwargs)
        return response

    def update_security_group_rule(
        self,
        security_group_id: str,
        id: str,
        security_group_rule_patch: 'SecurityGroupRulePatch',
        **kwargs,
    ) -> DetailedResponse:
        """
        Update a security group rule.

        This request updates a security group rule with the information in a provided rule
        patch object. The rule patch object contains only the information to be updated.
        The request will fail if the information is not applicable to the rule's protocol.

        :param str security_group_id: The security group identifier.
        :param str id: The rule identifier.
        :param SecurityGroupRulePatch security_group_rule_patch: The security group
               rule patch.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `SecurityGroupRule` object
        """

        if not security_group_id:
            raise ValueError('security_group_id must be provided')
        if not id:
            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'))
            del kwargs['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, **kwargs)
        return response

    def list_security_group_targets(
        self,
        security_group_id: str,
        *,
        start: str = None,
        limit: int = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        List all targets associated with a security group.

        This request lists all targets associated with a security group, to which the
        rules in the security group are applied.

        :param str security_group_id: The security group identifier.
        :param str start: (optional) A server-provided token determining what
               resource to start the page on.
        :param int limit: (optional) The number of resources to return on a page.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `SecurityGroupTargetCollection` object
        """

        if not security_group_id:
            raise ValueError('security_group_id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='list_security_group_targets',
        )
        headers.update(sdk_headers)

        params = {
            'version': self.version,
            'generation': self.generation,
            'start': start,
            'limit': limit,
        }

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
            del kwargs['headers']
        headers['Accept'] = 'application/json'

        path_param_keys = ['security_group_id']
        path_param_values = self.encode_path_vars(security_group_id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/security_groups/{security_group_id}/targets'.format(**path_param_dict)
        request = self.prepare_request(
            method='GET',
            url=url,
            headers=headers,
            params=params,
        )

        response = self.send(request, **kwargs)
        return response

    def delete_security_group_target_binding(
        self,
        security_group_id: str,
        id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Remove a target from a security group.

        This request removes a target from a security group. For this request to succeed,
        the target must be attached to at least one other security group.  The specified
        target identifier can be:
        - A bare metal server network interface identifier
        - A virtual network interface identifier
        - A VPN server identifier
        - A load balancer identifier
        - An endpoint gateway identifier
        - An instance network interface identifier
        Security groups are stateful, so any changes to a target's security groups are
        applied to new connections. Existing connections are not affected.

        :param str security_group_id: The security group identifier.
        :param str id: The security group target identifier.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse
        """

        if not security_group_id:
            raise ValueError('security_group_id must be provided')
        if not id:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='delete_security_group_target_binding',
        )
        headers.update(sdk_headers)

        params = {
            'version': self.version,
            'generation': self.generation,
        }

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
            del kwargs['headers']

        path_param_keys = ['security_group_id', 'id']
        path_param_values = self.encode_path_vars(security_group_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/security_groups/{security_group_id}/targets/{id}'.format(**path_param_dict)
        request = self.prepare_request(
            method='DELETE',
            url=url,
            headers=headers,
            params=params,
        )

        response = self.send(request, **kwargs)
        return response

    def get_security_group_target(
        self,
        security_group_id: str,
        id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Retrieve a security group target.

        This request retrieves a single target specified by the identifier in the URL
        path. The target must be an existing target of the security group.

        :param str security_group_id: The security group identifier.
        :param str id: The security group target identifier.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `SecurityGroupTargetReference` object
        """

        if not security_group_id:
            raise ValueError('security_group_id must be provided')
        if not id:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='get_security_group_target',
        )
        headers.update(sdk_headers)

        params = {
            'version': self.version,
            'generation': self.generation,
        }

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
            del kwargs['headers']
        headers['Accept'] = 'application/json'

        path_param_keys = ['security_group_id', 'id']
        path_param_values = self.encode_path_vars(security_group_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/security_groups/{security_group_id}/targets/{id}'.format(**path_param_dict)
        request = self.prepare_request(
            method='GET',
            url=url,
            headers=headers,
            params=params,
        )

        response = self.send(request, **kwargs)
        return response

    def create_security_group_target_binding(
        self,
        security_group_id: str,
        id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Add a target to a security group.

        This request adds a resource to an existing security group. The specified target
        identifier can be:
        - A bare metal server network interface identifier
        - A virtual network interface identifier
        - A VPN server identifier
        - A load balancer identifier
        - An endpoint gateway identifier
        - An instance network interface identifier
        When a target is added to a security group, the security group rules are applied
        to the target. A request body is not required, and if provided, is ignored.

        :param str security_group_id: The security group identifier.
        :param str id: The security group target identifier.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `SecurityGroupTargetReference` object
        """

        if not security_group_id:
            raise ValueError('security_group_id must be provided')
        if not id:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='create_security_group_target_binding',
        )
        headers.update(sdk_headers)

        params = {
            'version': self.version,
            'generation': self.generation,
        }

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
            del kwargs['headers']
        headers['Accept'] = 'application/json'

        path_param_keys = ['security_group_id', 'id']
        path_param_values = self.encode_path_vars(security_group_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/security_groups/{security_group_id}/targets/{id}'.format(**path_param_dict)
        request = self.prepare_request(
            method='PUT',
            url=url,
            headers=headers,
            params=params,
        )

        response = self.send(request, **kwargs)
        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-provided 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'))
            del kwargs['headers']
        headers['Accept'] = 'application/json'

        url = '/ike_policies'
        request = self.prepare_request(
            method='GET',
            url=url,
            headers=headers,
            params=params,
        )

        response = self.send(request, **kwargs)
        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 name for this IKE policy. The name must not
               be used by another IKE policies in the region. 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) will be
               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'))
            del kwargs['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, **kwargs)
        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. For this
        request to succeed, there must not be any VPN gateway connections using this
        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
        """

        if not id:
            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'))
            del kwargs['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, **kwargs)
        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 not id:
            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'))
            del kwargs['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, **kwargs)
        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 not id:
            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'))
            del kwargs['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, **kwargs)
        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 not id:
            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'))
            del kwargs['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, **kwargs)
        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-provided 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'))
            del kwargs['headers']
        headers['Accept'] = 'application/json'

        url = '/ipsec_policies'
        request = self.prepare_request(
            method='GET',
            url=url,
            headers=headers,
            params=params,
        )

        response = self.send(request, **kwargs)
        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
               Must be `disabled` if and only if the `encryption_algorithm` is
               `aes128gcm16`, `aes192gcm16`, or `aes256gcm16`.
        :param str encryption_algorithm: The encryption algorithm
               The `authentication_algorithm` must be `disabled` if and only if
               `encryption_algorithm` is `aes128gcm16`, `aes192gcm16`, or
               `aes256gcm16`.
        :param str pfs: Perfect Forward Secrecy.
        :param int key_lifetime: (optional) The key lifetime in seconds.
        :param str name: (optional) The name for this IPsec policy. The name must
               not be used by another IPsec policies in the region. 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) will be
               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'))
            del kwargs['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, **kwargs)
        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. For this
        request to succeed, there must not be any VPN gateway connections using this
        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
        """

        if not id:
            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'))
            del kwargs['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, **kwargs)
        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 not id:
            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'))
            del kwargs['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, **kwargs)
        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 not id:
            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'))
            del kwargs['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, **kwargs)
        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 not id:
            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'))
            del kwargs['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, **kwargs)
        return response

    def list_vpn_gateways(
        self,
        *,
        start: str = None,
        limit: int = None,
        resource_group_id: str = None,
        sort: 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-provided 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 with a `resource_group.id` property matching the specified
               identifier.
        :param str sort: (optional) Sorts the returned collection by the specified
               property name in ascending order. A `-` may be prepended to the name to
               sort in descending order. For example, the value `-created_at` sorts the
               collection by the `created_at` property in descending order, and the value
               `name` sorts it by the `name` property in ascending order.
        :param str mode: (optional) Filters the collection to VPN gateways with a
               `mode` property matching the specified value.
        :param dict headers: 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,
            'sort': sort,
            'mode': mode,
        }

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
            del kwargs['headers']
        headers['Accept'] = 'application/json'

        url = '/vpn_gateways'
        request = self.prepare_request(
            method='GET',
            url=url,
            headers=headers,
            params=params,
        )

        response = self.send(request, **kwargs)
        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'))
            del kwargs['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, **kwargs)
        return response

    def delete_vpn_gateway(
        self,
        id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Delete a VPN gateway.

        This request deletes a VPN gateway. This operation cannot be reversed. For this
        request to succeed, the VPN gateway must not have a `status` of `pending`, and
        there must not be any VPC routes using the VPN gateway's connections as a next
        hop.

        :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 not id:
            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'))
            del kwargs['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, **kwargs)
        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 not id:
            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'))
            del kwargs['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, **kwargs)
        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 not id:
            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'))
            del kwargs['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, **kwargs)
        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 a `status` property matching the specified value.
        :param dict headers: 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 not vpn_gateway_id:
            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'))
            del kwargs['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, **kwargs)
        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 not vpn_gateway_id:
            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'))
            del kwargs['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, **kwargs)
        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.
        For this request to succeed, there must not be VPC routes using this VPN
        connection as a next hop.

        :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 not vpn_gateway_id:
            raise ValueError('vpn_gateway_id must be provided')
        if not id:
            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'))
            del kwargs['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, **kwargs)
        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 not vpn_gateway_id:
            raise ValueError('vpn_gateway_id must be provided')
        if not id:
            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'))
            del kwargs['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, **kwargs)
        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 not vpn_gateway_id:
            raise ValueError('vpn_gateway_id must be provided')
        if not id:
            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'))
            del kwargs['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, **kwargs)
        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.
        This request is only supported for policy mode VPN gateways.

        :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 not vpn_gateway_id:
            raise ValueError('vpn_gateway_id must be provided')
        if not id:
            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'))
            del kwargs['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, **kwargs)
        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.
        This request is only supported for policy mode VPN gateways.

        :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 not vpn_gateway_id:
            raise ValueError('vpn_gateway_id must be provided')
        if not id:
            raise ValueError('id must be provided')
        if not cidr_prefix:
            raise ValueError('cidr_prefix must be provided')
        if not prefix_length:
            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'))
            del kwargs['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, **kwargs)
        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.
        This request is only supported for policy mode VPN gateways.

        :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 not vpn_gateway_id:
            raise ValueError('vpn_gateway_id must be provided')
        if not id:
            raise ValueError('id must be provided')
        if not cidr_prefix:
            raise ValueError('cidr_prefix must be provided')
        if not prefix_length:
            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'))
            del kwargs['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, **kwargs)
        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. This
        request succeeds if the specified CIDR already exists. A request body is not
        required, and if provided, is ignored.
        This request is only supported for policy mode VPN gateways.

        :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 not vpn_gateway_id:
            raise ValueError('vpn_gateway_id must be provided')
        if not id:
            raise ValueError('id must be provided')
        if not cidr_prefix:
            raise ValueError('cidr_prefix must be provided')
        if not prefix_length:
            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'))
            del kwargs['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, **kwargs)
        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.
        This request is only supported for policy mode VPN gateways.

        :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 not vpn_gateway_id:
            raise ValueError('vpn_gateway_id must be provided')
        if not id:
            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'))
            del kwargs['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, **kwargs)
        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.
        This request is only supported for policy mode VPN gateways.

        :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 not vpn_gateway_id:
            raise ValueError('vpn_gateway_id must be provided')
        if not id:
            raise ValueError('id must be provided')
        if not cidr_prefix:
            raise ValueError('cidr_prefix must be provided')
        if not prefix_length:
            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'))
            del kwargs['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, **kwargs)
        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.
        This request is only supported for policy mode VPN gateways.

        :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 not vpn_gateway_id:
            raise ValueError('vpn_gateway_id must be provided')
        if not id:
            raise ValueError('id must be provided')
        if not cidr_prefix:
            raise ValueError('cidr_prefix must be provided')
        if not prefix_length:
            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'))
            del kwargs['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, **kwargs)
        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. This
        request succeeds if the specified CIDR already exists. A request body is not
        required, and if provided, is ignored.
        This request is only supported for policy mode VPN gateways.

        :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 not vpn_gateway_id:
            raise ValueError('vpn_gateway_id must be provided')
        if not id:
            raise ValueError('id must be provided')
        if not cidr_prefix:
            raise ValueError('cidr_prefix must be provided')
        if not prefix_length:
            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'))
            del kwargs['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, **kwargs)
        return response

    #########################
    # VPN servers
    #########################

    def list_vpn_servers(
        self,
        *,
        name: str = None,
        start: str = None,
        limit: int = None,
        resource_group_id: str = None,
        sort: str = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        List all VPN servers.

        This request lists all VPN servers.

        :param str name: (optional) Filters the collection to resources with a
               `name` property matching the exact specified name.
        :param str start: (optional) A server-provided 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 with a `resource_group.id` property matching the specified
               identifier.
        :param str sort: (optional) Sorts the returned collection by the specified
               property name in ascending order. A `-` may be prepended to the name to
               sort in descending order. For example, the value `-created_at` sorts the
               collection by the `created_at` property in descending order, and the value
               `name` sorts it by the `name` property in ascending order.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `VPNServerCollection` object
        """

        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='list_vpn_servers',
        )
        headers.update(sdk_headers)

        params = {
            'version': self.version,
            'generation': self.generation,
            'name': name,
            'start': start,
            'limit': limit,
            'resource_group.id': resource_group_id,
            'sort': sort,
        }

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
            del kwargs['headers']
        headers['Accept'] = 'application/json'

        url = '/vpn_servers'
        request = self.prepare_request(
            method='GET',
            url=url,
            headers=headers,
            params=params,
        )

        response = self.send(request, **kwargs)
        return response

    def create_vpn_server(
        self,
        certificate: 'CertificateInstanceIdentity',
        client_authentication: List['VPNServerAuthenticationPrototype'],
        client_ip_pool: str,
        subnets: List['SubnetIdentity'],
        *,
        client_dns_server_ips: List['IP'] = None,
        client_idle_timeout: int = None,
        enable_split_tunneling: bool = None,
        name: str = None,
        port: int = None,
        protocol: str = None,
        resource_group: 'ResourceGroupIdentity' = None,
        security_groups: List['SecurityGroupIdentity'] = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        Create a VPN server.

        This request creates a new VPN server.

        :param CertificateInstanceIdentity certificate: The certificate instance
               for this VPN server.
        :param List[VPNServerAuthenticationPrototype] client_authentication: The
               methods used to authenticate VPN clients to this VPN server. VPN clients
               must authenticate against all specified methods.
        :param str client_ip_pool: The VPN client IPv4 address pool, 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 client IP address pool's CIDR must be between
               `/9` (8,388,608 addresses) and `/22` (1024 addresses). A CIDR block that
               contains twice the number of IP addresses that are required to enable the
               maximum number of concurrent connections is recommended.
        :param List[SubnetIdentity] subnets: The subnets to provision this VPN
               server in.  Use subnets in different zones for high availability.
        :param List[IP] client_dns_server_ips: (optional) The DNS server addresses
               that will be provided to VPN clients connected to this VPN server.
        :param int client_idle_timeout: (optional) The seconds a VPN client can be
               idle before this VPN server will disconnect it.   Specify `0` to prevent
               the server from disconnecting idle clients.
        :param bool enable_split_tunneling: (optional) Indicates whether the split
               tunneling is enabled on this VPN server.
        :param str name: (optional) The name for this VPN server. The name must not
               be used by another VPN server in the VPC. If unspecified, the name will be
               a hyphenated list of randomly-selected words.
        :param int port: (optional) The port number to use for this VPN server.
        :param str protocol: (optional) The transport protocol to use for this VPN
               server.
        :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) will be
               used.
        :param List[SecurityGroupIdentity] security_groups: (optional) The security
               groups to use for this VPN server. If unspecified, the VPC's default
               security group 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 `VPNServer` object
        """

        if certificate is None:
            raise ValueError('certificate must be provided')
        if client_authentication is None:
            raise ValueError('client_authentication must be provided')
        if client_ip_pool is None:
            raise ValueError('client_ip_pool must be provided')
        if subnets is None:
            raise ValueError('subnets must be provided')
        certificate = convert_model(certificate)
        client_authentication = [convert_model(x) for x in client_authentication]
        subnets = [convert_model(x) for x in subnets]
        if client_dns_server_ips is not None:
            client_dns_server_ips = [convert_model(x) for x in client_dns_server_ips]
        if resource_group is not None:
            resource_group = convert_model(resource_group)
        if security_groups is not None:
            security_groups = [convert_model(x) for x in security_groups]
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='create_vpn_server',
        )
        headers.update(sdk_headers)

        params = {
            'version': self.version,
            'generation': self.generation,
        }

        data = {
            'certificate': certificate,
            'client_authentication': client_authentication,
            'client_ip_pool': client_ip_pool,
            'subnets': subnets,
            'client_dns_server_ips': client_dns_server_ips,
            'client_idle_timeout': client_idle_timeout,
            'enable_split_tunneling': enable_split_tunneling,
            'name': name,
            'port': port,
            'protocol': protocol,
            'resource_group': resource_group,
            'security_groups': security_groups,
        }
        data = {k: v for (k, v) in data.items() if v is not None}
        data = json.dumps(data)
        headers['content-type'] = 'application/json'

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
            del kwargs['headers']
        headers['Accept'] = 'application/json'

        url = '/vpn_servers'
        request = self.prepare_request(
            method='POST',
            url=url,
            headers=headers,
            params=params,
            data=data,
        )

        response = self.send(request, **kwargs)
        return response

    def delete_vpn_server(
        self,
        id: str,
        *,
        if_match: str = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        Delete a VPN server.

        This request deletes a VPN server. This operation cannot be reversed.

        :param str id: The VPN server identifier.
        :param str if_match: (optional) If present, the request will fail if the
               specified ETag value does not match the resource's current ETag value.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse
        """

        if not id:
            raise ValueError('id must be provided')
        headers = {
            'If-Match': if_match,
        }
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='delete_vpn_server',
        )
        headers.update(sdk_headers)

        params = {
            'version': self.version,
            'generation': self.generation,
        }

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
            del kwargs['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_servers/{id}'.format(**path_param_dict)
        request = self.prepare_request(
            method='DELETE',
            url=url,
            headers=headers,
            params=params,
        )

        response = self.send(request, **kwargs)
        return response

    def get_vpn_server(
        self,
        id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Retrieve a VPN server.

        This request retrieves a single VPN server specified by the identifier in the URL.

        :param str id: The VPN server 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 `VPNServer` object
        """

        if not id:
            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_server',
        )
        headers.update(sdk_headers)

        params = {
            'version': self.version,
            'generation': self.generation,
        }

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
            del kwargs['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_servers/{id}'.format(**path_param_dict)
        request = self.prepare_request(
            method='GET',
            url=url,
            headers=headers,
            params=params,
        )

        response = self.send(request, **kwargs)
        return response

    def update_vpn_server(
        self,
        id: str,
        vpn_server_patch: 'VPNServerPatch',
        *,
        if_match: str = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        Update a VPN server.

        This request updates the properties of an existing VPN server. Any property
        changes will cause all connected VPN clients are disconnected from this VPN server
        except for the name change.

        :param str id: The VPN server identifier.
        :param VPNServerPatch vpn_server_patch: The VPN server patch.
        :param str if_match: (optional) If present, the request will fail if the
               specified ETag value does not match the resource's current ETag value.
               Required if the request body includes an array.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `VPNServer` object
        """

        if not id:
            raise ValueError('id must be provided')
        if vpn_server_patch is None:
            raise ValueError('vpn_server_patch must be provided')
        if isinstance(vpn_server_patch, VPNServerPatch):
            vpn_server_patch = convert_model(vpn_server_patch)
        headers = {
            'If-Match': if_match,
        }
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='update_vpn_server',
        )
        headers.update(sdk_headers)

        params = {
            'version': self.version,
            'generation': self.generation,
        }

        data = json.dumps(vpn_server_patch)
        headers['content-type'] = 'application/merge-patch+json'

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
            del kwargs['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_servers/{id}'.format(**path_param_dict)
        request = self.prepare_request(
            method='PATCH',
            url=url,
            headers=headers,
            params=params,
            data=data,
        )

        response = self.send(request, **kwargs)
        return response

    def get_vpn_server_client_configuration(
        self,
        id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Retrieve client configuration.

        This request retrieves OpenVPN client configuration on a single VPN server
        specified by the identifier in the URL. This configuration includes directives
        compatible with OpenVPN releases 2.4 and 2.5.

        :param str id: The VPN server identifier.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `str` result
        """

        if not id:
            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_server_client_configuration',
        )
        headers.update(sdk_headers)

        params = {
            'version': self.version,
            'generation': self.generation,
        }

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
            del kwargs['headers']
        headers['Accept'] = 'text/plain'

        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_servers/{id}/client_configuration'.format(**path_param_dict)
        request = self.prepare_request(
            method='GET',
            url=url,
            headers=headers,
            params=params,
        )

        response = self.send(request, **kwargs)
        return response

    def list_vpn_server_clients(
        self,
        vpn_server_id: str,
        *,
        start: str = None,
        limit: int = None,
        sort: str = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        List all VPN clients for a VPN server.

        This request retrieves all connected VPN clients, and any disconnected VPN clients
        that the VPN server has not yet deleted based on its auto-deletion policy.

        :param str vpn_server_id: The VPN server identifier.
        :param str start: (optional) A server-provided token determining what
               resource to start the page on.
        :param int limit: (optional) The number of resources to return on a page.
        :param str sort: (optional) Sorts the returned collection by the specified
               property name in ascending order. A `-` may be prepended to the name to
               sort in descending order. For example, the value `-created_at` sorts the
               collection by the `created_at` property in descending order.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `VPNServerClientCollection` object
        """

        if not vpn_server_id:
            raise ValueError('vpn_server_id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='list_vpn_server_clients',
        )
        headers.update(sdk_headers)

        params = {
            'version': self.version,
            'generation': self.generation,
            'start': start,
            'limit': limit,
            'sort': sort,
        }

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
            del kwargs['headers']
        headers['Accept'] = 'application/json'

        path_param_keys = ['vpn_server_id']
        path_param_values = self.encode_path_vars(vpn_server_id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/vpn_servers/{vpn_server_id}/clients'.format(**path_param_dict)
        request = self.prepare_request(
            method='GET',
            url=url,
            headers=headers,
            params=params,
        )

        response = self.send(request, **kwargs)
        return response

    def delete_vpn_server_client(
        self,
        vpn_server_id: str,
        id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Delete a VPN client.

        This request disconnects and deletes the VPN client from the VPN server. The VPN
        client may reconnect unless its authentication permissions for the configured
        authentication methods (such as its client certificate) have been revoked.

        :param str vpn_server_id: The VPN server identifier.
        :param str id: The VPN client identifier.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse
        """

        if not vpn_server_id:
            raise ValueError('vpn_server_id must be provided')
        if not id:
            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_server_client',
        )
        headers.update(sdk_headers)

        params = {
            'version': self.version,
            'generation': self.generation,
        }

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
            del kwargs['headers']

        path_param_keys = ['vpn_server_id', 'id']
        path_param_values = self.encode_path_vars(vpn_server_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/vpn_servers/{vpn_server_id}/clients/{id}'.format(**path_param_dict)
        request = self.prepare_request(
            method='DELETE',
            url=url,
            headers=headers,
            params=params,
        )

        response = self.send(request, **kwargs)
        return response

    def get_vpn_server_client(
        self,
        vpn_server_id: str,
        id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Retrieve a VPN client.

        This request retrieves a single VPN client specified by the identifier in the URL.

        :param str vpn_server_id: The VPN server identifier.
        :param str id: The VPN client 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 `VPNServerClient` object
        """

        if not vpn_server_id:
            raise ValueError('vpn_server_id must be provided')
        if not id:
            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_server_client',
        )
        headers.update(sdk_headers)

        params = {
            'version': self.version,
            'generation': self.generation,
        }

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
            del kwargs['headers']
        headers['Accept'] = 'application/json'

        path_param_keys = ['vpn_server_id', 'id']
        path_param_values = self.encode_path_vars(vpn_server_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/vpn_servers/{vpn_server_id}/clients/{id}'.format(**path_param_dict)
        request = self.prepare_request(
            method='GET',
            url=url,
            headers=headers,
            params=params,
        )

        response = self.send(request, **kwargs)
        return response

    def disconnect_vpn_client(
        self,
        vpn_server_id: str,
        id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Disconnect a VPN client.

        This request disconnects the specified VPN client, and deletes the client
        according to the VPN server's auto-deletion policy. The VPN client may reconnect
        unless its authentication permissions for the configured authentication methods
        (such as its client certificate) have been revoked.

        :param str vpn_server_id: The VPN server identifier.
        :param str id: The VPN client identifier.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse
        """

        if not vpn_server_id:
            raise ValueError('vpn_server_id must be provided')
        if not id:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='disconnect_vpn_client',
        )
        headers.update(sdk_headers)

        params = {
            'version': self.version,
            'generation': self.generation,
        }

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
            del kwargs['headers']

        path_param_keys = ['vpn_server_id', 'id']
        path_param_values = self.encode_path_vars(vpn_server_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/vpn_servers/{vpn_server_id}/clients/{id}/disconnect'.format(**path_param_dict)
        request = self.prepare_request(
            method='POST',
            url=url,
            headers=headers,
            params=params,
        )

        response = self.send(request, **kwargs)
        return response

    def list_vpn_server_routes(
        self,
        vpn_server_id: str,
        *,
        start: str = None,
        limit: int = None,
        sort: str = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        List all VPN routes for a VPN server.

        This request lists all VPN routes in a VPN server. All VPN routes are provided to
        the VPN client when the connection is established.  Packets received from the VPN
        client will be dropped by the VPN server if there is no VPN route matching their
        specified destinations. All VPN routes must be unique within the VPN server.

        :param str vpn_server_id: The VPN server identifier.
        :param str start: (optional) A server-provided token determining what
               resource to start the page on.
        :param int limit: (optional) The number of resources to return on a page.
        :param str sort: (optional) Sorts the returned collection by the specified
               property name in ascending order. A `-` may be prepended to the name to
               sort in descending order. For example, the value `-created_at` sorts the
               collection by the `created_at` property in descending order, and the value
               `name` sorts it by the `name` property in ascending order.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `VPNServerRouteCollection` object
        """

        if not vpn_server_id:
            raise ValueError('vpn_server_id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='list_vpn_server_routes',
        )
        headers.update(sdk_headers)

        params = {
            'version': self.version,
            'generation': self.generation,
            'start': start,
            'limit': limit,
            'sort': sort,
        }

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
            del kwargs['headers']
        headers['Accept'] = 'application/json'

        path_param_keys = ['vpn_server_id']
        path_param_values = self.encode_path_vars(vpn_server_id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/vpn_servers/{vpn_server_id}/routes'.format(**path_param_dict)
        request = self.prepare_request(
            method='GET',
            url=url,
            headers=headers,
            params=params,
        )

        response = self.send(request, **kwargs)
        return response

    def create_vpn_server_route(
        self,
        vpn_server_id: str,
        destination: str,
        *,
        action: str = None,
        name: str = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        Create a VPN route for a VPN server.

        This request creates a new VPN route in the VPN server. All VPN routes are
        provided to the VPN client when the connection is established. Packets received
        from the VPN client will be dropped by the VPN server if there is no VPN route
        matching their specified destinations. All VPN routes must be unique within the
        VPN server. destination of the packet.

        :param str vpn_server_id: The VPN server identifier.
        :param str destination: The destination to use for this VPN route in the
               VPN server. Must be unique within the VPN server. If an incoming packet
               does not match any destination, it will be dropped.
        :param str action: (optional) The action to perform with a packet matching
               the VPN route:
               - `translate`: translate the source IP address to one of the private IP
               addresses of the VPN server, then deliver the packet to target.
               - `deliver`: deliver the packet to the target.
               - `drop`: drop the packet
               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 VPN route
               on which the unexpected property value was encountered.
        :param str name: (optional) The name for this VPN server route. The name
               must not be used by another route for the VPN server. 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 `VPNServerRoute` object
        """

        if not vpn_server_id:
            raise ValueError('vpn_server_id must be provided')
        if destination is None:
            raise ValueError('destination must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='create_vpn_server_route',
        )
        headers.update(sdk_headers)

        params = {
            'version': self.version,
            'generation': self.generation,
        }

        data = {
            'destination': destination,
            'action': action,
            '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'))
            del kwargs['headers']
        headers['Accept'] = 'application/json'

        path_param_keys = ['vpn_server_id']
        path_param_values = self.encode_path_vars(vpn_server_id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/vpn_servers/{vpn_server_id}/routes'.format(**path_param_dict)
        request = self.prepare_request(
            method='POST',
            url=url,
            headers=headers,
            params=params,
            data=data,
        )

        response = self.send(request, **kwargs)
        return response

    def delete_vpn_server_route(
        self,
        vpn_server_id: str,
        id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Delete a VPN route.

        This request deletes a VPN route. This operation cannot be reversed.

        :param str vpn_server_id: The VPN server identifier.
        :param str id: The VPN 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 not vpn_server_id:
            raise ValueError('vpn_server_id must be provided')
        if not id:
            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_server_route',
        )
        headers.update(sdk_headers)

        params = {
            'version': self.version,
            'generation': self.generation,
        }

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
            del kwargs['headers']

        path_param_keys = ['vpn_server_id', 'id']
        path_param_values = self.encode_path_vars(vpn_server_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/vpn_servers/{vpn_server_id}/routes/{id}'.format(**path_param_dict)
        request = self.prepare_request(
            method='DELETE',
            url=url,
            headers=headers,
            params=params,
        )

        response = self.send(request, **kwargs)
        return response

    def get_vpn_server_route(
        self,
        vpn_server_id: str,
        id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Retrieve a VPN route.

        This request retrieves a single VPN route specified by the identifier in the URL.

        :param str vpn_server_id: The VPN server identifier.
        :param str id: The VPN 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 `VPNServerRoute` object
        """

        if not vpn_server_id:
            raise ValueError('vpn_server_id must be provided')
        if not id:
            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_server_route',
        )
        headers.update(sdk_headers)

        params = {
            'version': self.version,
            'generation': self.generation,
        }

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
            del kwargs['headers']
        headers['Accept'] = 'application/json'

        path_param_keys = ['vpn_server_id', 'id']
        path_param_values = self.encode_path_vars(vpn_server_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/vpn_servers/{vpn_server_id}/routes/{id}'.format(**path_param_dict)
        request = self.prepare_request(
            method='GET',
            url=url,
            headers=headers,
            params=params,
        )

        response = self.send(request, **kwargs)
        return response

    def update_vpn_server_route(
        self,
        vpn_server_id: str,
        id: str,
        vpn_server_route_patch: 'VPNServerRoutePatch',
        **kwargs,
    ) -> DetailedResponse:
        """
        Update a VPN route.

        This request updates a VPN route with the information in a provided VPN route
        patch. The VPN route patch object is structured in the same way as a retrieved VPN
        route and contains only the information to be updated.

        :param str vpn_server_id: The VPN server identifier.
        :param str id: The VPN route identifier.
        :param VPNServerRoutePatch vpn_server_route_patch: The VPN 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 `VPNServerRoute` object
        """

        if not vpn_server_id:
            raise ValueError('vpn_server_id must be provided')
        if not id:
            raise ValueError('id must be provided')
        if vpn_server_route_patch is None:
            raise ValueError('vpn_server_route_patch must be provided')
        if isinstance(vpn_server_route_patch, VPNServerRoutePatch):
            vpn_server_route_patch = convert_model(vpn_server_route_patch)
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='update_vpn_server_route',
        )
        headers.update(sdk_headers)

        params = {
            'version': self.version,
            'generation': self.generation,
        }

        data = json.dumps(vpn_server_route_patch)
        headers['content-type'] = 'application/merge-patch+json'

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
            del kwargs['headers']
        headers['Accept'] = 'application/json'

        path_param_keys = ['vpn_server_id', 'id']
        path_param_values = self.encode_path_vars(vpn_server_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/vpn_servers/{vpn_server_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, **kwargs)
        return response

    #########################
    # Load balancers
    #########################

    def list_load_balancer_profiles(
        self,
        *,
        start: str = None,
        limit: int = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        List all load balancer profiles.

        This request lists all load balancer profiles available in the region. A load
        balancer profile specifies the performance characteristics and pricing model for a
        load balancer.

        :param str start: (optional) A server-provided token determining what
               resource to start the page on.
        :param int limit: (optional) The number of resources to return on a page.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `LoadBalancerProfileCollection` object
        """

        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='list_load_balancer_profiles',
        )
        headers.update(sdk_headers)

        params = {
            'version': self.version,
            'generation': self.generation,
            'start': start,
            'limit': limit,
        }

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
            del kwargs['headers']
        headers['Accept'] = 'application/json'

        url = '/load_balancer/profiles'
        request = self.prepare_request(
            method='GET',
            url=url,
            headers=headers,
            params=params,
        )

        response = self.send(request, **kwargs)
        return response

    def get_load_balancer_profile(
        self,
        name: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Retrieve a load balancer profile.

        This request retrieves a load balancer profile specified by the name in the URL.

        :param str name: The load balancer profile name.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `LoadBalancerProfile` object
        """

        if not name:
            raise ValueError('name must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='get_load_balancer_profile',
        )
        headers.update(sdk_headers)

        params = {
            'version': self.version,
            'generation': self.generation,
        }

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
            del kwargs['headers']
        headers['Accept'] = 'application/json'

        path_param_keys = ['name']
        path_param_values = self.encode_path_vars(name)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/load_balancer/profiles/{name}'.format(**path_param_dict)
        request = self.prepare_request(
            method='GET',
            url=url,
            headers=headers,
            params=params,
        )

        response = self.send(request, **kwargs)
        return response

    def list_load_balancers(
        self,
        *,
        start: str = None,
        limit: int = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        List all load balancers.

        This request lists all load balancers in the region.

        :param str start: (optional) A server-provided 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 `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,
            'start': start,
            'limit': limit,
        }

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
            del kwargs['headers']
        headers['Accept'] = 'application/json'

        url = '/load_balancers'
        request = self.prepare_request(
            method='GET',
            url=url,
            headers=headers,
            params=params,
        )

        response = self.send(request, **kwargs)
        return response

    def create_load_balancer(
        self,
        is_public: bool,
        subnets: List['SubnetIdentity'],
        *,
        datapath: 'LoadBalancerLoggingDatapathPrototype' = None,
        dns: 'LoadBalancerDNSPrototype' = None,
        listeners: List['LoadBalancerListenerPrototypeLoadBalancerContext'] = None,
        logging: 'LoadBalancerLoggingPrototype' = None,
        name: str = None,
        pools: List['LoadBalancerPoolPrototype'] = None,
        profile: 'LoadBalancerProfileIdentity' = None,
        resource_group: 'ResourceGroupIdentity' = None,
        route_mode: bool = None,
        security_groups: List['SecurityGroupIdentity'] = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        Create a load balancer.

        This request creates and provisions a new load balancer.

        :param bool is_public: Indicates whether this load balancer is public.
               At present, if route mode is enabled, the load balancer must not be public.
        :param List[SubnetIdentity] subnets: The subnets to provision this load
               balancer in. The subnets must be in the same VPC. The load balancer's
               availability will depend on the availability of the zones that the subnets
               reside in.
               Load balancers in the `network` family allow only one subnet to be
               specified.
        :param LoadBalancerLoggingDatapathPrototype datapath: (optional) The
               datapath logging configuration for this load balancer.
        :param LoadBalancerDNSPrototype dns: (optional) The DNS configuration for
               this load balancer.
               If unspecified, DNS `A` records for this load balancer's `hostname`
               property will be added
               to the public DNS zone `lb.appdomain.cloud`. Otherwise, those DNS `A`
               records will be
               added to the specified `zone`.
        :param List[LoadBalancerListenerPrototypeLoadBalancerContext] listeners:
               (optional) The listeners of this load balancer.
        :param LoadBalancerLoggingPrototype 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 name for this load balancer. The name must
               not be used by another load balancer in the VPC.  If unspecified, the name
               will be a hyphenated list of randomly-selected words.
        :param List[LoadBalancerPoolPrototype] pools: (optional) The pools of this
               load balancer.
        :param LoadBalancerProfileIdentity profile: (optional) The profile to use
               for this load balancer.
               If unspecified, `application` will be used.
        :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) will be
               used.
        :param bool route_mode: (optional) Indicates whether route mode is enabled
               for this load balancer.
               At present, public load balancers are not supported with route mode
               enabled.
        :param List[SecurityGroupIdentity] security_groups: (optional) The security
               groups to use for this load balancer. If unspecified, the VPC's default
               security group is used.
               The load balancer profile must support security groups.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `LoadBalancer` object
        """

        if is_public is None:
            raise ValueError('is_public must be provided')
        if subnets is None:
            raise ValueError('subnets must be provided')
        subnets = [convert_model(x) for x in subnets]
        if datapath is not None:
            datapath = convert_model(datapath)
        if dns is not None:
            dns = convert_model(dns)
        if listeners is not None:
            listeners = [convert_model(x) for x in listeners]
        if logging is not None:
            logging = convert_model(logging)
        if pools is not None:
            pools = [convert_model(x) for x in pools]
        if profile is not None:
            profile = convert_model(profile)
        if resource_group is not None:
            resource_group = convert_model(resource_group)
        if security_groups is not None:
            security_groups = [convert_model(x) for x in security_groups]
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='create_load_balancer',
        )
        headers.update(sdk_headers)

        params = {
            'version': self.version,
            'generation': self.generation,
        }

        data = {
            'is_public': is_public,
            'subnets': subnets,
            'datapath': datapath,
            'dns': dns,
            'listeners': listeners,
            'logging': logging,
            'name': name,
            'pools': pools,
            'profile': profile,
            'resource_group': resource_group,
            'route_mode': route_mode,
            'security_groups': security_groups,
        }
        data = {k: v for (k, v) in data.items() if v is not None}
        data = json.dumps(data)
        headers['content-type'] = 'application/json'

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
            del kwargs['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, **kwargs)
        return response

    def delete_load_balancer(
        self,
        id: str,
        *,
        if_match: str = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        Delete a load balancer.

        This request deletes a load balancer. This operation cannot be reversed. A load
        balancer cannot be deleted if its `provisioning_status` is `delete_pending`.

        :param str id: The load balancer identifier.
        :param str if_match: (optional) If present, the request will fail if the
               specified ETag value does not match the resource's current ETag value.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse
        """

        if not id:
            raise ValueError('id must be provided')
        headers = {
            'If-Match': if_match,
        }
        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'))
            del kwargs['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, **kwargs)
        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 not id:
            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'))
            del kwargs['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, **kwargs)
        return response

    def update_load_balancer(
        self,
        id: str,
        load_balancer_patch: 'LoadBalancerPatch',
        *,
        if_match: str = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        Update a load balancer.

        This request updates a load balancer with the information in a provided load
        balancer patch. The load balancer patch object is structured in the same way as a
        retrieved load balancer and contains only the information to be updated. A load
        balancer can only be updated if its `provisioning_status` is `active`.

        :param str id: The load balancer identifier.
        :param LoadBalancerPatch load_balancer_patch: The load balancer patch.
        :param str if_match: (optional) If present, the request will fail if the
               specified ETag value does not match the resource's current ETag value.
               Required if the request body includes an array.
        :param dict headers: 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 not id:
            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 = {
            'If-Match': if_match,
        }
        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'))
            del kwargs['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, **kwargs)
        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 not id:
            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'))
            del kwargs['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, **kwargs)
        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 not load_balancer_id:
            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'))
            del kwargs['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, **kwargs)
        return response

    def create_load_balancer_listener(
        self,
        load_balancer_id: str,
        protocol: str,
        *,
        accept_proxy_protocol: bool = None,
        certificate_instance: 'CertificateInstanceIdentity' = None,
        connection_limit: int = None,
        default_pool: 'LoadBalancerPoolIdentity' = None,
        https_redirect: 'LoadBalancerListenerHTTPSRedirectPrototype' = None,
        idle_connection_timeout: int = None,
        policies: List['LoadBalancerListenerPolicyPrototype'] = None,
        port: int = None,
        port_max: int = None,
        port_min: int = 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 str protocol: The listener protocol. Each listener in the load
               balancer must have a unique `port` and `protocol` combination.
               Load balancers in the `network` family support `tcp` and `udp` (if
               `udp_supported` is `true`). Load balancers in the `application` family
               support `tcp`, `http` and
               `https`.
               Additional restrictions:
               - If `default_pool` is set, the pool's protocol must match, or be
               compatible with
                 the listener's protocol. At present, the compatible protocols are `http`
               and
                 `https`.
               - If `https_redirect` is set, the protocol must be `http`.
        :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`).
               Additional restrictions:
               - If this listener has `https_redirect` specified, its
               `accept_proxy_protocol` value must
                 match the `accept_proxy_protocol` value of the `https_redirect` listener.
               - If this listener is the target of another listener's `https_redirect`,
               its
                 `accept_proxy_protocol` value must match that listener's
               `accept_proxy_protocol` value.
        :param CertificateInstanceIdentity certificate_instance: (optional) The
               certificate instance to use for SSL termination. The listener must have a
               `protocol` of `https`.
        :param int connection_limit: (optional) The connection limit of the
               listener.
        :param LoadBalancerPoolIdentity default_pool: (optional) The default pool
               for this listener. If specified, the pool must:
               - Belong to this load balancer.
               - Have the same `protocol` as this listener, or have a compatible protocol.
                 At present, the compatible protocols are `http` and `https`.
               - Not already be the `default_pool` for another listener.
               If unspecified, this listener will be created with no default pool, but one
               may be
               subsequently set.
        :param LoadBalancerListenerHTTPSRedirectPrototype https_redirect:
               (optional) The target listener that requests will be redirected to. This
               listener must have a
               `protocol` of `http`, and the target listener must have a `protocol` of
               `https`.
        :param int idle_connection_timeout: (optional) The idle connection timeout
               of the listener in seconds. Supported for load balancers in the
               `application` family.
        :param List[LoadBalancerListenerPolicyPrototype] policies: (optional) The
               policy prototype objects for this listener. The load balancer must be in
               the
               `application` family.
        :param int port: (optional) The listener port number, or the inclusive
               lower bound of the port range. Each listener in the load balancer must have
               a unique `port` and `protocol` combination.
               Not supported for load balancers operating with route mode enabled.
        :param int port_max: (optional) The inclusive upper bound of the range of
               ports used by this listener. Must not be less than `port_min`.
               At present, only load balancers operating with route mode enabled, and
               public load balancers in the `network` family support different values for
               `port_min` and
               `port_max`. When route mode is enabled, the value `65535` must be
               specified.
               The specified port range must not overlap with port ranges used by other
               listeners for this load balancer using the same protocol.
        :param int port_min: (optional) The inclusive lower bound of the range of
               ports used by this listener. Must not be greater than `port_max`.
               At present, only load balancers operating with route mode enabled, and
               public load balancers in the `network` family support different values for
               `port_min` and
               `port_max`. When route mode is enabled, the value `1` must be specified.
               The specified port range must not overlap with port ranges used by other
               listeners for this load balancer using the same protocol.
        :param dict headers: 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 not load_balancer_id:
            raise ValueError('load_balancer_id 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 https_redirect is not None:
            https_redirect = convert_model(https_redirect)
        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 = {
            'protocol': protocol,
            'accept_proxy_protocol': accept_proxy_protocol,
            'certificate_instance': certificate_instance,
            'connection_limit': connection_limit,
            'default_pool': default_pool,
            'https_redirect': https_redirect,
            'idle_connection_timeout': idle_connection_timeout,
            'policies': policies,
            'port': port,
            'port_max': port_max,
            'port_min': port_min,
        }
        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'))
            del kwargs['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, **kwargs)
        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.
        For this operation to succeed, the listener must not be the target of another load
        balancer listener.

        :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 not load_balancer_id:
            raise ValueError('load_balancer_id must be provided')
        if not id:
            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'))
            del kwargs['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, **kwargs)
        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 not load_balancer_id:
            raise ValueError('load_balancer_id must be provided')
        if not id:
            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'))
            del kwargs['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, **kwargs)
        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 not load_balancer_id:
            raise ValueError('load_balancer_id must be provided')
        if not id:
            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'))
            del kwargs['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, **kwargs)
        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 not load_balancer_id:
            raise ValueError('load_balancer_id must be provided')
        if not listener_id:
            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'))
            del kwargs['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, **kwargs)
        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.
               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 policy on
               which the unexpected property value was encountered.
        :param int priority: Priority of the policy. Lower value indicates higher
               priority.
        :param str name: (optional) The name for this policy. The name must not be
               used by another policy for the load balancer listener. If unspecified, the
               name will be a hyphenated list of randomly-selected words.
        :param List[LoadBalancerListenerPolicyRulePrototype] rules: (optional) The
               rule prototype objects for this policy.
        :param LoadBalancerListenerPolicyTargetPrototype target: (optional) - If
               `action` is `forward`, specify a `LoadBalancerPoolIdentity`.
               - If `action` is `redirect`, specify a
               `LoadBalancerListenerPolicyRedirectURLPrototype`.
               - If `action` is `https_redirect`, specify a
                 `LoadBalancerListenerPolicyHTTPSRedirectPrototype`.
        :param dict headers: 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 not load_balancer_id:
            raise ValueError('load_balancer_id must be provided')
        if not listener_id:
            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'))
            del kwargs['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, **kwargs)
        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 not load_balancer_id:
            raise ValueError('load_balancer_id must be provided')
        if not listener_id:
            raise ValueError('listener_id must be provided')
        if not id:
            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'))
            del kwargs['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, **kwargs)
        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 not load_balancer_id:
            raise ValueError('load_balancer_id must be provided')
        if not listener_id:
            raise ValueError('listener_id must be provided')
        if not id:
            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'))
            del kwargs['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, **kwargs)
        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 not load_balancer_id:
            raise ValueError('load_balancer_id must be provided')
        if not listener_id:
            raise ValueError('listener_id must be provided')
        if not id:
            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'))
            del kwargs['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, **kwargs)
        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 not load_balancer_id:
            raise ValueError('load_balancer_id must be provided')
        if not listener_id:
            raise ValueError('listener_id must be provided')
        if not policy_id:
            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'))
            del kwargs['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, **kwargs)
        return response

    def create_load_balancer_listener_policy_rule(
        self,
        load_balancer_id: str,
        listener_id: str,
        policy_id: str,
        condition: str,
        type: str,
        value: str,
        *,
        field: str = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        Create a rule for a load balancer listener policy.

        Creates a new rule for the load balancer listener policy.

        :param str load_balancer_id: The load balancer identifier.
        :param str listener_id: The listener identifier.
        :param str policy_id: The policy identifier.
        :param str condition: The condition of the rule.
        :param str type: The type of the rule.
               Body rules are applied to form-encoded request bodies using the `UTF-8`
               character set.
        :param str value: Value to be matched for rule condition.
               If the rule type is `query` and the rule condition is not `matches_regex`,
               the value must be percent-encoded.
        :param str field: (optional) The field. This is applicable to `header`,
               `query`, and `body` rule types.
               If the rule type is `header`, this property is required.
               If the rule type is `query`, this is optional. If specified and the rule
               condition is not
               `matches_regex`, the value must be percent-encoded.
               If the rule type is `body`, this is optional.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `LoadBalancerListenerPolicyRule` object
        """

        if not load_balancer_id:
            raise ValueError('load_balancer_id must be provided')
        if not listener_id:
            raise ValueError('listener_id must be provided')
        if not policy_id:
            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'))
            del kwargs['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, **kwargs)
        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 not load_balancer_id:
            raise ValueError('load_balancer_id must be provided')
        if not listener_id:
            raise ValueError('listener_id must be provided')
        if not policy_id:
            raise ValueError('policy_id must be provided')
        if not id:
            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'))
            del kwargs['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, **kwargs)
        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 not load_balancer_id:
            raise ValueError('load_balancer_id must be provided')
        if not listener_id:
            raise ValueError('listener_id must be provided')
        if not policy_id:
            raise ValueError('policy_id must be provided')
        if not id:
            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'))
            del kwargs['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, **kwargs)
        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 not load_balancer_id:
            raise ValueError('load_balancer_id must be provided')
        if not listener_id:
            raise ValueError('listener_id must be provided')
        if not policy_id:
            raise ValueError('policy_id must be provided')
        if not id:
            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'))
            del kwargs['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, **kwargs)
        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 not load_balancer_id:
            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'))
            del kwargs['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, **kwargs)
        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` and `udp` (if
               `udp_supported` is `true`). 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 name for this load balancer pool. The name
               must not be used by another pool for the load balancer. 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 not load_balancer_id:
            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'))
            del kwargs['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, **kwargs)
        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 not load_balancer_id:
            raise ValueError('load_balancer_id must be provided')
        if not id:
            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'))
            del kwargs['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, **kwargs)
        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 not load_balancer_id:
            raise ValueError('load_balancer_id must be provided')
        if not id:
            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'))
            del kwargs['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, **kwargs)
        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 not load_balancer_id:
            raise ValueError('load_balancer_id must be provided')
        if not id:
            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'))
            del kwargs['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, **kwargs)
        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 not load_balancer_id:
            raise ValueError('load_balancer_id must be provided')
        if not pool_id:
            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'))
            del kwargs['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, **kwargs)
        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 the member will receive load balancer traffic on.
               Applies only to load balancer traffic received on a listener with a single
               port. (If the traffic is received on a listener with a port range, the
               member will receive the traffic on the same port the listener received it
               on.)
               This port will also be used for health checks unless the `port` property of
               `health_monitor` property is specified.
               The port must be unique across all members for all pools associated with
               this pool's listener.
        :param LoadBalancerPoolMemberTargetPrototype target: The pool member
               target. Load balancers in the `network` family support virtual server
               instances. Load balancers in the `application` family support IP addresses.
               If the load
               balancer has route mode enabled, the member must be in a zone the load
               balancer has a
               subnet in.
        :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 not load_balancer_id:
            raise ValueError('load_balancer_id must be provided')
        if not pool_id:
            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'))
            del kwargs['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, **kwargs)
        return response

    def replace_load_balancer_pool_members(
        self,
        load_balancer_id: str,
        pool_id: str,
        members: List['LoadBalancerPoolMemberPrototype'],
        **kwargs,
    ) -> DetailedResponse:
        """
        Replace load balancer pool members.

        This request replaces the existing members of the load balancer pool with new
        members created from the collection of member prototype objects.

        :param str load_balancer_id: The load balancer identifier.
        :param str pool_id: The pool identifier.
        :param List[LoadBalancerPoolMemberPrototype] members: The member prototype
               objects for 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 `LoadBalancerPoolMemberCollection` object
        """

        if not load_balancer_id:
            raise ValueError('load_balancer_id must be provided')
        if not pool_id:
            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'))
            del kwargs['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, **kwargs)
        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 not load_balancer_id:
            raise ValueError('load_balancer_id must be provided')
        if not pool_id:
            raise ValueError('pool_id must be provided')
        if not id:
            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'))
            del kwargs['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, **kwargs)
        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 not load_balancer_id:
            raise ValueError('load_balancer_id must be provided')
        if not pool_id:
            raise ValueError('pool_id must be provided')
        if not id:
            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'))
            del kwargs['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, **kwargs)
        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 not load_balancer_id:
            raise ValueError('load_balancer_id must be provided')
        if not pool_id:
            raise ValueError('pool_id must be provided')
        if not id:
            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'))
            del kwargs['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, **kwargs)
        return response

    #########################
    # Endpoint gateways
    #########################

    def list_endpoint_gateways(
        self,
        *,
        name: str = None,
        start: str = None,
        limit: int = None,
        resource_group_id: str = None,
        vpc_id: str = None,
        vpc_crn: str = None,
        vpc_name: str = None,
        allow_dns_resolution_binding: bool = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        List all endpoint gateways.

        This request lists all endpoint gateways in the region. An endpoint gateway maps
        one or more reserved IPs in a VPC to a target outside the VPC.

        :param str name: (optional) Filters the collection to resources with a
               `name` property matching the exact specified name.
        :param str start: (optional) A server-provided 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 with a `resource_group.id` property matching the specified
               identifier.
        :param str vpc_id: (optional) Filters the collection to resources with a
               `vpc.id` property matching the specified identifier.
        :param str vpc_crn: (optional) Filters the collection to resources with a
               `vpc.crn` property matching the specified CRN.
        :param str vpc_name: (optional) Filters the collection to resources with a
               `vpc.name` property matching the exact specified name.
        :param bool allow_dns_resolution_binding: (optional) Filters the collection
               to endpoint gateways with an `allow_dns_resolution_binding` property
               matching the specified value.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `EndpointGatewayCollection` object
        """

        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='list_endpoint_gateways',
        )
        headers.update(sdk_headers)

        params = {
            'version': self.version,
            'generation': self.generation,
            'name': name,
            'start': start,
            'limit': limit,
            'resource_group.id': resource_group_id,
            'vpc.id': vpc_id,
            'vpc.crn': vpc_crn,
            'vpc.name': vpc_name,
            'allow_dns_resolution_binding': allow_dns_resolution_binding,
        }

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
            del kwargs['headers']
        headers['Accept'] = 'application/json'

        url = '/endpoint_gateways'
        request = self.prepare_request(
            method='GET',
            url=url,
            headers=headers,
            params=params,
        )

        response = self.send(request, **kwargs)
        return response

    def create_endpoint_gateway(
        self,
        target: 'EndpointGatewayTargetPrototype',
        vpc: 'VPCIdentity',
        *,
        allow_dns_resolution_binding: bool = None,
        ips: List['EndpointGatewayReservedIP'] = None,
        name: str = None,
        resource_group: 'ResourceGroupIdentity' = None,
        security_groups: List['SecurityGroupIdentity'] = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        Create an endpoint gateway.

        This request creates a new endpoint gateway. An endpoint gateway maps one or more
        reserved IPs in a VPC to a target outside the VPC.

        :param EndpointGatewayTargetPrototype target: The target to use for this
               endpoint gateway. Must not already be the target of another
               endpoint gateway in the VPC.
        :param VPCIdentity vpc: The VPC this endpoint gateway will reside in.
        :param bool allow_dns_resolution_binding: (optional) Indicates whether to
               allow DNS resolution for this endpoint gateway when the VPC this endpoint
               gateway resides in has a DNS resolution binding to a VPC with
               `dns.enable_hub` set to `true`.
               Must be `true` if the VPC this endpoint gateway resides in has
               `dns.enable_hub` set to
               `true`.
        :param List[EndpointGatewayReservedIP] ips: (optional) The reserved IPs to
               bind to this endpoint gateway. At most one reserved IP per zone is allowed.
        :param str name: (optional) The name for this endpoint gateway. The name
               must not be used by another endpoint gateway in the 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) will be
               used.
        :param List[SecurityGroupIdentity] security_groups: (optional) The security
               groups to use for this endpoint gateway. If unspecified, the VPC's default
               security group is used.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `EndpointGateway` object
        """

        if target is None:
            raise ValueError('target must be provided')
        if vpc is None:
            raise ValueError('vpc must be provided')
        target = convert_model(target)
        vpc = convert_model(vpc)
        if ips is not None:
            ips = [convert_model(x) for x in ips]
        if resource_group is not None:
            resource_group = convert_model(resource_group)
        if security_groups is not None:
            security_groups = [convert_model(x) for x in security_groups]
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='create_endpoint_gateway',
        )
        headers.update(sdk_headers)

        params = {
            'version': self.version,
            'generation': self.generation,
        }

        data = {
            'target': target,
            'vpc': vpc,
            'allow_dns_resolution_binding': allow_dns_resolution_binding,
            'ips': ips,
            'name': name,
            'resource_group': resource_group,
            'security_groups': security_groups,
        }
        data = {k: v for (k, v) in data.items() if v is not None}
        data = json.dumps(data)
        headers['content-type'] = 'application/json'

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
            del kwargs['headers']
        headers['Accept'] = 'application/json'

        url = '/endpoint_gateways'
        request = self.prepare_request(
            method='POST',
            url=url,
            headers=headers,
            params=params,
            data=data,
        )

        response = self.send(request, **kwargs)
        return response

    def list_endpoint_gateway_ips(
        self,
        endpoint_gateway_id: str,
        *,
        start: str = None,
        limit: int = None,
        sort: str = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        List all reserved IPs bound to an endpoint gateway.

        This request lists all reserved IPs bound to an endpoint gateway.

        :param str endpoint_gateway_id: The endpoint gateway identifier.
        :param str start: (optional) A server-provided token determining what
               resource to start the page on.
        :param int limit: (optional) The number of resources to return on a page.
        :param str sort: (optional) Sorts the returned collection by the specified
               property name in ascending order. A `-` may be prepended to the name to
               sort in descending order. For example, the value `-created_at` sorts the
               collection by the `created_at` property in descending order, and the value
               `name` sorts it by the `name` property in ascending order.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `ReservedIPCollectionEndpointGatewayContext` object
        """

        if not endpoint_gateway_id:
            raise ValueError('endpoint_gateway_id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='list_endpoint_gateway_ips',
        )
        headers.update(sdk_headers)

        params = {
            'version': self.version,
            'generation': self.generation,
            'start': start,
            'limit': limit,
            'sort': sort,
        }

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
            del kwargs['headers']
        headers['Accept'] = 'application/json'

        path_param_keys = ['endpoint_gateway_id']
        path_param_values = self.encode_path_vars(endpoint_gateway_id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/endpoint_gateways/{endpoint_gateway_id}/ips'.format(**path_param_dict)
        request = self.prepare_request(
            method='GET',
            url=url,
            headers=headers,
            params=params,
        )

        response = self.send(request, **kwargs)
        return response

    def remove_endpoint_gateway_ip(
        self,
        endpoint_gateway_id: str,
        id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Unbind a reserved IP from an endpoint gateway.

        This request unbinds the specified reserved IP from the specified endpoint
        gateway. If the reserved IP has `auto_delete` set to `true`, the reserved IP will
        be deleted.

        :param str endpoint_gateway_id: The endpoint gateway identifier.
        :param str id: The reserved IP identifier.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse
        """

        if not endpoint_gateway_id:
            raise ValueError('endpoint_gateway_id must be provided')
        if not id:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='remove_endpoint_gateway_ip',
        )
        headers.update(sdk_headers)

        params = {
            'version': self.version,
            'generation': self.generation,
        }

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
            del kwargs['headers']

        path_param_keys = ['endpoint_gateway_id', 'id']
        path_param_values = self.encode_path_vars(endpoint_gateway_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/endpoint_gateways/{endpoint_gateway_id}/ips/{id}'.format(**path_param_dict)
        request = self.prepare_request(
            method='DELETE',
            url=url,
            headers=headers,
            params=params,
        )

        response = self.send(request, **kwargs)
        return response

    def get_endpoint_gateway_ip(
        self,
        endpoint_gateway_id: str,
        id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Retrieve a reserved IP bound to an endpoint gateway.

        This request retrieves the specified reserved IP address if it is bound to the
        endpoint gateway specified in the URL.

        :param str endpoint_gateway_id: The endpoint gateway identifier.
        :param str id: The reserved IP identifier.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `ReservedIP` object
        """

        if not endpoint_gateway_id:
            raise ValueError('endpoint_gateway_id must be provided')
        if not id:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='get_endpoint_gateway_ip',
        )
        headers.update(sdk_headers)

        params = {
            'version': self.version,
            'generation': self.generation,
        }

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
            del kwargs['headers']
        headers['Accept'] = 'application/json'

        path_param_keys = ['endpoint_gateway_id', 'id']
        path_param_values = self.encode_path_vars(endpoint_gateway_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/endpoint_gateways/{endpoint_gateway_id}/ips/{id}'.format(**path_param_dict)
        request = self.prepare_request(
            method='GET',
            url=url,
            headers=headers,
            params=params,
        )

        response = self.send(request, **kwargs)
        return response

    def add_endpoint_gateway_ip(
        self,
        endpoint_gateway_id: str,
        id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Bind a reserved IP to an endpoint gateway.

        This request binds the specified reserved IP to the specified endpoint gateway.
        The reserved IP:
        - must currently be unbound
        - must not be in the same zone as any other reserved IP bound to the endpoint
        gateway.

        :param str endpoint_gateway_id: The endpoint gateway identifier.
        :param str id: The reserved IP identifier.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `ReservedIP` object
        """

        if not endpoint_gateway_id:
            raise ValueError('endpoint_gateway_id must be provided')
        if not id:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='add_endpoint_gateway_ip',
        )
        headers.update(sdk_headers)

        params = {
            'version': self.version,
            'generation': self.generation,
        }

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
            del kwargs['headers']
        headers['Accept'] = 'application/json'

        path_param_keys = ['endpoint_gateway_id', 'id']
        path_param_values = self.encode_path_vars(endpoint_gateway_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/endpoint_gateways/{endpoint_gateway_id}/ips/{id}'.format(**path_param_dict)
        request = self.prepare_request(
            method='PUT',
            url=url,
            headers=headers,
            params=params,
        )

        response = self.send(request, **kwargs)
        return response

    def delete_endpoint_gateway(
        self,
        id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Delete an endpoint gateway.

        This request deletes an endpoint gateway. This operation cannot be reversed.
        Reserved IPs that were bound to the endpoint gateway will be released if their
        `auto_delete` property is set to true.

        :param str id: The endpoint gateway identifier.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse
        """

        if not id:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='delete_endpoint_gateway',
        )
        headers.update(sdk_headers)

        params = {
            'version': self.version,
            'generation': self.generation,
        }

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
            del kwargs['headers']

        path_param_keys = ['id']
        path_param_values = self.encode_path_vars(id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/endpoint_gateways/{id}'.format(**path_param_dict)
        request = self.prepare_request(
            method='DELETE',
            url=url,
            headers=headers,
            params=params,
        )

        response = self.send(request, **kwargs)
        return response

    def get_endpoint_gateway(
        self,
        id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Retrieve an endpoint gateway.

        This request retrieves a single endpoint gateway specified by the identifier in
        the URL.

        :param str id: The endpoint gateway identifier.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `EndpointGateway` object
        """

        if not id:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='get_endpoint_gateway',
        )
        headers.update(sdk_headers)

        params = {
            'version': self.version,
            'generation': self.generation,
        }

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
            del kwargs['headers']
        headers['Accept'] = 'application/json'

        path_param_keys = ['id']
        path_param_values = self.encode_path_vars(id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/endpoint_gateways/{id}'.format(**path_param_dict)
        request = self.prepare_request(
            method='GET',
            url=url,
            headers=headers,
            params=params,
        )

        response = self.send(request, **kwargs)
        return response

    def update_endpoint_gateway(
        self,
        id: str,
        endpoint_gateway_patch: 'EndpointGatewayPatch',
        **kwargs,
    ) -> DetailedResponse:
        """
        Update an endpoint gateway.

        This request updates an endpoint gateway's name.

        :param str id: The endpoint gateway identifier.
        :param EndpointGatewayPatch endpoint_gateway_patch: The endpoint gateway
               patch.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `EndpointGateway` object
        """

        if not id:
            raise ValueError('id must be provided')
        if endpoint_gateway_patch is None:
            raise ValueError('endpoint_gateway_patch must be provided')
        if isinstance(endpoint_gateway_patch, EndpointGatewayPatch):
            endpoint_gateway_patch = convert_model(endpoint_gateway_patch)
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='update_endpoint_gateway',
        )
        headers.update(sdk_headers)

        params = {
            'version': self.version,
            'generation': self.generation,
        }

        data = json.dumps(endpoint_gateway_patch)
        headers['content-type'] = 'application/merge-patch+json'

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
            del kwargs['headers']
        headers['Accept'] = 'application/json'

        path_param_keys = ['id']
        path_param_values = self.encode_path_vars(id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/endpoint_gateways/{id}'.format(**path_param_dict)
        request = self.prepare_request(
            method='PATCH',
            url=url,
            headers=headers,
            params=params,
            data=data,
        )

        response = self.send(request, **kwargs)
        return response

    #########################
    # Flow log collectors
    #########################

    def list_flow_log_collectors(
        self,
        *,
        start: str = None,
        limit: int = None,
        resource_group_id: str = None,
        name: str = None,
        vpc_id: str = None,
        vpc_crn: str = None,
        vpc_name: str = None,
        target_id: str = None,
        target_resource_type: str = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        List all flow log collectors.

        This request lists all flow log collectors in the region. A flow log collector
        summarizes data sent over the instance network interfaces contained within its
        target.

        :param str start: (optional) A server-provided 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 with a `resource_group.id` property matching the specified
               identifier.
        :param str name: (optional) Filters the collection to resources with a
               `name` property matching the exact specified name.
        :param str vpc_id: (optional) Filters the collection to resources with a
               `vpc.id` property matching the specified identifier.
        :param str vpc_crn: (optional) Filters the collection to resources with a
               `vpc.crn` property matching the specified CRN.
        :param str vpc_name: (optional) Filters the collection to resources with a
               `vpc.name` property matching the exact specified name.
        :param str target_id: (optional) Filters the collection to resources with a
               `target.id` property matching the specified identifier.
        :param str target_resource_type: (optional) Filters the collection to
               resources with a `target.resource_type` property matching the specified
               value.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `FlowLogCollectorCollection` object
        """

        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='list_flow_log_collectors',
        )
        headers.update(sdk_headers)

        params = {
            'version': self.version,
            'generation': self.generation,
            'start': start,
            'limit': limit,
            'resource_group.id': resource_group_id,
            'name': name,
            'vpc.id': vpc_id,
            'vpc.crn': vpc_crn,
            'vpc.name': vpc_name,
            'target.id': target_id,
            'target.resource_type': target_resource_type,
        }

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
            del kwargs['headers']
        headers['Accept'] = 'application/json'

        url = '/flow_log_collectors'
        request = self.prepare_request(
            method='GET',
            url=url,
            headers=headers,
            params=params,
        )

        response = self.send(request, **kwargs)
        return response

    def create_flow_log_collector(
        self,
        storage_bucket: 'LegacyCloudObjectStorageBucketIdentity',
        target: 'FlowLogCollectorTargetPrototype',
        *,
        active: bool = None,
        name: str = None,
        resource_group: 'ResourceGroupIdentity' = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        Create a flow log collector.

        This request creates and starts a new flow log collector from a flow log collector
        prototype object. The prototype object is structured in the same way as a
        retrieved flow log collector, and contains the information necessary to create and
        start the new flow log collector.

        :param LegacyCloudObjectStorageBucketIdentity storage_bucket: The Cloud
               Object Storage bucket where the collected flows will be logged.
               The bucket must exist and an IAM service authorization must grant
               `IBM Cloud Flow Logs` resources of `VPC Infrastructure Services` writer
               access to the bucket. For more information, see [Creating a flow log
               collector](https://cloud.ibm.com/docs/vpc?topic=vpc-ordering-flow-log-collector).
        :param FlowLogCollectorTargetPrototype target: The target this collector
               will collect flow logs for. If the target is an instance,
               subnet, or VPC, flow logs will not be collected for any instance network
               interfaces within
               the target that are themselves the target of a more specific flow log
               collector.
        :param bool active: (optional) Indicates whether this collector will be
               active upon creation.
        :param str name: (optional) The name for this flow log collector. The name
               must not be used by another flow log collector in the 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) will be
               used.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `FlowLogCollector` object
        """

        if storage_bucket is None:
            raise ValueError('storage_bucket must be provided')
        if target is None:
            raise ValueError('target must be provided')
        storage_bucket = convert_model(storage_bucket)
        target = convert_model(target)
        if resource_group is not None:
            resource_group = convert_model(resource_group)
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='create_flow_log_collector',
        )
        headers.update(sdk_headers)

        params = {
            'version': self.version,
            'generation': self.generation,
        }

        data = {
            'storage_bucket': storage_bucket,
            'target': target,
            'active': active,
            'name': name,
            'resource_group': resource_group,
        }
        data = {k: v for (k, v) in data.items() if v is not None}
        data = json.dumps(data)
        headers['content-type'] = 'application/json'

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
            del kwargs['headers']
        headers['Accept'] = 'application/json'

        url = '/flow_log_collectors'
        request = self.prepare_request(
            method='POST',
            url=url,
            headers=headers,
            params=params,
            data=data,
        )

        response = self.send(request, **kwargs)
        return response

    def delete_flow_log_collector(
        self,
        id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Delete a flow log collector.

        This request stops and deletes a flow log collector. This operation cannot be
        reversed.
        Collected flow logs remain available within the flow log collector's Cloud Object
        Storage bucket.

        :param str id: The flow log collector identifier.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse
        """

        if not id:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='delete_flow_log_collector',
        )
        headers.update(sdk_headers)

        params = {
            'version': self.version,
            'generation': self.generation,
        }

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
            del kwargs['headers']

        path_param_keys = ['id']
        path_param_values = self.encode_path_vars(id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/flow_log_collectors/{id}'.format(**path_param_dict)
        request = self.prepare_request(
            method='DELETE',
            url=url,
            headers=headers,
            params=params,
        )

        response = self.send(request, **kwargs)
        return response

    def get_flow_log_collector(
        self,
        id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Retrieve a flow log collector.

        This request retrieves a single flow log collector specified by the identifier in
        the URL.

        :param str id: The flow log collector identifier.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `FlowLogCollector` object
        """

        if not id:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='get_flow_log_collector',
        )
        headers.update(sdk_headers)

        params = {
            'version': self.version,
            'generation': self.generation,
        }

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
            del kwargs['headers']
        headers['Accept'] = 'application/json'

        path_param_keys = ['id']
        path_param_values = self.encode_path_vars(id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/flow_log_collectors/{id}'.format(**path_param_dict)
        request = self.prepare_request(
            method='GET',
            url=url,
            headers=headers,
            params=params,
        )

        response = self.send(request, **kwargs)
        return response

    def update_flow_log_collector(
        self,
        id: str,
        flow_log_collector_patch: 'FlowLogCollectorPatch',
        **kwargs,
    ) -> DetailedResponse:
        """
        Update a flow log collector.

        This request updates a flow log collector with the information in a provided flow
        log collector patch. The flow log collector patch object is structured in the same
        way as a retrieved flow log collector and contains only the information to be
        updated.

        :param str id: The flow log collector identifier.
        :param FlowLogCollectorPatch flow_log_collector_patch: The flow log
               collector patch.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `FlowLogCollector` object
        """

        if not id:
            raise ValueError('id must be provided')
        if flow_log_collector_patch is None:
            raise ValueError('flow_log_collector_patch must be provided')
        if isinstance(flow_log_collector_patch, FlowLogCollectorPatch):
            flow_log_collector_patch = convert_model(flow_log_collector_patch)
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='update_flow_log_collector',
        )
        headers.update(sdk_headers)

        params = {
            'version': self.version,
            'generation': self.generation,
        }

        data = json.dumps(flow_log_collector_patch)
        headers['content-type'] = 'application/merge-patch+json'

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
            del kwargs['headers']
        headers['Accept'] = 'application/json'

        path_param_keys = ['id']
        path_param_values = self.encode_path_vars(id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/flow_log_collectors/{id}'.format(**path_param_dict)
        request = self.prepare_request(
            method='PATCH',
            url=url,
            headers=headers,
            params=params,
            data=data,
        )

        response = self.send(request, **kwargs)
        return response


class ListVpcDnsResolutionBindingsEnums:
    """
    Enums for list_vpc_dns_resolution_bindings parameters.
    """

    class Sort(str, Enum):
        """
        Sorts the returned collection by the specified property name in ascending order. A
        `-` may be prepended to the name to sort in descending order. For example, the
        value `-created_at` sorts the collection by the `created_at` property in
        descending order, and the value `name` sorts it by the `name` property in
        ascending order.
        """

        CREATED_AT = 'created_at'
        NAME = 'name'


class ListSubnetReservedIpsEnums:
    """
    Enums for list_subnet_reserved_ips parameters.
    """

    class Sort(str, Enum):
        """
        Sorts the returned collection by the specified property name in ascending order. A
        `-` may be prepended to the name to sort in descending order. For example, the
        value `-created_at` sorts the collection by the `created_at` property in
        descending order, and the value `name` sorts it by the `name` property in
        ascending order.
        """

        ADDRESS = 'address'
        CREATED_AT = 'created_at'
        NAME = 'name'


class ListImagesEnums:
    """
    Enums for list_images parameters.
    """

    class Status(str, Enum):
        """
        Filters the collection to images with a `status` property matching one of the
        specified comma-separated values.
        """

        AVAILABLE = 'available'
        DELETING = 'deleting'
        DEPRECATED = 'deprecated'
        FAILED = 'failed'
        OBSOLETE = 'obsolete'
        PENDING = 'pending'
        UNUSABLE = 'unusable'
    class Visibility(str, Enum):
        """
        Filters the collection to images with a `visibility` property matching the
        specified value.
        """

        PRIVATE = 'private'
        PUBLIC = 'public'


class ListBackupPolicyJobsEnums:
    """
    Enums for list_backup_policy_jobs parameters.
    """

    class Status(str, Enum):
        """
        Filters the collection to backup policy jobs with a `status` property matching the
        specified value.
        """

        FAILED = 'failed'
        RUNNING = 'running'
        SUCCEEDED = 'succeeded'
    class Sort(str, Enum):
        """
        Sorts the returned collection by the specified property name in ascending order. A
        `-` may be prepended to the name to sort in descending order. For example, the
        value `-created_at` sorts the collection by the `created_at` property in
        descending order, and the value `name` sorts it by the `name` property in
        ascending order.
        """

        CREATED_AT = 'created_at'
        NAME = 'name'


class ListVolumesEnums:
    """
    Enums for list_volumes parameters.
    """

    class AttachmentState(str, Enum):
        """
        Filters the collection to volumes with an `attachment_state` property matching the
        specified value.
        """

        ATTACHED = 'attached'
        UNATTACHED = 'unattached'
        UNUSABLE = 'unusable'
    class Encryption(str, Enum):
        """
        Filters the collection to resources with an `encryption` property matching the
        specified value.
        """

        PROVIDER_MANAGED = 'provider_managed'
        USER_MANAGED = 'user_managed'


class ListSnapshotsEnums:
    """
    Enums for list_snapshots parameters.
    """

    class Sort(str, Enum):
        """
        Sorts the returned collection by the specified property name in ascending order. A
        `-` may be prepended to the name to sort in descending order. For example, the
        value `-created_at` sorts the collection by the `created_at` property in
        descending order, and the value `name` sorts it by the `name` property in
        ascending order.
        """

        CREATED_AT = 'created_at'
        NAME = 'name'


class ListShareProfilesEnums:
    """
    Enums for list_share_profiles parameters.
    """

    class Sort(str, Enum):
        """
        Sorts the returned collection by the specified property name in ascending order. A
        `-` may be prepended to the name to sort in descending order. For example, the
        value `-created_at` sorts the collection by the `created_at` property in
        descending order, and the value `name` sorts it by the `name` property in
        ascending order.
        """

        CREATED_AT = 'created_at'
        NAME = 'name'


class ListSharesEnums:
    """
    Enums for list_shares parameters.
    """

    class Sort(str, Enum):
        """
        Sorts the returned collection by the specified property name in ascending order. A
        `-` may be prepended to the name to sort in descending order. For example, the
        value `-created_at` sorts the collection by the `created_at` property in
        descending order, and the value `name` sorts it by the `name` property in
        ascending order.
        """

        CREATED_AT = 'created_at'
        NAME = 'name'
    class ReplicationRole(str, Enum):
        """
        Filters the collection to file shares with a `replication_role` property matching
        the specified value.
        """

        NONE = 'none'
        REPLICA = 'replica'
        SOURCE = 'source'


class ListFloatingIpsEnums:
    """
    Enums for list_floating_ips parameters.
    """

    class Sort(str, Enum):
        """
        Sorts the returned collection by the specified property name in ascending order. A
        `-` may be prepended to the name to sort in descending order. For example, the
        value `-created_at` sorts the collection by the `created_at` property in
        descending order, and the value `name` sorts it by the `name` property in
        ascending order.
        """

        CREATED_AT = 'created_at'
        NAME = 'name'


class ListNetworkAclRulesEnums:
    """
    Enums for list_network_acl_rules parameters.
    """

    class Direction(str, Enum):
        """
        Filters the collection to rules with a `direction` property matching the specified
        value.
        """

        INBOUND = 'inbound'
        OUTBOUND = 'outbound'


class ListVpnGatewaysEnums:
    """
    Enums for list_vpn_gateways parameters.
    """

    class Sort(str, Enum):
        """
        Sorts the returned collection by the specified property name in ascending order. A
        `-` may be prepended to the name to sort in descending order. For example, the
        value `-created_at` sorts the collection by the `created_at` property in
        descending order, and the value `name` sorts it by the `name` property in
        ascending order.
        """

        CREATED_AT = 'created_at'
        NAME = 'name'
    class Mode(str, Enum):
        """
        Filters the collection to VPN gateways with a `mode` property matching the
        specified value.
        """

        POLICY = 'policy'
        ROUTE = 'route'


class ListVpnGatewayConnectionsEnums:
    """
    Enums for list_vpn_gateway_connections parameters.
    """

    class Status(str, Enum):
        """
        Filters the collection to VPN gateway connections with a `status` property
        matching the specified value.
        """

        DOWN = 'down'
        UP = 'up'


class ListVpnServersEnums:
    """
    Enums for list_vpn_servers parameters.
    """

    class Sort(str, Enum):
        """
        Sorts the returned collection by the specified property name in ascending order. A
        `-` may be prepended to the name to sort in descending order. For example, the
        value `-created_at` sorts the collection by the `created_at` property in
        descending order, and the value `name` sorts it by the `name` property in
        ascending order.
        """

        CREATED_AT = 'created_at'
        NAME = 'name'


class ListVpnServerClientsEnums:
    """
    Enums for list_vpn_server_clients parameters.
    """

    class Sort(str, Enum):
        """
        Sorts the returned collection by the specified property name in ascending order. A
        `-` may be prepended to the name to sort in descending order. For example, the
        value `-created_at` sorts the collection by the `created_at` property in
        descending order.
        """

        CREATED_AT = 'created_at'


class ListVpnServerRoutesEnums:
    """
    Enums for list_vpn_server_routes parameters.
    """

    class Sort(str, Enum):
        """
        Sorts the returned collection by the specified property name in ascending order. A
        `-` may be prepended to the name to sort in descending order. For example, the
        value `-created_at` sorts the collection by the `created_at` property in
        descending order, and the value `name` sorts it by the `name` property in
        ascending order.
        """

        CREATED_AT = 'created_at'
        NAME = 'name'


class ListEndpointGatewayIpsEnums:
    """
    Enums for list_endpoint_gateway_ips parameters.
    """

    class Sort(str, Enum):
        """
        Sorts the returned collection by the specified property name in ascending order. A
        `-` may be prepended to the name to sort in descending order. For example, the
        value `-created_at` sorts the collection by the `created_at` property in
        descending order, and the value `name` sorts it by the `name` property in
        ascending order.
        """

        ADDRESS = 'address'
        CREATED_AT = 'created_at'
        NAME = 'name'


##############################################################################
# Models
##############################################################################


class AccountReference:
    """
    AccountReference.

    :attr str id: The unique identifier for this account.
    :attr str resource_type: The resource type.
    """

    def __init__(
        self,
        id: str,
        resource_type: str,
    ) -> None:
        """
        Initialize a AccountReference object.

        :param str id: The unique identifier for this account.
        :param str resource_type: The resource type.
        """
        self.id = id
        self.resource_type = resource_type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'AccountReference':
        """Initialize a AccountReference object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in AccountReference JSON')
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError('Required property \'resource_type\' not present in AccountReference JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a AccountReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, '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 AccountReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'AccountReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'AccountReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        ACCOUNT = 'account'



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 changed.
    :attr str name: The name for this address prefix. The name must not be used by
          another address prefix for the VPC.
    :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 changed.
        :param str name: The name for this address prefix. The name must not be
               used by another address prefix for the VPC.
        :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:
            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 AddressPrefix object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'AddressPrefix') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'AddressPrefix') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class AddressPrefixCollection:
    """
    AddressPrefixCollection.

    :attr List[AddressPrefix] address_prefixes: Collection of address prefixes.
    :attr AddressPrefixCollectionFirst first: A link to the first page of resources.
    :attr int limit: The maximum number of resources that can be returned by the
          request.
    :attr AddressPrefixCollectionNext next: (optional) A link to the next page of
          resources. This property is present for all pages
          except the last page.
    :attr int total_count: The total number of resources across all pages.
    """

    def __init__(
        self,
        address_prefixes: List['AddressPrefix'],
        first: 'AddressPrefixCollectionFirst',
        limit: int,
        total_count: int,
        *,
        next: 'AddressPrefixCollectionNext' = None,
    ) -> None:
        """
        Initialize a AddressPrefixCollection object.

        :param List[AddressPrefix] address_prefixes: Collection of address
               prefixes.
        :param AddressPrefixCollectionFirst first: A link to the first page of
               resources.
        :param int limit: The maximum number of resources that can be returned by
               the request.
        :param int total_count: The total number of resources across all pages.
        :param AddressPrefixCollectionNext next: (optional) A link to the next page
               of resources. This property is present for all pages
               except the last page.
        """
        self.address_prefixes = address_prefixes
        self.first = first
        self.limit = limit
        self.next = next
        self.total_count = total_count

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'AddressPrefixCollection':
        """Initialize a AddressPrefixCollection object from a json dictionary."""
        args = {}
        if 'address_prefixes' in _dict:
            args['address_prefixes'] = [AddressPrefix.from_dict(v) for v in _dict.get('address_prefixes')]
        else:
            raise ValueError('Required property \'address_prefixes\' not present in AddressPrefixCollection JSON')
        if 'first' in _dict:
            args['first'] = AddressPrefixCollectionFirst.from_dict(_dict.get('first'))
        else:
            raise ValueError('Required property \'first\' not present in AddressPrefixCollection JSON')
        if 'limit' in _dict:
            args['limit'] = _dict.get('limit')
        else:
            raise ValueError('Required property \'limit\' not present in AddressPrefixCollection JSON')
        if 'next' in _dict:
            args['next'] = AddressPrefixCollectionNext.from_dict(_dict.get('next'))
        if 'total_count' in _dict:
            args['total_count'] = _dict.get('total_count')
        else:
            raise ValueError('Required property \'total_count\' not present in AddressPrefixCollection JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a AddressPrefixCollection object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'address_prefixes') and self.address_prefixes is not None:
            address_prefixes_list = []
            for v in self.address_prefixes:
                if isinstance(v, dict):
                    address_prefixes_list.append(v)
                else:
                    address_prefixes_list.append(v.to_dict())
            _dict['address_prefixes'] = address_prefixes_list
        if hasattr(self, 'first') and self.first is not None:
            if isinstance(self.first, dict):
                _dict['first'] = self.first
            else:
                _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:
            if isinstance(self.next, dict):
                _dict['next'] = self.next
            else:
                _dict['next'] = self.next.to_dict()
        if hasattr(self, 'total_count') and self.total_count is not None:
            _dict['total_count'] = self.total_count
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this AddressPrefixCollection object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'AddressPrefixCollection') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'AddressPrefixCollection') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class AddressPrefixCollectionFirst:
    """
    A link to the first page of resources.

    :attr str href: The URL for a page of resources.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a AddressPrefixCollectionFirst object.

        :param str href: The URL for a page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'AddressPrefixCollectionFirst':
        """Initialize a AddressPrefixCollectionFirst object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in AddressPrefixCollectionFirst JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a AddressPrefixCollectionFirst object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this AddressPrefixCollectionFirst object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'AddressPrefixCollectionFirst') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'AddressPrefixCollectionFirst') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class AddressPrefixCollectionNext:
    """
    A link to the next page of resources. This property is present for all pages except
    the last page.

    :attr str href: The URL for a page of resources.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a AddressPrefixCollectionNext object.

        :param str href: The URL for a page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'AddressPrefixCollectionNext':
        """Initialize a AddressPrefixCollectionNext object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in AddressPrefixCollectionNext JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a AddressPrefixCollectionNext object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this AddressPrefixCollectionNext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'AddressPrefixCollectionNext') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'AddressPrefixCollectionNext') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class AddressPrefixPatch:
    """
    AddressPrefixPatch.

    :attr bool is_default: (optional) Indicates whether this is the default prefix
          for this zone in this VPC. Updating to true makes this prefix the default prefix
          for this zone in this VPC, provided the VPC currently has no default address
          prefix for this zone. Updating to false removes the default prefix for this zone
          in this VPC.
    :attr str name: (optional) The name for this address prefix. The name must not
          be used by another address prefix for the VPC.
    """

    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 name for this address prefix. The name must
               not be used by another address prefix for the VPC.
        """
        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 BackupPolicy:
    """
    BackupPolicy.

    :attr datetime created_at: The date and time that the backup policy was created.
    :attr str crn: The CRN for this backup policy.
    :attr List[BackupPolicyHealthReason] health_reasons: The reasons for the current
          `health_state` (if any).
          The enumerated reason code values for this property will expand in the future.
          When processing this property, check for and log unknown values. Optionally halt
          processing and surface the error, or bypass the resource on which the unexpected
          reason code was encountered.
    :attr str health_state: The health of this resource.
          - `ok`: No abnormal behavior detected
          - `degraded`: Experiencing compromised performance, capacity, or connectivity
          - `faulted`: Completely unreachable, inoperative, or otherwise entirely
          incapacitated
          - `inapplicable`: The health state does not apply because of the current
          lifecycle state. A resource with a lifecycle state of `failed` or `deleting`
          will have a health state of `inapplicable`. A `pending` resource may also have
          this state.
    :attr str href: The URL for this backup policy.
    :attr str id: The unique identifier for this backup policy.
    :attr datetime last_job_completed_at: (optional) The date and time that the most
          recent job for this backup policy completed.
          If absent, no job has yet completed for this backup policy.
    :attr str lifecycle_state: The lifecycle state of the backup policy.
    :attr List[str] match_resource_types: The resource types this backup policy
          applies to. Resources that have both a matching type and a matching user tag
          will be subject to the backup policy.
          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 backup policy on which the
          unexpected property value was encountered.
    :attr List[str] match_user_tags: The user tags this backup policy applies to.
          Resources that have both a matching user tag and a matching type will be subject
          to the backup policy.
    :attr str name: The name for this backup policy. The name is unique across all
          backup policies in the region.
    :attr List[BackupPolicyPlanReference] plans: The plans for the backup policy.
    :attr ResourceGroupReference resource_group: The resource group for this backup
          policy.
    :attr str resource_type: The resource type.
    :attr BackupPolicyScope scope: The scope for this backup policy.
    """

    def __init__(
        self,
        created_at: datetime,
        crn: str,
        health_reasons: List['BackupPolicyHealthReason'],
        health_state: str,
        href: str,
        id: str,
        lifecycle_state: str,
        match_resource_types: List[str],
        match_user_tags: List[str],
        name: str,
        plans: List['BackupPolicyPlanReference'],
        resource_group: 'ResourceGroupReference',
        resource_type: str,
        scope: 'BackupPolicyScope',
        *,
        last_job_completed_at: datetime = None,
    ) -> None:
        """
        Initialize a BackupPolicy object.

        :param datetime created_at: The date and time that the backup policy was
               created.
        :param str crn: The CRN for this backup policy.
        :param List[BackupPolicyHealthReason] health_reasons: The reasons for the
               current `health_state` (if any).
               The enumerated reason code values for this property will expand in the
               future. When processing this property, check for and log unknown values.
               Optionally halt processing and surface the error, or bypass the resource on
               which the unexpected reason code was encountered.
        :param str health_state: The health of this resource.
               - `ok`: No abnormal behavior detected
               - `degraded`: Experiencing compromised performance, capacity, or
               connectivity
               - `faulted`: Completely unreachable, inoperative, or otherwise entirely
               incapacitated
               - `inapplicable`: The health state does not apply because of the current
               lifecycle state. A resource with a lifecycle state of `failed` or
               `deleting` will have a health state of `inapplicable`. A `pending` resource
               may also have this state.
        :param str href: The URL for this backup policy.
        :param str id: The unique identifier for this backup policy.
        :param str lifecycle_state: The lifecycle state of the backup policy.
        :param List[str] match_resource_types: The resource types this backup
               policy applies to. Resources that have both a matching type and a matching
               user tag will be subject to the backup policy.
               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 backup policy on which the
               unexpected property value was encountered.
        :param List[str] match_user_tags: The user tags this backup policy applies
               to. Resources that have both a matching user tag and a matching type will
               be subject to the backup policy.
        :param str name: The name for this backup policy. The name is unique across
               all backup policies in the region.
        :param List[BackupPolicyPlanReference] plans: The plans for the backup
               policy.
        :param ResourceGroupReference resource_group: The resource group for this
               backup policy.
        :param str resource_type: The resource type.
        :param BackupPolicyScope scope: The scope for this backup policy.
        :param datetime last_job_completed_at: (optional) The date and time that
               the most recent job for this backup policy completed.
               If absent, no job has yet completed for this backup policy.
        """
        self.created_at = created_at
        self.crn = crn
        self.health_reasons = health_reasons
        self.health_state = health_state
        self.href = href
        self.id = id
        self.last_job_completed_at = last_job_completed_at
        self.lifecycle_state = lifecycle_state
        self.match_resource_types = match_resource_types
        self.match_user_tags = match_user_tags
        self.name = name
        self.plans = plans
        self.resource_group = resource_group
        self.resource_type = resource_type
        self.scope = scope

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'BackupPolicy':
        """Initialize a BackupPolicy 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 BackupPolicy JSON')
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError('Required property \'crn\' not present in BackupPolicy JSON')
        if 'health_reasons' in _dict:
            args['health_reasons'] = [BackupPolicyHealthReason.from_dict(v) for v in _dict.get('health_reasons')]
        else:
            raise ValueError('Required property \'health_reasons\' not present in BackupPolicy JSON')
        if 'health_state' in _dict:
            args['health_state'] = _dict.get('health_state')
        else:
            raise ValueError('Required property \'health_state\' not present in BackupPolicy JSON')
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in BackupPolicy JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in BackupPolicy JSON')
        if 'last_job_completed_at' in _dict:
            args['last_job_completed_at'] = string_to_datetime(_dict.get('last_job_completed_at'))
        if 'lifecycle_state' in _dict:
            args['lifecycle_state'] = _dict.get('lifecycle_state')
        else:
            raise ValueError('Required property \'lifecycle_state\' not present in BackupPolicy JSON')
        if 'match_resource_types' in _dict:
            args['match_resource_types'] = _dict.get('match_resource_types')
        else:
            raise ValueError('Required property \'match_resource_types\' not present in BackupPolicy JSON')
        if 'match_user_tags' in _dict:
            args['match_user_tags'] = _dict.get('match_user_tags')
        else:
            raise ValueError('Required property \'match_user_tags\' not present in BackupPolicy JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in BackupPolicy JSON')
        if 'plans' in _dict:
            args['plans'] = [BackupPolicyPlanReference.from_dict(v) for v in _dict.get('plans')]
        else:
            raise ValueError('Required property \'plans\' not present in BackupPolicy 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 BackupPolicy JSON')
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError('Required property \'resource_type\' not present in BackupPolicy JSON')
        if 'scope' in _dict:
            args['scope'] = _dict.get('scope')
        else:
            raise ValueError('Required property \'scope\' not present in BackupPolicy JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a BackupPolicy object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'created_at') and self.created_at is not None:
            _dict['created_at'] = datetime_to_string(self.created_at)
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'health_reasons') and self.health_reasons is not None:
            health_reasons_list = []
            for v in self.health_reasons:
                if isinstance(v, dict):
                    health_reasons_list.append(v)
                else:
                    health_reasons_list.append(v.to_dict())
            _dict['health_reasons'] = health_reasons_list
        if hasattr(self, 'health_state') and self.health_state is not None:
            _dict['health_state'] = self.health_state
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'last_job_completed_at') and self.last_job_completed_at is not None:
            _dict['last_job_completed_at'] = datetime_to_string(self.last_job_completed_at)
        if hasattr(self, 'lifecycle_state') and self.lifecycle_state is not None:
            _dict['lifecycle_state'] = self.lifecycle_state
        if hasattr(self, 'match_resource_types') and self.match_resource_types is not None:
            _dict['match_resource_types'] = self.match_resource_types
        if hasattr(self, 'match_user_tags') and self.match_user_tags is not None:
            _dict['match_user_tags'] = self.match_user_tags
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'plans') and self.plans is not None:
            plans_list = []
            for v in self.plans:
                if isinstance(v, dict):
                    plans_list.append(v)
                else:
                    plans_list.append(v.to_dict())
            _dict['plans'] = plans_list
        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, 'resource_type') and self.resource_type is not None:
            _dict['resource_type'] = self.resource_type
        if hasattr(self, 'scope') and self.scope is not None:
            if isinstance(self.scope, dict):
                _dict['scope'] = self.scope
            else:
                _dict['scope'] = self.scope.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 BackupPolicy object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'BackupPolicy') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'BackupPolicy') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class HealthStateEnum(str, Enum):
        """
        The health of this resource.
        - `ok`: No abnormal behavior detected
        - `degraded`: Experiencing compromised performance, capacity, or connectivity
        - `faulted`: Completely unreachable, inoperative, or otherwise entirely
        incapacitated
        - `inapplicable`: The health state does not apply because of the current lifecycle
        state. A resource with a lifecycle state of `failed` or `deleting` will have a
        health state of `inapplicable`. A `pending` resource may also have this state.
        """

        DEGRADED = 'degraded'
        FAULTED = 'faulted'
        INAPPLICABLE = 'inapplicable'
        OK = 'ok'


    class LifecycleStateEnum(str, Enum):
        """
        The lifecycle state of the backup policy.
        """

        DELETING = 'deleting'
        FAILED = 'failed'
        PENDING = 'pending'
        STABLE = 'stable'
        SUSPENDED = 'suspended'
        UPDATING = 'updating'
        WAITING = 'waiting'


    class MatchResourceTypesEnum(str, Enum):
        """
        The resource type.
        """

        VOLUME = 'volume'


    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        BACKUP_POLICY = 'backup_policy'



class BackupPolicyCollection:
    """
    BackupPolicyCollection.

    :attr List[BackupPolicy] backup_policies: Collection of backup policies.
    :attr BackupPolicyCollectionFirst 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 BackupPolicyCollectionNext 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,
        backup_policies: List['BackupPolicy'],
        first: 'BackupPolicyCollectionFirst',
        limit: int,
        total_count: int,
        *,
        next: 'BackupPolicyCollectionNext' = None,
    ) -> None:
        """
        Initialize a BackupPolicyCollection object.

        :param List[BackupPolicy] backup_policies: Collection of backup policies.
        :param BackupPolicyCollectionFirst 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 BackupPolicyCollectionNext next: (optional) A link to the next page
               of resources. This property is present for all pages
               except the last page.
        """
        self.backup_policies = backup_policies
        self.first = first
        self.limit = limit
        self.next = next
        self.total_count = total_count

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'BackupPolicyCollection':
        """Initialize a BackupPolicyCollection object from a json dictionary."""
        args = {}
        if 'backup_policies' in _dict:
            args['backup_policies'] = [BackupPolicy.from_dict(v) for v in _dict.get('backup_policies')]
        else:
            raise ValueError('Required property \'backup_policies\' not present in BackupPolicyCollection JSON')
        if 'first' in _dict:
            args['first'] = BackupPolicyCollectionFirst.from_dict(_dict.get('first'))
        else:
            raise ValueError('Required property \'first\' not present in BackupPolicyCollection JSON')
        if 'limit' in _dict:
            args['limit'] = _dict.get('limit')
        else:
            raise ValueError('Required property \'limit\' not present in BackupPolicyCollection JSON')
        if 'next' in _dict:
            args['next'] = BackupPolicyCollectionNext.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 BackupPolicyCollection JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a BackupPolicyCollection object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'backup_policies') and self.backup_policies is not None:
            backup_policies_list = []
            for v in self.backup_policies:
                if isinstance(v, dict):
                    backup_policies_list.append(v)
                else:
                    backup_policies_list.append(v.to_dict())
            _dict['backup_policies'] = backup_policies_list
        if hasattr(self, 'first') and self.first is not None:
            if isinstance(self.first, dict):
                _dict['first'] = self.first
            else:
                _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:
            if isinstance(self.next, dict):
                _dict['next'] = self.next
            else:
                _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 BackupPolicyCollection object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'BackupPolicyCollection') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'BackupPolicyCollection') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class BackupPolicyCollectionFirst:
    """
    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 BackupPolicyCollectionFirst object.

        :param str href: The URL for a page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'BackupPolicyCollectionFirst':
        """Initialize a BackupPolicyCollectionFirst object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in BackupPolicyCollectionFirst JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a BackupPolicyCollectionFirst object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(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 BackupPolicyCollectionFirst object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'BackupPolicyCollectionFirst') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'BackupPolicyCollectionFirst') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class BackupPolicyCollectionNext:
    """
    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 BackupPolicyCollectionNext object.

        :param str href: The URL for a page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'BackupPolicyCollectionNext':
        """Initialize a BackupPolicyCollectionNext object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in BackupPolicyCollectionNext JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a BackupPolicyCollectionNext object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(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 BackupPolicyCollectionNext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'BackupPolicyCollectionNext') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'BackupPolicyCollectionNext') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class BackupPolicyHealthReason:
    """
    BackupPolicyHealthReason.

    :attr str code: A snake case string succinctly identifying the reason for this
          health state.
    :attr str message: An explanation of the reason for this health state.
    :attr str more_info: (optional) Link to documentation about the reason for this
          health state.
    """

    def __init__(
        self,
        code: str,
        message: str,
        *,
        more_info: str = None,
    ) -> None:
        """
        Initialize a BackupPolicyHealthReason object.

        :param str code: A snake case string succinctly identifying the reason for
               this health state.
        :param str message: An explanation of the reason for this health state.
        :param str more_info: (optional) Link to documentation about the reason for
               this health state.
        """
        self.code = code
        self.message = message
        self.more_info = more_info

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'BackupPolicyHealthReason':
        """Initialize a BackupPolicyHealthReason object from a json dictionary."""
        args = {}
        if 'code' in _dict:
            args['code'] = _dict.get('code')
        else:
            raise ValueError('Required property \'code\' not present in BackupPolicyHealthReason JSON')
        if 'message' in _dict:
            args['message'] = _dict.get('message')
        else:
            raise ValueError('Required property \'message\' not present in BackupPolicyHealthReason JSON')
        if 'more_info' in _dict:
            args['more_info'] = _dict.get('more_info')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a BackupPolicyHealthReason object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'code') and self.code is not None:
            _dict['code'] = self.code
        if hasattr(self, 'message') and self.message is not None:
            _dict['message'] = self.message
        if hasattr(self, 'more_info') and self.more_info is not None:
            _dict['more_info'] = self.more_info
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this BackupPolicyHealthReason object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'BackupPolicyHealthReason') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'BackupPolicyHealthReason') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class CodeEnum(str, Enum):
        """
        A snake case string succinctly identifying the reason for this health state.
        """

        MISSING_SERVICE_AUTHORIZATION_POLICIES = 'missing_service_authorization_policies'



class BackupPolicyJob:
    """
    BackupPolicyJob.

    :attr bool auto_delete: Indicates whether this backup policy job will be
          automatically deleted after it completes. At present, this is always `true`, but
          may be modifiable in the future.
    :attr int auto_delete_after: If `auto_delete` is `true`, the days after
          completion that this backup policy job will be deleted. This value may be
          modifiable in the future.
    :attr BackupPolicyPlanReference backup_policy_plan: The backup policy plan
          operated this backup policy job (may be
          [deleted](https://cloud.ibm.com/apidocs/vpc#deleted-resources)).
    :attr datetime completed_at: (optional) The date and time that the backup policy
          job was completed.
          If absent, the backup policy job has not yet completed.
    :attr datetime created_at: The date and time that the backup policy job was
          created.
    :attr str href: The URL for this backup policy job.
    :attr str id: The unique identifier for this backup policy job.
    :attr str job_type: The type of backup policy job.
          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 backup policy job on which the
          unexpected property value was encountered.
    :attr str resource_type: The resource type.
    :attr BackupPolicyJobSource source: The source this backup was created from (may
          be
          [deleted](https://cloud.ibm.com/apidocs/vpc#deleted-resources)).
    :attr str status: The status of the backup policy job.
          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 backup policy job on which the
          unexpected property value was encountered.
    :attr List[BackupPolicyJobStatusReason] status_reasons: The reasons for the
          current status (if any).
          The enumerated reason code values for this property will expand in the future.
          When processing this property, check for and log unknown values. Optionally halt
          processing and surface the error, or bypass the resource on which the unexpected
          reason code was encountered.
    :attr List[SnapshotReference] target_snapshots: The snapshots operated on by
          this backup policy job (may be
          [deleted](https://cloud.ibm.com/apidocs/vpc#deleted-resources)).
    """

    def __init__(
        self,
        auto_delete: bool,
        auto_delete_after: int,
        backup_policy_plan: 'BackupPolicyPlanReference',
        created_at: datetime,
        href: str,
        id: str,
        job_type: str,
        resource_type: str,
        source: 'BackupPolicyJobSource',
        status: str,
        status_reasons: List['BackupPolicyJobStatusReason'],
        target_snapshots: List['SnapshotReference'],
        *,
        completed_at: datetime = None,
    ) -> None:
        """
        Initialize a BackupPolicyJob object.

        :param bool auto_delete: Indicates whether this backup policy job will be
               automatically deleted after it completes. At present, this is always
               `true`, but may be modifiable in the future.
        :param int auto_delete_after: If `auto_delete` is `true`, the days after
               completion that this backup policy job will be deleted. This value may be
               modifiable in the future.
        :param BackupPolicyPlanReference backup_policy_plan: The backup policy plan
               operated this backup policy job (may be
               [deleted](https://cloud.ibm.com/apidocs/vpc#deleted-resources)).
        :param datetime created_at: The date and time that the backup policy job
               was created.
        :param str href: The URL for this backup policy job.
        :param str id: The unique identifier for this backup policy job.
        :param str job_type: The type of backup policy job.
               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 backup policy job on which
               the unexpected property value was encountered.
        :param str resource_type: The resource type.
        :param BackupPolicyJobSource source: The source this backup was created
               from (may be
               [deleted](https://cloud.ibm.com/apidocs/vpc#deleted-resources)).
        :param str status: The status of the backup policy job.
               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 backup policy job on which
               the unexpected property value was encountered.
        :param List[BackupPolicyJobStatusReason] status_reasons: The reasons for
               the current status (if any).
               The enumerated reason code values for this property will expand in the
               future. When processing this property, check for and log unknown values.
               Optionally halt processing and surface the error, or bypass the resource on
               which the unexpected reason code was encountered.
        :param List[SnapshotReference] target_snapshots: The snapshots operated on
               by this backup policy job (may be
               [deleted](https://cloud.ibm.com/apidocs/vpc#deleted-resources)).
        :param datetime completed_at: (optional) The date and time that the backup
               policy job was completed.
               If absent, the backup policy job has not yet completed.
        """
        self.auto_delete = auto_delete
        self.auto_delete_after = auto_delete_after
        self.backup_policy_plan = backup_policy_plan
        self.completed_at = completed_at
        self.created_at = created_at
        self.href = href
        self.id = id
        self.job_type = job_type
        self.resource_type = resource_type
        self.source = source
        self.status = status
        self.status_reasons = status_reasons
        self.target_snapshots = target_snapshots

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'BackupPolicyJob':
        """Initialize a BackupPolicyJob object from a json dictionary."""
        args = {}
        if 'auto_delete' in _dict:
            args['auto_delete'] = _dict.get('auto_delete')
        else:
            raise ValueError('Required property \'auto_delete\' not present in BackupPolicyJob JSON')
        if 'auto_delete_after' in _dict:
            args['auto_delete_after'] = _dict.get('auto_delete_after')
        else:
            raise ValueError('Required property \'auto_delete_after\' not present in BackupPolicyJob JSON')
        if 'backup_policy_plan' in _dict:
            args['backup_policy_plan'] = BackupPolicyPlanReference.from_dict(_dict.get('backup_policy_plan'))
        else:
            raise ValueError('Required property \'backup_policy_plan\' not present in BackupPolicyJob JSON')
        if 'completed_at' in _dict:
            args['completed_at'] = string_to_datetime(_dict.get('completed_at'))
        if 'created_at' in _dict:
            args['created_at'] = string_to_datetime(_dict.get('created_at'))
        else:
            raise ValueError('Required property \'created_at\' not present in BackupPolicyJob JSON')
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in BackupPolicyJob JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in BackupPolicyJob JSON')
        if 'job_type' in _dict:
            args['job_type'] = _dict.get('job_type')
        else:
            raise ValueError('Required property \'job_type\' not present in BackupPolicyJob JSON')
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError('Required property \'resource_type\' not present in BackupPolicyJob JSON')
        if 'source' in _dict:
            args['source'] = _dict.get('source')
        else:
            raise ValueError('Required property \'source\' not present in BackupPolicyJob JSON')
        if 'status' in _dict:
            args['status'] = _dict.get('status')
        else:
            raise ValueError('Required property \'status\' not present in BackupPolicyJob JSON')
        if 'status_reasons' in _dict:
            args['status_reasons'] = [BackupPolicyJobStatusReason.from_dict(v) for v in _dict.get('status_reasons')]
        else:
            raise ValueError('Required property \'status_reasons\' not present in BackupPolicyJob JSON')
        if 'target_snapshots' in _dict:
            args['target_snapshots'] = [SnapshotReference.from_dict(v) for v in _dict.get('target_snapshots')]
        else:
            raise ValueError('Required property \'target_snapshots\' not present in BackupPolicyJob JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a BackupPolicyJob object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'auto_delete') and self.auto_delete is not None:
            _dict['auto_delete'] = self.auto_delete
        if hasattr(self, 'auto_delete_after') and self.auto_delete_after is not None:
            _dict['auto_delete_after'] = self.auto_delete_after
        if hasattr(self, 'backup_policy_plan') and self.backup_policy_plan is not None:
            if isinstance(self.backup_policy_plan, dict):
                _dict['backup_policy_plan'] = self.backup_policy_plan
            else:
                _dict['backup_policy_plan'] = self.backup_policy_plan.to_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, 'job_type') and self.job_type is not None:
            _dict['job_type'] = self.job_type
        if hasattr(self, 'resource_type') and self.resource_type is not None:
            _dict['resource_type'] = self.resource_type
        if hasattr(self, 'source') and self.source is not None:
            if isinstance(self.source, dict):
                _dict['source'] = self.source
            else:
                _dict['source'] = self.source.to_dict()
        if hasattr(self, 'status') and self.status is not None:
            _dict['status'] = self.status
        if hasattr(self, 'status_reasons') and self.status_reasons is not None:
            status_reasons_list = []
            for v in self.status_reasons:
                if isinstance(v, dict):
                    status_reasons_list.append(v)
                else:
                    status_reasons_list.append(v.to_dict())
            _dict['status_reasons'] = status_reasons_list
        if hasattr(self, 'target_snapshots') and self.target_snapshots is not None:
            target_snapshots_list = []
            for v in self.target_snapshots:
                if isinstance(v, dict):
                    target_snapshots_list.append(v)
                else:
                    target_snapshots_list.append(v.to_dict())
            _dict['target_snapshots'] = target_snapshots_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 BackupPolicyJob object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'BackupPolicyJob') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'BackupPolicyJob') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class JobTypeEnum(str, Enum):
        """
        The type of backup policy job.
        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 backup policy job on which the unexpected
        property value was encountered.
        """

        CREATION = 'creation'
        DELETION = 'deletion'


    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        BACKUP_POLICY_JOB = 'backup_policy_job'


    class StatusEnum(str, Enum):
        """
        The status of the backup policy job.
        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 backup policy job on which the unexpected
        property value was encountered.
        """

        FAILED = 'failed'
        RUNNING = 'running'
        SUCCEEDED = 'succeeded'



class BackupPolicyJobCollection:
    """
    BackupPolicyJobCollection.

    :attr BackupPolicyJobCollectionFirst first: A link to the first page of
          resources.
    :attr List[BackupPolicyJob] jobs: Collection of backup policy jobs.
    :attr int limit: The maximum number of resources that can be returned by the
          request.
    :attr BackupPolicyJobCollectionNext 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: 'BackupPolicyJobCollectionFirst',
        jobs: List['BackupPolicyJob'],
        limit: int,
        total_count: int,
        *,
        next: 'BackupPolicyJobCollectionNext' = None,
    ) -> None:
        """
        Initialize a BackupPolicyJobCollection object.

        :param BackupPolicyJobCollectionFirst first: A link to the first page of
               resources.
        :param List[BackupPolicyJob] jobs: Collection of backup policy jobs.
        :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 BackupPolicyJobCollectionNext 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.jobs = jobs
        self.limit = limit
        self.next = next
        self.total_count = total_count

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'BackupPolicyJobCollection':
        """Initialize a BackupPolicyJobCollection object from a json dictionary."""
        args = {}
        if 'first' in _dict:
            args['first'] = BackupPolicyJobCollectionFirst.from_dict(_dict.get('first'))
        else:
            raise ValueError('Required property \'first\' not present in BackupPolicyJobCollection JSON')
        if 'jobs' in _dict:
            args['jobs'] = [BackupPolicyJob.from_dict(v) for v in _dict.get('jobs')]
        else:
            raise ValueError('Required property \'jobs\' not present in BackupPolicyJobCollection JSON')
        if 'limit' in _dict:
            args['limit'] = _dict.get('limit')
        else:
            raise ValueError('Required property \'limit\' not present in BackupPolicyJobCollection JSON')
        if 'next' in _dict:
            args['next'] = BackupPolicyJobCollectionNext.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 BackupPolicyJobCollection JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a BackupPolicyJobCollection object from 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:
            if isinstance(self.first, dict):
                _dict['first'] = self.first
            else:
                _dict['first'] = self.first.to_dict()
        if hasattr(self, 'jobs') and self.jobs is not None:
            jobs_list = []
            for v in self.jobs:
                if isinstance(v, dict):
                    jobs_list.append(v)
                else:
                    jobs_list.append(v.to_dict())
            _dict['jobs'] = jobs_list
        if hasattr(self, 'limit') and self.limit is not None:
            _dict['limit'] = self.limit
        if hasattr(self, 'next') and self.next is not None:
            if isinstance(self.next, dict):
                _dict['next'] = self.next
            else:
                _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 BackupPolicyJobCollection object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'BackupPolicyJobCollection') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'BackupPolicyJobCollection') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class BackupPolicyJobCollectionFirst:
    """
    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 BackupPolicyJobCollectionFirst object.

        :param str href: The URL for a page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'BackupPolicyJobCollectionFirst':
        """Initialize a BackupPolicyJobCollectionFirst object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in BackupPolicyJobCollectionFirst JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a BackupPolicyJobCollectionFirst object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(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 BackupPolicyJobCollectionFirst object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'BackupPolicyJobCollectionFirst') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'BackupPolicyJobCollectionFirst') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class BackupPolicyJobCollectionNext:
    """
    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 BackupPolicyJobCollectionNext object.

        :param str href: The URL for a page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'BackupPolicyJobCollectionNext':
        """Initialize a BackupPolicyJobCollectionNext object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in BackupPolicyJobCollectionNext JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a BackupPolicyJobCollectionNext object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(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 BackupPolicyJobCollectionNext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'BackupPolicyJobCollectionNext') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'BackupPolicyJobCollectionNext') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class BackupPolicyJobSource:
    """
    The source this backup was created from (may be
    [deleted](https://cloud.ibm.com/apidocs/vpc#deleted-resources)).

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a BackupPolicyJobSource object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['BackupPolicyJobSourceVolumeReference'])
        )
        raise Exception(msg)


class BackupPolicyJobStatusReason:
    """
    BackupPolicyJobStatusReason.

    :attr str code: A snake case string succinctly identifying the status reason:
          - `internal_error`: Internal error (contact IBM support)
          - `snapshot_pending`: Cannot delete backup (snapshot) in the `pending` lifecycle
          state
          - `snapshot_volume_limit`: The snapshot limit for the source volume has been
          reached
          - `source_volume_busy`: The source volume has `busy` set (after multiple
          retries).
    :attr str message: An explanation of the status reason.
    :attr str more_info: (optional) Link to documentation about this status reason.
    """

    def __init__(
        self,
        code: str,
        message: str,
        *,
        more_info: str = None,
    ) -> None:
        """
        Initialize a BackupPolicyJobStatusReason object.

        :param str code: A snake case string succinctly identifying the status
               reason:
               - `internal_error`: Internal error (contact IBM support)
               - `snapshot_pending`: Cannot delete backup (snapshot) in the `pending`
               lifecycle state
               - `snapshot_volume_limit`: The snapshot limit for the source volume has
               been reached
               - `source_volume_busy`: The source volume has `busy` set (after multiple
               retries).
        :param str message: An explanation of the status reason.
        :param str more_info: (optional) Link to documentation about this status
               reason.
        """
        self.code = code
        self.message = message
        self.more_info = more_info

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'BackupPolicyJobStatusReason':
        """Initialize a BackupPolicyJobStatusReason object from a json dictionary."""
        args = {}
        if 'code' in _dict:
            args['code'] = _dict.get('code')
        else:
            raise ValueError('Required property \'code\' not present in BackupPolicyJobStatusReason JSON')
        if 'message' in _dict:
            args['message'] = _dict.get('message')
        else:
            raise ValueError('Required property \'message\' not present in BackupPolicyJobStatusReason JSON')
        if 'more_info' in _dict:
            args['more_info'] = _dict.get('more_info')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a BackupPolicyJobStatusReason object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'code') and self.code is not None:
            _dict['code'] = self.code
        if hasattr(self, 'message') and self.message is not None:
            _dict['message'] = self.message
        if hasattr(self, 'more_info') and self.more_info is not None:
            _dict['more_info'] = self.more_info
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this BackupPolicyJobStatusReason object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'BackupPolicyJobStatusReason') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'BackupPolicyJobStatusReason') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class CodeEnum(str, Enum):
        """
        A snake case string succinctly identifying the status reason:
        - `internal_error`: Internal error (contact IBM support)
        - `snapshot_pending`: Cannot delete backup (snapshot) in the `pending` lifecycle
        state
        - `snapshot_volume_limit`: The snapshot limit for the source volume has been
        reached
        - `source_volume_busy`: The source volume has `busy` set (after multiple retries).
        """

        INTERNAL_ERROR = 'internal_error'
        SNAPSHOT_PENDING = 'snapshot_pending'
        SNAPSHOT_VOLUME_LIMIT = 'snapshot_volume_limit'
        SOURCE_VOLUME_BUSY = 'source_volume_busy'



class BackupPolicyPatch:
    """
    BackupPolicyPatch.

    :attr List[str] match_user_tags: (optional) The user tags this backup policy
          will apply to (replacing any existing tags). Resources that have both a matching
          user tag and a matching type will be subject to the backup policy.
    :attr str name: (optional) The name for this backup policy. The name must not be
          used by another backup policy in the region.
    """

    def __init__(
        self,
        *,
        match_user_tags: List[str] = None,
        name: str = None,
    ) -> None:
        """
        Initialize a BackupPolicyPatch object.

        :param List[str] match_user_tags: (optional) The user tags this backup
               policy will apply to (replacing any existing tags). Resources that have
               both a matching user tag and a matching type will be subject to the backup
               policy.
        :param str name: (optional) The name for this backup policy. The name must
               not be used by another backup policy in the region.
        """
        self.match_user_tags = match_user_tags
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'BackupPolicyPatch':
        """Initialize a BackupPolicyPatch object from a json dictionary."""
        args = {}
        if 'match_user_tags' in _dict:
            args['match_user_tags'] = _dict.get('match_user_tags')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a BackupPolicyPatch object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'match_user_tags') and self.match_user_tags is not None:
            _dict['match_user_tags'] = self.match_user_tags
        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 BackupPolicyPatch object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'BackupPolicyPatch') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'BackupPolicyPatch') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class BackupPolicyPlan:
    """
    BackupPolicyPlan.

    :attr bool active: Indicates whether the plan is active.
    :attr List[str] attach_user_tags: The user tags to attach to backups (snapshots)
          created by this plan.
    :attr BackupPolicyPlanClonePolicy clone_policy:
    :attr bool copy_user_tags: Indicates whether to copy the source's user tags to
          the created backups (snapshots).
    :attr datetime created_at: The date and time that the backup policy plan was
          created.
    :attr str cron_spec: The cron specification for the backup schedule. The backup
          policy jobs
          (which create and delete backups for this plan) will not start until this time,
          and may start for up to 90 minutes after this time.
          All backup schedules for plans in the same policy must be at least an hour
          apart.
    :attr BackupPolicyPlanDeletionTrigger deletion_trigger:
    :attr str href: The URL for this backup policy plan.
    :attr str id: The unique identifier for this backup policy plan.
    :attr str lifecycle_state: The lifecycle state of this backup policy plan.
    :attr str name: The name for this backup policy plan. The name is unique across
          all plans in the backup policy.
    :attr List[BackupPolicyPlanRemoteRegionPolicy] remote_region_policies: The
          policies for additional backups in remote regions.
    :attr str resource_type: The resource type.
    """

    def __init__(
        self,
        active: bool,
        attach_user_tags: List[str],
        clone_policy: 'BackupPolicyPlanClonePolicy',
        copy_user_tags: bool,
        created_at: datetime,
        cron_spec: str,
        deletion_trigger: 'BackupPolicyPlanDeletionTrigger',
        href: str,
        id: str,
        lifecycle_state: str,
        name: str,
        remote_region_policies: List['BackupPolicyPlanRemoteRegionPolicy'],
        resource_type: str,
    ) -> None:
        """
        Initialize a BackupPolicyPlan object.

        :param bool active: Indicates whether the plan is active.
        :param List[str] attach_user_tags: The user tags to attach to backups
               (snapshots) created by this plan.
        :param BackupPolicyPlanClonePolicy clone_policy:
        :param bool copy_user_tags: Indicates whether to copy the source's user
               tags to the created backups (snapshots).
        :param datetime created_at: The date and time that the backup policy plan
               was created.
        :param str cron_spec: The cron specification for the backup schedule. The
               backup policy jobs
               (which create and delete backups for this plan) will not start until this
               time, and may start for up to 90 minutes after this time.
               All backup schedules for plans in the same policy must be at least an hour
               apart.
        :param BackupPolicyPlanDeletionTrigger deletion_trigger:
        :param str href: The URL for this backup policy plan.
        :param str id: The unique identifier for this backup policy plan.
        :param str lifecycle_state: The lifecycle state of this backup policy plan.
        :param str name: The name for this backup policy plan. The name is unique
               across all plans in the backup policy.
        :param List[BackupPolicyPlanRemoteRegionPolicy] remote_region_policies: The
               policies for additional backups in remote regions.
        :param str resource_type: The resource type.
        """
        self.active = active
        self.attach_user_tags = attach_user_tags
        self.clone_policy = clone_policy
        self.copy_user_tags = copy_user_tags
        self.created_at = created_at
        self.cron_spec = cron_spec
        self.deletion_trigger = deletion_trigger
        self.href = href
        self.id = id
        self.lifecycle_state = lifecycle_state
        self.name = name
        self.remote_region_policies = remote_region_policies
        self.resource_type = resource_type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'BackupPolicyPlan':
        """Initialize a BackupPolicyPlan object from a json dictionary."""
        args = {}
        if 'active' in _dict:
            args['active'] = _dict.get('active')
        else:
            raise ValueError('Required property \'active\' not present in BackupPolicyPlan JSON')
        if 'attach_user_tags' in _dict:
            args['attach_user_tags'] = _dict.get('attach_user_tags')
        else:
            raise ValueError('Required property \'attach_user_tags\' not present in BackupPolicyPlan JSON')
        if 'clone_policy' in _dict:
            args['clone_policy'] = BackupPolicyPlanClonePolicy.from_dict(_dict.get('clone_policy'))
        else:
            raise ValueError('Required property \'clone_policy\' not present in BackupPolicyPlan JSON')
        if 'copy_user_tags' in _dict:
            args['copy_user_tags'] = _dict.get('copy_user_tags')
        else:
            raise ValueError('Required property \'copy_user_tags\' not present in BackupPolicyPlan 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 BackupPolicyPlan JSON')
        if 'cron_spec' in _dict:
            args['cron_spec'] = _dict.get('cron_spec')
        else:
            raise ValueError('Required property \'cron_spec\' not present in BackupPolicyPlan JSON')
        if 'deletion_trigger' in _dict:
            args['deletion_trigger'] = BackupPolicyPlanDeletionTrigger.from_dict(_dict.get('deletion_trigger'))
        else:
            raise ValueError('Required property \'deletion_trigger\' not present in BackupPolicyPlan JSON')
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in BackupPolicyPlan JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in BackupPolicyPlan JSON')
        if 'lifecycle_state' in _dict:
            args['lifecycle_state'] = _dict.get('lifecycle_state')
        else:
            raise ValueError('Required property \'lifecycle_state\' not present in BackupPolicyPlan JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in BackupPolicyPlan JSON')
        if 'remote_region_policies' in _dict:
            args['remote_region_policies'] = [BackupPolicyPlanRemoteRegionPolicy.from_dict(v) for v in _dict.get('remote_region_policies')]
        else:
            raise ValueError('Required property \'remote_region_policies\' not present in BackupPolicyPlan JSON')
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError('Required property \'resource_type\' not present in BackupPolicyPlan JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a BackupPolicyPlan object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'active') and self.active is not None:
            _dict['active'] = self.active
        if hasattr(self, 'attach_user_tags') and self.attach_user_tags is not None:
            _dict['attach_user_tags'] = self.attach_user_tags
        if hasattr(self, 'clone_policy') and self.clone_policy is not None:
            if isinstance(self.clone_policy, dict):
                _dict['clone_policy'] = self.clone_policy
            else:
                _dict['clone_policy'] = self.clone_policy.to_dict()
        if hasattr(self, 'copy_user_tags') and self.copy_user_tags is not None:
            _dict['copy_user_tags'] = self.copy_user_tags
        if hasattr(self, 'created_at') and self.created_at is not None:
            _dict['created_at'] = datetime_to_string(self.created_at)
        if hasattr(self, 'cron_spec') and self.cron_spec is not None:
            _dict['cron_spec'] = self.cron_spec
        if hasattr(self, 'deletion_trigger') and self.deletion_trigger is not None:
            if isinstance(self.deletion_trigger, dict):
                _dict['deletion_trigger'] = self.deletion_trigger
            else:
                _dict['deletion_trigger'] = self.deletion_trigger.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, '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, 'remote_region_policies') and self.remote_region_policies is not None:
            remote_region_policies_list = []
            for v in self.remote_region_policies:
                if isinstance(v, dict):
                    remote_region_policies_list.append(v)
                else:
                    remote_region_policies_list.append(v.to_dict())
            _dict['remote_region_policies'] = remote_region_policies_list
        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 BackupPolicyPlan object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'BackupPolicyPlan') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'BackupPolicyPlan') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class LifecycleStateEnum(str, Enum):
        """
        The lifecycle state of this backup policy plan.
        """

        DELETING = 'deleting'
        FAILED = 'failed'
        PENDING = 'pending'
        STABLE = 'stable'
        SUSPENDED = 'suspended'
        UPDATING = 'updating'
        WAITING = 'waiting'


    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        BACKUP_POLICY_PLAN = 'backup_policy_plan'



class BackupPolicyPlanClonePolicy:
    """
    BackupPolicyPlanClonePolicy.

    :attr int max_snapshots: The maximum number of recent snapshots (per source)
          that will keep clones.
    :attr List[ZoneReference] zones: The zone this backup policy plan will create
          snapshot clones in.
    """

    def __init__(
        self,
        max_snapshots: int,
        zones: List['ZoneReference'],
    ) -> None:
        """
        Initialize a BackupPolicyPlanClonePolicy object.

        :param int max_snapshots: The maximum number of recent snapshots (per
               source) that will keep clones.
        :param List[ZoneReference] zones: The zone this backup policy plan will
               create snapshot clones in.
        """
        self.max_snapshots = max_snapshots
        self.zones = zones

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'BackupPolicyPlanClonePolicy':
        """Initialize a BackupPolicyPlanClonePolicy object from a json dictionary."""
        args = {}
        if 'max_snapshots' in _dict:
            args['max_snapshots'] = _dict.get('max_snapshots')
        else:
            raise ValueError('Required property \'max_snapshots\' not present in BackupPolicyPlanClonePolicy JSON')
        if 'zones' in _dict:
            args['zones'] = [ZoneReference.from_dict(v) for v in _dict.get('zones')]
        else:
            raise ValueError('Required property \'zones\' not present in BackupPolicyPlanClonePolicy JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a BackupPolicyPlanClonePolicy object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'max_snapshots') and self.max_snapshots is not None:
            _dict['max_snapshots'] = self.max_snapshots
        if hasattr(self, 'zones') and self.zones is not None:
            zones_list = []
            for v in self.zones:
                if isinstance(v, dict):
                    zones_list.append(v)
                else:
                    zones_list.append(v.to_dict())
            _dict['zones'] = zones_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 BackupPolicyPlanClonePolicy object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'BackupPolicyPlanClonePolicy') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'BackupPolicyPlanClonePolicy') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class BackupPolicyPlanClonePolicyPatch:
    """
    BackupPolicyPlanClonePolicyPatch.

    :attr int max_snapshots: (optional) The maximum number of recent snapshots (per
          source) that will keep clones.
    :attr List[ZoneIdentity] zones: (optional) The zones this backup policy plan
          will create snapshot clones in. Updating this value does not change the clones
          for snapshots that have already been created by this plan.
    """

    def __init__(
        self,
        *,
        max_snapshots: int = None,
        zones: List['ZoneIdentity'] = None,
    ) -> None:
        """
        Initialize a BackupPolicyPlanClonePolicyPatch object.

        :param int max_snapshots: (optional) The maximum number of recent snapshots
               (per source) that will keep clones.
        :param List[ZoneIdentity] zones: (optional) The zones this backup policy
               plan will create snapshot clones in. Updating this value does not change
               the clones for snapshots that have already been created by this plan.
        """
        self.max_snapshots = max_snapshots
        self.zones = zones

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'BackupPolicyPlanClonePolicyPatch':
        """Initialize a BackupPolicyPlanClonePolicyPatch object from a json dictionary."""
        args = {}
        if 'max_snapshots' in _dict:
            args['max_snapshots'] = _dict.get('max_snapshots')
        if 'zones' in _dict:
            args['zones'] = _dict.get('zones')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a BackupPolicyPlanClonePolicyPatch object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'max_snapshots') and self.max_snapshots is not None:
            _dict['max_snapshots'] = self.max_snapshots
        if hasattr(self, 'zones') and self.zones is not None:
            zones_list = []
            for v in self.zones:
                if isinstance(v, dict):
                    zones_list.append(v)
                else:
                    zones_list.append(v.to_dict())
            _dict['zones'] = zones_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 BackupPolicyPlanClonePolicyPatch object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'BackupPolicyPlanClonePolicyPatch') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'BackupPolicyPlanClonePolicyPatch') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class BackupPolicyPlanClonePolicyPrototype:
    """
    BackupPolicyPlanClonePolicyPrototype.

    :attr int max_snapshots: (optional) The maximum number of recent snapshots (per
          source) that will keep clones.
    :attr List[ZoneIdentity] zones: The zone this backup policy plan will create
          snapshot clones in.
    """

    def __init__(
        self,
        zones: List['ZoneIdentity'],
        *,
        max_snapshots: int = None,
    ) -> None:
        """
        Initialize a BackupPolicyPlanClonePolicyPrototype object.

        :param List[ZoneIdentity] zones: The zone this backup policy plan will
               create snapshot clones in.
        :param int max_snapshots: (optional) The maximum number of recent snapshots
               (per source) that will keep clones.
        """
        self.max_snapshots = max_snapshots
        self.zones = zones

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'BackupPolicyPlanClonePolicyPrototype':
        """Initialize a BackupPolicyPlanClonePolicyPrototype object from a json dictionary."""
        args = {}
        if 'max_snapshots' in _dict:
            args['max_snapshots'] = _dict.get('max_snapshots')
        if 'zones' in _dict:
            args['zones'] = _dict.get('zones')
        else:
            raise ValueError('Required property \'zones\' not present in BackupPolicyPlanClonePolicyPrototype JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a BackupPolicyPlanClonePolicyPrototype object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'max_snapshots') and self.max_snapshots is not None:
            _dict['max_snapshots'] = self.max_snapshots
        if hasattr(self, 'zones') and self.zones is not None:
            zones_list = []
            for v in self.zones:
                if isinstance(v, dict):
                    zones_list.append(v)
                else:
                    zones_list.append(v.to_dict())
            _dict['zones'] = zones_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 BackupPolicyPlanClonePolicyPrototype object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'BackupPolicyPlanClonePolicyPrototype') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'BackupPolicyPlanClonePolicyPrototype') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class BackupPolicyPlanCollection:
    """
    BackupPolicyPlanCollection.

    :attr List[BackupPolicyPlan] plans: Collection of backup policy plans.
    """

    def __init__(
        self,
        plans: List['BackupPolicyPlan'],
    ) -> None:
        """
        Initialize a BackupPolicyPlanCollection object.

        :param List[BackupPolicyPlan] plans: Collection of backup policy plans.
        """
        self.plans = plans

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'BackupPolicyPlanCollection':
        """Initialize a BackupPolicyPlanCollection object from a json dictionary."""
        args = {}
        if 'plans' in _dict:
            args['plans'] = [BackupPolicyPlan.from_dict(v) for v in _dict.get('plans')]
        else:
            raise ValueError('Required property \'plans\' not present in BackupPolicyPlanCollection JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a BackupPolicyPlanCollection object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'plans') and self.plans is not None:
            plans_list = []
            for v in self.plans:
                if isinstance(v, dict):
                    plans_list.append(v)
                else:
                    plans_list.append(v.to_dict())
            _dict['plans'] = plans_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 BackupPolicyPlanCollection object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'BackupPolicyPlanCollection') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'BackupPolicyPlanCollection') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class BackupPolicyPlanDeletionTrigger:
    """
    BackupPolicyPlanDeletionTrigger.

    :attr int delete_after: The maximum number of days to keep each backup after
          creation.
    :attr int delete_over_count: (optional) The maximum number of recent backups to
          keep. If absent, there is no maximum.
    """

    def __init__(
        self,
        delete_after: int,
        *,
        delete_over_count: int = None,
    ) -> None:
        """
        Initialize a BackupPolicyPlanDeletionTrigger object.

        :param int delete_after: The maximum number of days to keep each backup
               after creation.
        :param int delete_over_count: (optional) The maximum number of recent
               backups to keep. If absent, there is no maximum.
        """
        self.delete_after = delete_after
        self.delete_over_count = delete_over_count

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'BackupPolicyPlanDeletionTrigger':
        """Initialize a BackupPolicyPlanDeletionTrigger object from a json dictionary."""
        args = {}
        if 'delete_after' in _dict:
            args['delete_after'] = _dict.get('delete_after')
        else:
            raise ValueError('Required property \'delete_after\' not present in BackupPolicyPlanDeletionTrigger JSON')
        if 'delete_over_count' in _dict:
            args['delete_over_count'] = _dict.get('delete_over_count')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a BackupPolicyPlanDeletionTrigger object from 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_after') and self.delete_after is not None:
            _dict['delete_after'] = self.delete_after
        if hasattr(self, 'delete_over_count') and self.delete_over_count is not None:
            _dict['delete_over_count'] = self.delete_over_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 BackupPolicyPlanDeletionTrigger object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'BackupPolicyPlanDeletionTrigger') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'BackupPolicyPlanDeletionTrigger') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class BackupPolicyPlanDeletionTriggerPatch:
    """
    BackupPolicyPlanDeletionTriggerPatch.

    :attr int delete_after: (optional) The maximum number of days to keep each
          backup after creation.
    :attr int delete_over_count: (optional) The maximum number of recent backups to
          keep. Specify `null` to remove any existing maximum.
    """

    def __init__(
        self,
        *,
        delete_after: int = None,
        delete_over_count: int = None,
    ) -> None:
        """
        Initialize a BackupPolicyPlanDeletionTriggerPatch object.

        :param int delete_after: (optional) The maximum number of days to keep each
               backup after creation.
        :param int delete_over_count: (optional) The maximum number of recent
               backups to keep. Specify `null` to remove any existing maximum.
        """
        self.delete_after = delete_after
        self.delete_over_count = delete_over_count

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'BackupPolicyPlanDeletionTriggerPatch':
        """Initialize a BackupPolicyPlanDeletionTriggerPatch object from a json dictionary."""
        args = {}
        if 'delete_after' in _dict:
            args['delete_after'] = _dict.get('delete_after')
        if 'delete_over_count' in _dict:
            args['delete_over_count'] = _dict.get('delete_over_count')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a BackupPolicyPlanDeletionTriggerPatch object from 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_after') and self.delete_after is not None:
            _dict['delete_after'] = self.delete_after
        if hasattr(self, 'delete_over_count') and self.delete_over_count is not None:
            _dict['delete_over_count'] = self.delete_over_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 BackupPolicyPlanDeletionTriggerPatch object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'BackupPolicyPlanDeletionTriggerPatch') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'BackupPolicyPlanDeletionTriggerPatch') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class BackupPolicyPlanDeletionTriggerPrototype:
    """
    BackupPolicyPlanDeletionTriggerPrototype.

    :attr int delete_after: (optional) The maximum number of days to keep each
          backup after creation.
    :attr int delete_over_count: (optional) The maximum number of recent backups to
          keep. If unspecified, there will be no maximum.
    """

    def __init__(
        self,
        *,
        delete_after: int = None,
        delete_over_count: int = None,
    ) -> None:
        """
        Initialize a BackupPolicyPlanDeletionTriggerPrototype object.

        :param int delete_after: (optional) The maximum number of days to keep each
               backup after creation.
        :param int delete_over_count: (optional) The maximum number of recent
               backups to keep. If unspecified, there will be no maximum.
        """
        self.delete_after = delete_after
        self.delete_over_count = delete_over_count

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'BackupPolicyPlanDeletionTriggerPrototype':
        """Initialize a BackupPolicyPlanDeletionTriggerPrototype object from a json dictionary."""
        args = {}
        if 'delete_after' in _dict:
            args['delete_after'] = _dict.get('delete_after')
        if 'delete_over_count' in _dict:
            args['delete_over_count'] = _dict.get('delete_over_count')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a BackupPolicyPlanDeletionTriggerPrototype object from 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_after') and self.delete_after is not None:
            _dict['delete_after'] = self.delete_after
        if hasattr(self, 'delete_over_count') and self.delete_over_count is not None:
            _dict['delete_over_count'] = self.delete_over_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 BackupPolicyPlanDeletionTriggerPrototype object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'BackupPolicyPlanDeletionTriggerPrototype') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'BackupPolicyPlanDeletionTriggerPrototype') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class BackupPolicyPlanPatch:
    """
    BackupPolicyPlanPatch.

    :attr bool active: (optional) Indicates whether the plan is active.
    :attr List[str] attach_user_tags: (optional) The user tags to attach to backups
          (snapshots) created by this plan. Updating this value does not change the user
          tags for backups that have already been created by this plan.
    :attr BackupPolicyPlanClonePolicyPatch clone_policy: (optional)
    :attr bool copy_user_tags: (optional) Indicates whether to copy the source's
          user tags to the created backups (snapshots).
    :attr str cron_spec: (optional) The cron specification for the backup schedule.
          The backup policy jobs
          (which create and delete backups for this plan) will not start until this time,
          and may start for up to 90 minutes after this time.
          All backup schedules for plans in the same policy must be at least an hour
          apart.
    :attr BackupPolicyPlanDeletionTriggerPatch deletion_trigger: (optional)
    :attr str name: (optional) The name for this backup policy plan. The name must
          not be used by another plan for the backup policy.
    :attr List[BackupPolicyPlanRemoteRegionPolicyPrototype] remote_region_policies:
          (optional) The policies for additional backups in remote regions (replacing any
          existing policies).
    """

    def __init__(
        self,
        *,
        active: bool = None,
        attach_user_tags: List[str] = None,
        clone_policy: 'BackupPolicyPlanClonePolicyPatch' = None,
        copy_user_tags: bool = None,
        cron_spec: str = None,
        deletion_trigger: 'BackupPolicyPlanDeletionTriggerPatch' = None,
        name: str = None,
        remote_region_policies: List['BackupPolicyPlanRemoteRegionPolicyPrototype'] = None,
    ) -> None:
        """
        Initialize a BackupPolicyPlanPatch object.

        :param bool active: (optional) Indicates whether the plan is active.
        :param List[str] attach_user_tags: (optional) The user tags to attach to
               backups (snapshots) created by this plan. Updating this value does not
               change the user tags for backups that have already been created by this
               plan.
        :param BackupPolicyPlanClonePolicyPatch clone_policy: (optional)
        :param bool copy_user_tags: (optional) Indicates whether to copy the
               source's user tags to the created backups (snapshots).
        :param str cron_spec: (optional) The cron specification for the backup
               schedule. The backup policy jobs
               (which create and delete backups for this plan) will not start until this
               time, and may start for up to 90 minutes after this time.
               All backup schedules for plans in the same policy must be at least an hour
               apart.
        :param BackupPolicyPlanDeletionTriggerPatch deletion_trigger: (optional)
        :param str name: (optional) The name for this backup policy plan. The name
               must not be used by another plan for the backup policy.
        :param List[BackupPolicyPlanRemoteRegionPolicyPrototype]
               remote_region_policies: (optional) The policies for additional backups in
               remote regions (replacing any existing policies).
        """
        self.active = active
        self.attach_user_tags = attach_user_tags
        self.clone_policy = clone_policy
        self.copy_user_tags = copy_user_tags
        self.cron_spec = cron_spec
        self.deletion_trigger = deletion_trigger
        self.name = name
        self.remote_region_policies = remote_region_policies

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'BackupPolicyPlanPatch':
        """Initialize a BackupPolicyPlanPatch object from a json dictionary."""
        args = {}
        if 'active' in _dict:
            args['active'] = _dict.get('active')
        if 'attach_user_tags' in _dict:
            args['attach_user_tags'] = _dict.get('attach_user_tags')
        if 'clone_policy' in _dict:
            args['clone_policy'] = BackupPolicyPlanClonePolicyPatch.from_dict(_dict.get('clone_policy'))
        if 'copy_user_tags' in _dict:
            args['copy_user_tags'] = _dict.get('copy_user_tags')
        if 'cron_spec' in _dict:
            args['cron_spec'] = _dict.get('cron_spec')
        if 'deletion_trigger' in _dict:
            args['deletion_trigger'] = BackupPolicyPlanDeletionTriggerPatch.from_dict(_dict.get('deletion_trigger'))
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        if 'remote_region_policies' in _dict:
            args['remote_region_policies'] = [BackupPolicyPlanRemoteRegionPolicyPrototype.from_dict(v) for v in _dict.get('remote_region_policies')]
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a BackupPolicyPlanPatch object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'active') and self.active is not None:
            _dict['active'] = self.active
        if hasattr(self, 'attach_user_tags') and self.attach_user_tags is not None:
            _dict['attach_user_tags'] = self.attach_user_tags
        if hasattr(self, 'clone_policy') and self.clone_policy is not None:
            if isinstance(self.clone_policy, dict):
                _dict['clone_policy'] = self.clone_policy
            else:
                _dict['clone_policy'] = self.clone_policy.to_dict()
        if hasattr(self, 'copy_user_tags') and self.copy_user_tags is not None:
            _dict['copy_user_tags'] = self.copy_user_tags
        if hasattr(self, 'cron_spec') and self.cron_spec is not None:
            _dict['cron_spec'] = self.cron_spec
        if hasattr(self, 'deletion_trigger') and self.deletion_trigger is not None:
            if isinstance(self.deletion_trigger, dict):
                _dict['deletion_trigger'] = self.deletion_trigger
            else:
                _dict['deletion_trigger'] = self.deletion_trigger.to_dict()
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'remote_region_policies') and self.remote_region_policies is not None:
            remote_region_policies_list = []
            for v in self.remote_region_policies:
                if isinstance(v, dict):
                    remote_region_policies_list.append(v)
                else:
                    remote_region_policies_list.append(v.to_dict())
            _dict['remote_region_policies'] = remote_region_policies_list
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this BackupPolicyPlanPatch object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'BackupPolicyPlanPatch') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'BackupPolicyPlanPatch') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class BackupPolicyPlanPrototype:
    """
    BackupPolicyPlanPrototype.

    :attr bool active: (optional) Indicates whether the plan is active.
    :attr List[str] attach_user_tags: (optional) User tags to attach to each backup
          (snapshot) created by this plan. If unspecified, no user tags will be attached.
    :attr BackupPolicyPlanClonePolicyPrototype clone_policy: (optional)
    :attr bool copy_user_tags: (optional) Indicates whether to copy the source's
          user tags to the created backups (snapshots).
    :attr str cron_spec: The cron specification for the backup schedule. The backup
          policy jobs
          (which create and delete backups for this plan) will not start until this time,
          and may start for up to 90 minutes after this time.
          All backup schedules for plans in the same policy must be at least an hour
          apart.
    :attr BackupPolicyPlanDeletionTriggerPrototype deletion_trigger: (optional)
    :attr str name: (optional) The name for this backup policy plan. The name must
          not be used by another plan for the backup policy. If unspecified, the name will
          be a hyphenated list of randomly-selected words.
    :attr List[BackupPolicyPlanRemoteRegionPolicyPrototype] remote_region_policies:
          (optional) The policies for additional backups in remote regions.
    """

    def __init__(
        self,
        cron_spec: str,
        *,
        active: bool = None,
        attach_user_tags: List[str] = None,
        clone_policy: 'BackupPolicyPlanClonePolicyPrototype' = None,
        copy_user_tags: bool = None,
        deletion_trigger: 'BackupPolicyPlanDeletionTriggerPrototype' = None,
        name: str = None,
        remote_region_policies: List['BackupPolicyPlanRemoteRegionPolicyPrototype'] = None,
    ) -> None:
        """
        Initialize a BackupPolicyPlanPrototype object.

        :param str cron_spec: The cron specification for the backup schedule. The
               backup policy jobs
               (which create and delete backups for this plan) will not start until this
               time, and may start for up to 90 minutes after this time.
               All backup schedules for plans in the same policy must be at least an hour
               apart.
        :param bool active: (optional) Indicates whether the plan is active.
        :param List[str] attach_user_tags: (optional) User tags to attach to each
               backup (snapshot) created by this plan. If unspecified, no user tags will
               be attached.
        :param BackupPolicyPlanClonePolicyPrototype clone_policy: (optional)
        :param bool copy_user_tags: (optional) Indicates whether to copy the
               source's user tags to the created backups (snapshots).
        :param BackupPolicyPlanDeletionTriggerPrototype deletion_trigger:
               (optional)
        :param str name: (optional) The name for this backup policy plan. The name
               must not be used by another plan for the backup policy. If unspecified, the
               name will be a hyphenated list of randomly-selected words.
        :param List[BackupPolicyPlanRemoteRegionPolicyPrototype]
               remote_region_policies: (optional) The policies for additional backups in
               remote regions.
        """
        self.active = active
        self.attach_user_tags = attach_user_tags
        self.clone_policy = clone_policy
        self.copy_user_tags = copy_user_tags
        self.cron_spec = cron_spec
        self.deletion_trigger = deletion_trigger
        self.name = name
        self.remote_region_policies = remote_region_policies

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'BackupPolicyPlanPrototype':
        """Initialize a BackupPolicyPlanPrototype object from a json dictionary."""
        args = {}
        if 'active' in _dict:
            args['active'] = _dict.get('active')
        if 'attach_user_tags' in _dict:
            args['attach_user_tags'] = _dict.get('attach_user_tags')
        if 'clone_policy' in _dict:
            args['clone_policy'] = BackupPolicyPlanClonePolicyPrototype.from_dict(_dict.get('clone_policy'))
        if 'copy_user_tags' in _dict:
            args['copy_user_tags'] = _dict.get('copy_user_tags')
        if 'cron_spec' in _dict:
            args['cron_spec'] = _dict.get('cron_spec')
        else:
            raise ValueError('Required property \'cron_spec\' not present in BackupPolicyPlanPrototype JSON')
        if 'deletion_trigger' in _dict:
            args['deletion_trigger'] = BackupPolicyPlanDeletionTriggerPrototype.from_dict(_dict.get('deletion_trigger'))
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        if 'remote_region_policies' in _dict:
            args['remote_region_policies'] = [BackupPolicyPlanRemoteRegionPolicyPrototype.from_dict(v) for v in _dict.get('remote_region_policies')]
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a BackupPolicyPlanPrototype object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'active') and self.active is not None:
            _dict['active'] = self.active
        if hasattr(self, 'attach_user_tags') and self.attach_user_tags is not None:
            _dict['attach_user_tags'] = self.attach_user_tags
        if hasattr(self, 'clone_policy') and self.clone_policy is not None:
            if isinstance(self.clone_policy, dict):
                _dict['clone_policy'] = self.clone_policy
            else:
                _dict['clone_policy'] = self.clone_policy.to_dict()
        if hasattr(self, 'copy_user_tags') and self.copy_user_tags is not None:
            _dict['copy_user_tags'] = self.copy_user_tags
        if hasattr(self, 'cron_spec') and self.cron_spec is not None:
            _dict['cron_spec'] = self.cron_spec
        if hasattr(self, 'deletion_trigger') and self.deletion_trigger is not None:
            if isinstance(self.deletion_trigger, dict):
                _dict['deletion_trigger'] = self.deletion_trigger
            else:
                _dict['deletion_trigger'] = self.deletion_trigger.to_dict()
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'remote_region_policies') and self.remote_region_policies is not None:
            remote_region_policies_list = []
            for v in self.remote_region_policies:
                if isinstance(v, dict):
                    remote_region_policies_list.append(v)
                else:
                    remote_region_policies_list.append(v.to_dict())
            _dict['remote_region_policies'] = remote_region_policies_list
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this BackupPolicyPlanPrototype object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'BackupPolicyPlanPrototype') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'BackupPolicyPlanPrototype') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class BackupPolicyPlanReference:
    """
    BackupPolicyPlanReference.

    :attr BackupPolicyPlanReferenceDeleted deleted: (optional) If present, this
          property indicates the referenced resource has been deleted, and provides
          some supplementary information.
    :attr str href: The URL for this backup policy plan.
    :attr str id: The unique identifier for this backup policy plan.
    :attr str name: The name for this backup policy plan. The name is unique across
          all plans in the backup policy.
    :attr BackupPolicyPlanRemote remote: (optional) If present, this property
          indicates that the resource associated with this reference
          is remote and therefore may not be directly retrievable.
    :attr str resource_type: The resource type.
    """

    def __init__(
        self,
        href: str,
        id: str,
        name: str,
        resource_type: str,
        *,
        deleted: 'BackupPolicyPlanReferenceDeleted' = None,
        remote: 'BackupPolicyPlanRemote' = None,
    ) -> None:
        """
        Initialize a BackupPolicyPlanReference object.

        :param str href: The URL for this backup policy plan.
        :param str id: The unique identifier for this backup policy plan.
        :param str name: The name for this backup policy plan. The name is unique
               across all plans in the backup policy.
        :param str resource_type: The resource type.
        :param BackupPolicyPlanReferenceDeleted deleted: (optional) If present,
               this property indicates the referenced resource has been deleted, and
               provides
               some supplementary information.
        :param BackupPolicyPlanRemote remote: (optional) If present, this property
               indicates that the resource associated with this reference
               is remote and therefore may not be directly retrievable.
        """
        self.deleted = deleted
        self.href = href
        self.id = id
        self.name = name
        self.remote = remote
        self.resource_type = resource_type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'BackupPolicyPlanReference':
        """Initialize a BackupPolicyPlanReference object from a json dictionary."""
        args = {}
        if 'deleted' in _dict:
            args['deleted'] = BackupPolicyPlanReferenceDeleted.from_dict(_dict.get('deleted'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in BackupPolicyPlanReference JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in BackupPolicyPlanReference JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in BackupPolicyPlanReference JSON')
        if 'remote' in _dict:
            args['remote'] = BackupPolicyPlanRemote.from_dict(_dict.get('remote'))
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError('Required property \'resource_type\' not present in BackupPolicyPlanReference JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a BackupPolicyPlanReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'deleted') and self.deleted is not None:
            if isinstance(self.deleted, dict):
                _dict['deleted'] = self.deleted
            else:
                _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, '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, '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 BackupPolicyPlanReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'BackupPolicyPlanReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'BackupPolicyPlanReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        BACKUP_POLICY_PLAN = 'backup_policy_plan'



class BackupPolicyPlanReferenceDeleted:
    """
    If present, this property indicates the referenced resource has been deleted, and
    provides some supplementary information.

    :attr str more_info: Link to documentation about deleted resources.
    """

    def __init__(
        self,
        more_info: str,
    ) -> None:
        """
        Initialize a BackupPolicyPlanReferenceDeleted object.

        :param str more_info: Link to documentation about deleted resources.
        """
        self.more_info = more_info

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'BackupPolicyPlanReferenceDeleted':
        """Initialize a BackupPolicyPlanReferenceDeleted object from a json dictionary."""
        args = {}
        if 'more_info' in _dict:
            args['more_info'] = _dict.get('more_info')
        else:
            raise ValueError('Required property \'more_info\' not present in BackupPolicyPlanReferenceDeleted JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a BackupPolicyPlanReferenceDeleted object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'more_info') and self.more_info is not None:
            _dict['more_info'] = self.more_info
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this BackupPolicyPlanReferenceDeleted object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'BackupPolicyPlanReferenceDeleted') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'BackupPolicyPlanReferenceDeleted') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class BackupPolicyPlanRemote:
    """
    If present, this property indicates that the resource associated with this reference
    is remote and therefore may not be directly retrievable.

    :attr RegionReference region: (optional) If present, this property indicates
          that the referenced resource is remote to this
          region, and identifies the native region.
    """

    def __init__(
        self,
        *,
        region: 'RegionReference' = None,
    ) -> None:
        """
        Initialize a BackupPolicyPlanRemote object.

        :param RegionReference region: (optional) If present, this property
               indicates that the referenced resource is remote to this
               region, and identifies the native region.
        """
        self.region = region

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'BackupPolicyPlanRemote':
        """Initialize a BackupPolicyPlanRemote object from a json dictionary."""
        args = {}
        if 'region' in _dict:
            args['region'] = RegionReference.from_dict(_dict.get('region'))
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a BackupPolicyPlanRemote object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'region') and self.region is not None:
            if isinstance(self.region, dict):
                _dict['region'] = self.region
            else:
                _dict['region'] = self.region.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 BackupPolicyPlanRemote object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'BackupPolicyPlanRemote') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'BackupPolicyPlanRemote') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class BackupPolicyPlanRemoteRegionPolicy:
    """
    BackupPolicyPlanRemoteRegionPolicy.

    :attr int delete_over_count: The region this backup policy plan will create
          backups in.
    :attr EncryptionKeyReference encryption_key: The root key used to rewrap the
          data encryption key for the backup (snapshot).
    :attr RegionReference region: The region this backup policy plan will create
          backups in.
    """

    def __init__(
        self,
        delete_over_count: int,
        encryption_key: 'EncryptionKeyReference',
        region: 'RegionReference',
    ) -> None:
        """
        Initialize a BackupPolicyPlanRemoteRegionPolicy object.

        :param int delete_over_count: The region this backup policy plan will
               create backups in.
        :param EncryptionKeyReference encryption_key: The root key used to rewrap
               the data encryption key for the backup (snapshot).
        :param RegionReference region: The region this backup policy plan will
               create backups in.
        """
        self.delete_over_count = delete_over_count
        self.encryption_key = encryption_key
        self.region = region

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'BackupPolicyPlanRemoteRegionPolicy':
        """Initialize a BackupPolicyPlanRemoteRegionPolicy object from a json dictionary."""
        args = {}
        if 'delete_over_count' in _dict:
            args['delete_over_count'] = _dict.get('delete_over_count')
        else:
            raise ValueError('Required property \'delete_over_count\' not present in BackupPolicyPlanRemoteRegionPolicy JSON')
        if 'encryption_key' in _dict:
            args['encryption_key'] = EncryptionKeyReference.from_dict(_dict.get('encryption_key'))
        else:
            raise ValueError('Required property \'encryption_key\' not present in BackupPolicyPlanRemoteRegionPolicy JSON')
        if 'region' in _dict:
            args['region'] = RegionReference.from_dict(_dict.get('region'))
        else:
            raise ValueError('Required property \'region\' not present in BackupPolicyPlanRemoteRegionPolicy JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a BackupPolicyPlanRemoteRegionPolicy object from 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_over_count') and self.delete_over_count is not None:
            _dict['delete_over_count'] = self.delete_over_count
        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, 'region') and self.region is not None:
            if isinstance(self.region, dict):
                _dict['region'] = self.region
            else:
                _dict['region'] = self.region.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 BackupPolicyPlanRemoteRegionPolicy object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'BackupPolicyPlanRemoteRegionPolicy') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'BackupPolicyPlanRemoteRegionPolicy') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class BackupPolicyPlanRemoteRegionPolicyPrototype:
    """
    BackupPolicyPlanRemoteRegionPolicyPrototype.

    :attr int delete_over_count: (optional) The region this backup policy plan will
          create backups in.
    :attr EncryptionKeyIdentity encryption_key: (optional) The root key to use to
          rewrap the data encryption key for the backup (snapshot).
          If unspecified, the source's `encryption_key` will be used.
          The specified key may be in a different account, subject to IAM policies.
    :attr RegionIdentity region: The region this backup policy plan will create
          backups in.
    """

    def __init__(
        self,
        region: 'RegionIdentity',
        *,
        delete_over_count: int = None,
        encryption_key: 'EncryptionKeyIdentity' = None,
    ) -> None:
        """
        Initialize a BackupPolicyPlanRemoteRegionPolicyPrototype object.

        :param RegionIdentity region: The region this backup policy plan will
               create backups in.
        :param int delete_over_count: (optional) The region this backup policy plan
               will create backups in.
        :param EncryptionKeyIdentity encryption_key: (optional) The root key to use
               to rewrap the data encryption key for the backup (snapshot).
               If unspecified, the source's `encryption_key` will be used.
               The specified key may be in a different account, subject to IAM policies.
        """
        self.delete_over_count = delete_over_count
        self.encryption_key = encryption_key
        self.region = region

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'BackupPolicyPlanRemoteRegionPolicyPrototype':
        """Initialize a BackupPolicyPlanRemoteRegionPolicyPrototype object from a json dictionary."""
        args = {}
        if 'delete_over_count' in _dict:
            args['delete_over_count'] = _dict.get('delete_over_count')
        if 'encryption_key' in _dict:
            args['encryption_key'] = _dict.get('encryption_key')
        if 'region' in _dict:
            args['region'] = _dict.get('region')
        else:
            raise ValueError('Required property \'region\' not present in BackupPolicyPlanRemoteRegionPolicyPrototype JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a BackupPolicyPlanRemoteRegionPolicyPrototype object from 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_over_count') and self.delete_over_count is not None:
            _dict['delete_over_count'] = self.delete_over_count
        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, 'region') and self.region is not None:
            if isinstance(self.region, dict):
                _dict['region'] = self.region
            else:
                _dict['region'] = self.region.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 BackupPolicyPlanRemoteRegionPolicyPrototype object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'BackupPolicyPlanRemoteRegionPolicyPrototype') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'BackupPolicyPlanRemoteRegionPolicyPrototype') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class BackupPolicyScope:
    """
    The scope for this backup policy.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a BackupPolicyScope object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['BackupPolicyScopeEnterpriseReference', 'BackupPolicyScopeAccountReference'])
        )
        raise Exception(msg)


class BackupPolicyScopePrototype:
    """
    The scope to use for this backup policy.
    If unspecified, the policy will be scoped to the account.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a BackupPolicyScopePrototype object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['BackupPolicyScopePrototypeEnterpriseIdentity'])
        )
        raise Exception(msg)


class BareMetalServer:
    """
    BareMetalServer.

    :attr int bandwidth: The total bandwidth (in megabits per second) shared across
          the bare metal server network interfaces.
    :attr BareMetalServerBootTarget boot_target: The possible resource types for
          this property are expected to expand in the future.
    :attr BareMetalServerCPU cpu: The bare metal server CPU configuration.
    :attr datetime created_at: The date and time that the bare metal server was
          created.
    :attr str crn: The CRN for this bare metal server.
    :attr List[BareMetalServerDisk] disks: The disks for this bare metal server,
          including any disks that are associated with the
          `boot_target`.
    :attr bool enable_secure_boot: Indicates whether secure boot is enabled. If
          enabled, the image must support secure boot or the server will fail to boot.
    :attr str href: The URL for this bare metal server.
    :attr str id: The unique identifier for this bare metal server.
    :attr List[BareMetalServerLifecycleReason] lifecycle_reasons: The reasons for
          the current `lifecycle_state` (if any).
          The enumerated reason code values for this property will expand in the future.
          When processing this property, check for and log unknown values. Optionally halt
          processing and surface the error, or bypass the resource on which the unexpected
          reason code was encountered.
    :attr str lifecycle_state: The lifecycle state of the bare metal server.
    :attr int memory: The amount of memory, truncated to whole gibibytes.
    :attr str name: The name for this bare metal server. The name is unique across
          all bare metal servers in the region.
    :attr List[NetworkInterfaceBareMetalServerContextReference] network_interfaces:
          The network interfaces for this bare metal server, including the primary network
          interface.
    :attr NetworkInterfaceBareMetalServerContextReference primary_network_interface:
          The primary network interface for this bare metal server.
    :attr BareMetalServerProfileReference profile: The
          [profile](https://cloud.ibm.com/docs/vpc?topic=vpc-bare-metal-servers-profile)
          for this bare metal server.
    :attr ResourceGroupReference resource_group: The resource group for this bare
          metal server.
    :attr str resource_type: The resource type.
    :attr str status: The status of the bare metal server.
    :attr List[BareMetalServerStatusReason] status_reasons: The reasons for the
          current status (if any).
          The enumerated reason code values for this property will expand in the future.
          When processing this property, check for and log unknown values. Optionally halt
          processing and surface the error, or bypass the resource on which the unexpected
          reason code was encountered.
    :attr BareMetalServerTrustedPlatformModule trusted_platform_module:
    :attr VPCReference vpc: The VPC this bare metal server resides in.
    :attr ZoneReference zone: The zone this bare metal server resides in.
    """

    def __init__(
        self,
        bandwidth: int,
        boot_target: 'BareMetalServerBootTarget',
        cpu: 'BareMetalServerCPU',
        created_at: datetime,
        crn: str,
        disks: List['BareMetalServerDisk'],
        enable_secure_boot: bool,
        href: str,
        id: str,
        lifecycle_reasons: List['BareMetalServerLifecycleReason'],
        lifecycle_state: str,
        memory: int,
        name: str,
        network_interfaces: List['NetworkInterfaceBareMetalServerContextReference'],
        primary_network_interface: 'NetworkInterfaceBareMetalServerContextReference',
        profile: 'BareMetalServerProfileReference',
        resource_group: 'ResourceGroupReference',
        resource_type: str,
        status: str,
        status_reasons: List['BareMetalServerStatusReason'],
        trusted_platform_module: 'BareMetalServerTrustedPlatformModule',
        vpc: 'VPCReference',
        zone: 'ZoneReference',
    ) -> None:
        """
        Initialize a BareMetalServer object.

        :param int bandwidth: The total bandwidth (in megabits per second) shared
               across the bare metal server network interfaces.
        :param BareMetalServerBootTarget boot_target: The possible resource types
               for this property are expected to expand in the future.
        :param BareMetalServerCPU cpu: The bare metal server CPU configuration.
        :param datetime created_at: The date and time that the bare metal server
               was created.
        :param str crn: The CRN for this bare metal server.
        :param List[BareMetalServerDisk] disks: The disks for this bare metal
               server, including any disks that are associated with the
               `boot_target`.
        :param bool enable_secure_boot: Indicates whether secure boot is enabled.
               If enabled, the image must support secure boot or the server will fail to
               boot.
        :param str href: The URL for this bare metal server.
        :param str id: The unique identifier for this bare metal server.
        :param List[BareMetalServerLifecycleReason] lifecycle_reasons: The reasons
               for the current `lifecycle_state` (if any).
               The enumerated reason code values for this property will expand in the
               future. When processing this property, check for and log unknown values.
               Optionally halt processing and surface the error, or bypass the resource on
               which the unexpected reason code was encountered.
        :param str lifecycle_state: The lifecycle state of the bare metal server.
        :param int memory: The amount of memory, truncated to whole gibibytes.
        :param str name: The name for this bare metal server. The name is unique
               across all bare metal servers in the region.
        :param List[NetworkInterfaceBareMetalServerContextReference]
               network_interfaces: The network interfaces for this bare metal server,
               including the primary network interface.
        :param NetworkInterfaceBareMetalServerContextReference
               primary_network_interface: The primary network interface for this bare
               metal server.
        :param BareMetalServerProfileReference profile: The
               [profile](https://cloud.ibm.com/docs/vpc?topic=vpc-bare-metal-servers-profile)
               for this bare metal server.
        :param ResourceGroupReference resource_group: The resource group for this
               bare metal server.
        :param str resource_type: The resource type.
        :param str status: The status of the bare metal server.
        :param List[BareMetalServerStatusReason] status_reasons: The reasons for
               the current status (if any).
               The enumerated reason code values for this property will expand in the
               future. When processing this property, check for and log unknown values.
               Optionally halt processing and surface the error, or bypass the resource on
               which the unexpected reason code was encountered.
        :param BareMetalServerTrustedPlatformModule trusted_platform_module:
        :param VPCReference vpc: The VPC this bare metal server resides in.
        :param ZoneReference zone: The zone this bare metal server resides in.
        """
        self.bandwidth = bandwidth
        self.boot_target = boot_target
        self.cpu = cpu
        self.created_at = created_at
        self.crn = crn
        self.disks = disks
        self.enable_secure_boot = enable_secure_boot
        self.href = href
        self.id = id
        self.lifecycle_reasons = lifecycle_reasons
        self.lifecycle_state = lifecycle_state
        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.resource_type = resource_type
        self.status = status
        self.status_reasons = status_reasons
        self.trusted_platform_module = trusted_platform_module
        self.vpc = vpc
        self.zone = zone

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'BareMetalServer':
        """Initialize a BareMetalServer object from a json dictionary."""
        args = {}
        if 'bandwidth' in _dict:
            args['bandwidth'] = _dict.get('bandwidth')
        else:
            raise ValueError('Required property \'bandwidth\' not present in BareMetalServer JSON')
        if 'boot_target' in _dict:
            args['boot_target'] = _dict.get('boot_target')
        else:
            raise ValueError('Required property \'boot_target\' not present in BareMetalServer JSON')
        if 'cpu' in _dict:
            args['cpu'] = BareMetalServerCPU.from_dict(_dict.get('cpu'))
        else:
            raise ValueError('Required property \'cpu\' not present in BareMetalServer 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 BareMetalServer JSON')
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError('Required property \'crn\' not present in BareMetalServer JSON')
        if 'disks' in _dict:
            args['disks'] = [BareMetalServerDisk.from_dict(v) for v in _dict.get('disks')]
        else:
            raise ValueError('Required property \'disks\' not present in BareMetalServer JSON')
        if 'enable_secure_boot' in _dict:
            args['enable_secure_boot'] = _dict.get('enable_secure_boot')
        else:
            raise ValueError('Required property \'enable_secure_boot\' not present in BareMetalServer JSON')
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in BareMetalServer JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in BareMetalServer JSON')
        if 'lifecycle_reasons' in _dict:
            args['lifecycle_reasons'] = [BareMetalServerLifecycleReason.from_dict(v) for v in _dict.get('lifecycle_reasons')]
        else:
            raise ValueError('Required property \'lifecycle_reasons\' not present in BareMetalServer JSON')
        if 'lifecycle_state' in _dict:
            args['lifecycle_state'] = _dict.get('lifecycle_state')
        else:
            raise ValueError('Required property \'lifecycle_state\' not present in BareMetalServer JSON')
        if 'memory' in _dict:
            args['memory'] = _dict.get('memory')
        else:
            raise ValueError('Required property \'memory\' not present in BareMetalServer JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in BareMetalServer JSON')
        if 'network_interfaces' in _dict:
            args['network_interfaces'] = [NetworkInterfaceBareMetalServerContextReference.from_dict(v) for v in _dict.get('network_interfaces')]
        else:
            raise ValueError('Required property \'network_interfaces\' not present in BareMetalServer JSON')
        if 'primary_network_interface' in _dict:
            args['primary_network_interface'] = NetworkInterfaceBareMetalServerContextReference.from_dict(_dict.get('primary_network_interface'))
        else:
            raise ValueError('Required property \'primary_network_interface\' not present in BareMetalServer JSON')
        if 'profile' in _dict:
            args['profile'] = BareMetalServerProfileReference.from_dict(_dict.get('profile'))
        else:
            raise ValueError('Required property \'profile\' not present in BareMetalServer 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 BareMetalServer JSON')
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError('Required property \'resource_type\' not present in BareMetalServer JSON')
        if 'status' in _dict:
            args['status'] = _dict.get('status')
        else:
            raise ValueError('Required property \'status\' not present in BareMetalServer JSON')
        if 'status_reasons' in _dict:
            args['status_reasons'] = [BareMetalServerStatusReason.from_dict(v) for v in _dict.get('status_reasons')]
        else:
            raise ValueError('Required property \'status_reasons\' not present in BareMetalServer JSON')
        if 'trusted_platform_module' in _dict:
            args['trusted_platform_module'] = BareMetalServerTrustedPlatformModule.from_dict(_dict.get('trusted_platform_module'))
        else:
            raise ValueError('Required property \'trusted_platform_module\' not present in BareMetalServer JSON')
        if 'vpc' in _dict:
            args['vpc'] = VPCReference.from_dict(_dict.get('vpc'))
        else:
            raise ValueError('Required property \'vpc\' not present in BareMetalServer JSON')
        if 'zone' in _dict:
            args['zone'] = ZoneReference.from_dict(_dict.get('zone'))
        else:
            raise ValueError('Required property \'zone\' not present in BareMetalServer JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a BareMetalServer object from 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_target') and self.boot_target is not None:
            if isinstance(self.boot_target, dict):
                _dict['boot_target'] = self.boot_target
            else:
                _dict['boot_target'] = self.boot_target.to_dict()
        if hasattr(self, 'cpu') and self.cpu is not None:
            if isinstance(self.cpu, dict):
                _dict['cpu'] = self.cpu
            else:
                _dict['cpu'] = self.cpu.to_dict()
        if hasattr(self, 'created_at') and self.created_at is not None:
            _dict['created_at'] = datetime_to_string(self.created_at)
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'disks') and self.disks is not None:
            disks_list = []
            for v in self.disks:
                if isinstance(v, dict):
                    disks_list.append(v)
                else:
                    disks_list.append(v.to_dict())
            _dict['disks'] = disks_list
        if hasattr(self, 'enable_secure_boot') and self.enable_secure_boot is not None:
            _dict['enable_secure_boot'] = self.enable_secure_boot
        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_reasons') and self.lifecycle_reasons is not None:
            lifecycle_reasons_list = []
            for v in self.lifecycle_reasons:
                if isinstance(v, dict):
                    lifecycle_reasons_list.append(v)
                else:
                    lifecycle_reasons_list.append(v.to_dict())
            _dict['lifecycle_reasons'] = lifecycle_reasons_list
        if hasattr(self, 'lifecycle_state') and self.lifecycle_state is not None:
            _dict['lifecycle_state'] = self.lifecycle_state
        if hasattr(self, 'memory') and self.memory is not None:
            _dict['memory'] = self.memory
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'network_interfaces') and self.network_interfaces is not None:
            network_interfaces_list = []
            for v in self.network_interfaces:
                if isinstance(v, dict):
                    network_interfaces_list.append(v)
                else:
                    network_interfaces_list.append(v.to_dict())
            _dict['network_interfaces'] = network_interfaces_list
        if hasattr(self, 'primary_network_interface') and self.primary_network_interface is not None:
            if isinstance(self.primary_network_interface, dict):
                _dict['primary_network_interface'] = self.primary_network_interface
            else:
                _dict['primary_network_interface'] = self.primary_network_interface.to_dict()
        if hasattr(self, 'profile') and self.profile is not None:
            if isinstance(self.profile, dict):
                _dict['profile'] = self.profile
            else:
                _dict['profile'] = self.profile.to_dict()
        if hasattr(self, 'resource_group') and self.resource_group is not None:
            if isinstance(self.resource_group, dict):
                _dict['resource_group'] = self.resource_group
            else:
                _dict['resource_group'] = self.resource_group.to_dict()
        if hasattr(self, '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, 'status_reasons') and self.status_reasons is not None:
            status_reasons_list = []
            for v in self.status_reasons:
                if isinstance(v, dict):
                    status_reasons_list.append(v)
                else:
                    status_reasons_list.append(v.to_dict())
            _dict['status_reasons'] = status_reasons_list
        if hasattr(self, 'trusted_platform_module') and self.trusted_platform_module is not None:
            if isinstance(self.trusted_platform_module, dict):
                _dict['trusted_platform_module'] = self.trusted_platform_module
            else:
                _dict['trusted_platform_module'] = self.trusted_platform_module.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, '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 BareMetalServer object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'BareMetalServer') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'BareMetalServer') -> 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 bare metal server.
        """

        DELETING = 'deleting'
        FAILED = 'failed'
        PENDING = 'pending'
        STABLE = 'stable'
        SUSPENDED = 'suspended'
        UPDATING = 'updating'
        WAITING = 'waiting'


    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        BARE_METAL_SERVER = 'bare_metal_server'


    class StatusEnum(str, Enum):
        """
        The status of the bare metal server.
        """

        DELETING = 'deleting'
        FAILED = 'failed'
        MAINTENANCE = 'maintenance'
        PENDING = 'pending'
        RESTARTING = 'restarting'
        RUNNING = 'running'
        STARTING = 'starting'
        STOPPED = 'stopped'
        STOPPING = 'stopping'



class BareMetalServerBootTarget:
    """
    The possible resource types for this property are expected to expand in the future.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a BareMetalServerBootTarget object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['BareMetalServerBootTargetBareMetalServerDiskReference'])
        )
        raise Exception(msg)


class BareMetalServerCPU:
    """
    The bare metal server CPU configuration.

    :attr str architecture: The CPU architecture.
    :attr int core_count: The total number of cores.
    :attr int socket_count: The total number of CPU sockets.
    :attr int threads_per_core: The total number of hardware threads per core.
    """

    def __init__(
        self,
        architecture: str,
        core_count: int,
        socket_count: int,
        threads_per_core: int,
    ) -> None:
        """
        Initialize a BareMetalServerCPU object.

        :param str architecture: The CPU architecture.
        :param int core_count: The total number of cores.
        :param int socket_count: The total number of CPU sockets.
        :param int threads_per_core: The total number of hardware threads per core.
        """
        self.architecture = architecture
        self.core_count = core_count
        self.socket_count = socket_count
        self.threads_per_core = threads_per_core

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'BareMetalServerCPU':
        """Initialize a BareMetalServerCPU object from a json dictionary."""
        args = {}
        if 'architecture' in _dict:
            args['architecture'] = _dict.get('architecture')
        else:
            raise ValueError('Required property \'architecture\' not present in BareMetalServerCPU JSON')
        if 'core_count' in _dict:
            args['core_count'] = _dict.get('core_count')
        else:
            raise ValueError('Required property \'core_count\' not present in BareMetalServerCPU JSON')
        if 'socket_count' in _dict:
            args['socket_count'] = _dict.get('socket_count')
        else:
            raise ValueError('Required property \'socket_count\' not present in BareMetalServerCPU JSON')
        if 'threads_per_core' in _dict:
            args['threads_per_core'] = _dict.get('threads_per_core')
        else:
            raise ValueError('Required property \'threads_per_core\' not present in BareMetalServerCPU JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a BareMetalServerCPU object from 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, 'core_count') and self.core_count is not None:
            _dict['core_count'] = self.core_count
        if hasattr(self, 'socket_count') and self.socket_count is not None:
            _dict['socket_count'] = self.socket_count
        if hasattr(self, 'threads_per_core') and self.threads_per_core is not None:
            _dict['threads_per_core'] = self.threads_per_core
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this BareMetalServerCPU object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'BareMetalServerCPU') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'BareMetalServerCPU') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class BareMetalServerCollection:
    """
    BareMetalServerCollection.

    :attr List[BareMetalServer] bare_metal_servers: Collection of bare metal
          servers.
    :attr BareMetalServerCollectionFirst 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 BareMetalServerCollectionNext 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,
        bare_metal_servers: List['BareMetalServer'],
        first: 'BareMetalServerCollectionFirst',
        limit: int,
        total_count: int,
        *,
        next: 'BareMetalServerCollectionNext' = None,
    ) -> None:
        """
        Initialize a BareMetalServerCollection object.

        :param List[BareMetalServer] bare_metal_servers: Collection of bare metal
               servers.
        :param BareMetalServerCollectionFirst 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 BareMetalServerCollectionNext next: (optional) A link to the next
               page of resources. This property is present for all pages
               except the last page.
        """
        self.bare_metal_servers = bare_metal_servers
        self.first = first
        self.limit = limit
        self.next = next
        self.total_count = total_count

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'BareMetalServerCollection':
        """Initialize a BareMetalServerCollection object from a json dictionary."""
        args = {}
        if 'bare_metal_servers' in _dict:
            args['bare_metal_servers'] = [BareMetalServer.from_dict(v) for v in _dict.get('bare_metal_servers')]
        else:
            raise ValueError('Required property \'bare_metal_servers\' not present in BareMetalServerCollection JSON')
        if 'first' in _dict:
            args['first'] = BareMetalServerCollectionFirst.from_dict(_dict.get('first'))
        else:
            raise ValueError('Required property \'first\' not present in BareMetalServerCollection JSON')
        if 'limit' in _dict:
            args['limit'] = _dict.get('limit')
        else:
            raise ValueError('Required property \'limit\' not present in BareMetalServerCollection JSON')
        if 'next' in _dict:
            args['next'] = BareMetalServerCollectionNext.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 BareMetalServerCollection JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a BareMetalServerCollection object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'bare_metal_servers') and self.bare_metal_servers is not None:
            bare_metal_servers_list = []
            for v in self.bare_metal_servers:
                if isinstance(v, dict):
                    bare_metal_servers_list.append(v)
                else:
                    bare_metal_servers_list.append(v.to_dict())
            _dict['bare_metal_servers'] = bare_metal_servers_list
        if hasattr(self, 'first') and self.first is not None:
            if isinstance(self.first, dict):
                _dict['first'] = self.first
            else:
                _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:
            if isinstance(self.next, dict):
                _dict['next'] = self.next
            else:
                _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 BareMetalServerCollection object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'BareMetalServerCollection') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'BareMetalServerCollection') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class BareMetalServerCollectionFirst:
    """
    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 BareMetalServerCollectionFirst object.

        :param str href: The URL for a page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'BareMetalServerCollectionFirst':
        """Initialize a BareMetalServerCollectionFirst object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in BareMetalServerCollectionFirst JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a BareMetalServerCollectionFirst object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(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 BareMetalServerCollectionFirst object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'BareMetalServerCollectionFirst') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'BareMetalServerCollectionFirst') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class BareMetalServerCollectionNext:
    """
    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 BareMetalServerCollectionNext object.

        :param str href: The URL for a page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'BareMetalServerCollectionNext':
        """Initialize a BareMetalServerCollectionNext object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in BareMetalServerCollectionNext JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a BareMetalServerCollectionNext object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(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 BareMetalServerCollectionNext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'BareMetalServerCollectionNext') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'BareMetalServerCollectionNext') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class BareMetalServerConsoleAccessToken:
    """
    The bare metal server console access token information.

    :attr str access_token: A URL safe single-use token used to access the console
          WebSocket.
    :attr str console_type: The bare metal server console type for which this token
          may be used.
    :attr datetime created_at: The date and time that the access token was created.
    :attr datetime expires_at: The date and time that the access token will expire.
    :attr bool force: Indicates whether to disconnect an existing serial console
          session as the serial console cannot be shared.  This has no effect on VNC
          consoles.
    :attr str href: The URL to access this bare metal server console.
    """

    def __init__(
        self,
        access_token: str,
        console_type: str,
        created_at: datetime,
        expires_at: datetime,
        force: bool,
        href: str,
    ) -> None:
        """
        Initialize a BareMetalServerConsoleAccessToken object.

        :param str access_token: A URL safe single-use token used to access the
               console WebSocket.
        :param str console_type: The bare metal server console type for which this
               token may be used.
        :param datetime created_at: The date and time that the access token was
               created.
        :param datetime expires_at: The date and time that the access token will
               expire.
        :param bool force: Indicates whether to disconnect an existing serial
               console session as the serial console cannot be shared.  This has no effect
               on VNC consoles.
        :param str href: The URL to access this bare metal server console.
        """
        self.access_token = access_token
        self.console_type = console_type
        self.created_at = created_at
        self.expires_at = expires_at
        self.force = force
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'BareMetalServerConsoleAccessToken':
        """Initialize a BareMetalServerConsoleAccessToken object from a json dictionary."""
        args = {}
        if 'access_token' in _dict:
            args['access_token'] = _dict.get('access_token')
        else:
            raise ValueError('Required property \'access_token\' not present in BareMetalServerConsoleAccessToken JSON')
        if 'console_type' in _dict:
            args['console_type'] = _dict.get('console_type')
        else:
            raise ValueError('Required property \'console_type\' not present in BareMetalServerConsoleAccessToken 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 BareMetalServerConsoleAccessToken JSON')
        if 'expires_at' in _dict:
            args['expires_at'] = string_to_datetime(_dict.get('expires_at'))
        else:
            raise ValueError('Required property \'expires_at\' not present in BareMetalServerConsoleAccessToken JSON')
        if 'force' in _dict:
            args['force'] = _dict.get('force')
        else:
            raise ValueError('Required property \'force\' not present in BareMetalServerConsoleAccessToken JSON')
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in BareMetalServerConsoleAccessToken JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a BareMetalServerConsoleAccessToken object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'access_token') and self.access_token is not None:
            _dict['access_token'] = self.access_token
        if hasattr(self, 'console_type') and self.console_type is not None:
            _dict['console_type'] = self.console_type
        if hasattr(self, 'created_at') and self.created_at is not None:
            _dict['created_at'] = datetime_to_string(self.created_at)
        if hasattr(self, 'expires_at') and self.expires_at is not None:
            _dict['expires_at'] = datetime_to_string(self.expires_at)
        if hasattr(self, 'force') and self.force is not None:
            _dict['force'] = self.force
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this BareMetalServerConsoleAccessToken object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'BareMetalServerConsoleAccessToken') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'BareMetalServerConsoleAccessToken') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ConsoleTypeEnum(str, Enum):
        """
        The bare metal server console type for which this token may be used.
        """

        SERIAL = 'serial'
        VNC = 'vnc'



class BareMetalServerDisk:
    """
    BareMetalServerDisk.

    :attr datetime created_at: The date and time that the disk was created.
    :attr str href: The URL for this bare metal server disk.
    :attr str id: The unique identifier for this bare metal server disk.
    :attr str interface_type: The disk interface used for attaching the disk.
          - `fcp`: Attached using Fiber Channel Protocol
          - `sata`: Attached using Serial Advanced Technology Attachment
          - `nvme`: Attached using Non-Volatile Memory Express
          The enumerated values for this property are expected to expand in the future.
          When processing this property, check for and log unknown values. Optionally halt
          processing and surface the error, or bypass the resource on which the unexpected
          property value was encountered.
    :attr str name: The name for this bare metal server disk. The name is unique
          across all disks on the bare metal server.
    :attr str resource_type: The resource type.
    :attr int size: The size of the disk in GB (gigabytes).
    """

    def __init__(
        self,
        created_at: datetime,
        href: str,
        id: str,
        interface_type: str,
        name: str,
        resource_type: str,
        size: int,
    ) -> None:
        """
        Initialize a BareMetalServerDisk object.

        :param datetime created_at: The date and time that the disk was created.
        :param str href: The URL for this bare metal server disk.
        :param str id: The unique identifier for this bare metal server disk.
        :param str interface_type: The disk interface used for attaching the disk.
               - `fcp`: Attached using Fiber Channel Protocol
               - `sata`: Attached using Serial Advanced Technology Attachment
               - `nvme`: Attached using Non-Volatile Memory Express
               The enumerated values for this property are expected to expand in the
               future. When processing this property, check for and log unknown values.
               Optionally halt processing and surface the error, or bypass the resource on
               which the unexpected property value was encountered.
        :param str name: The name for this bare metal server disk. The name is
               unique across all disks on the bare metal server.
        :param str resource_type: The resource type.
        :param int size: The size of the disk in GB (gigabytes).
        """
        self.created_at = created_at
        self.href = href
        self.id = id
        self.interface_type = interface_type
        self.name = name
        self.resource_type = resource_type
        self.size = size

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'BareMetalServerDisk':
        """Initialize a BareMetalServerDisk 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 BareMetalServerDisk JSON')
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in BareMetalServerDisk JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in BareMetalServerDisk JSON')
        if 'interface_type' in _dict:
            args['interface_type'] = _dict.get('interface_type')
        else:
            raise ValueError('Required property \'interface_type\' not present in BareMetalServerDisk JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in BareMetalServerDisk JSON')
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError('Required property \'resource_type\' not present in BareMetalServerDisk JSON')
        if 'size' in _dict:
            args['size'] = _dict.get('size')
        else:
            raise ValueError('Required property \'size\' not present in BareMetalServerDisk JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a BareMetalServerDisk object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'created_at') and self.created_at is not None:
            _dict['created_at'] = datetime_to_string(self.created_at)
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'interface_type') and self.interface_type is not None:
            _dict['interface_type'] = self.interface_type
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'resource_type') and self.resource_type is not None:
            _dict['resource_type'] = self.resource_type
        if hasattr(self, 'size') and self.size is not None:
            _dict['size'] = self.size
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this BareMetalServerDisk object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'BareMetalServerDisk') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'BareMetalServerDisk') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class InterfaceTypeEnum(str, Enum):
        """
        The disk interface used for attaching the disk.
        - `fcp`: Attached using Fiber Channel Protocol
        - `sata`: Attached using Serial Advanced Technology Attachment
        - `nvme`: Attached using Non-Volatile Memory Express
        The enumerated values for this property are expected to expand in the future. When
        processing this property, check for and log unknown values. Optionally halt
        processing and surface the error, or bypass the resource on which the unexpected
        property value was encountered.
        """

        FCP = 'fcp'
        NVME = 'nvme'
        SATA = 'sata'


    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        BARE_METAL_SERVER_DISK = 'bare_metal_server_disk'



class BareMetalServerDiskCollection:
    """
    BareMetalServerDiskCollection.

    :attr List[BareMetalServerDisk] disks: Collection of the bare metal server's
          disks.
    """

    def __init__(
        self,
        disks: List['BareMetalServerDisk'],
    ) -> None:
        """
        Initialize a BareMetalServerDiskCollection object.

        :param List[BareMetalServerDisk] disks: Collection of the bare metal
               server's disks.
        """
        self.disks = disks

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'BareMetalServerDiskCollection':
        """Initialize a BareMetalServerDiskCollection object from a json dictionary."""
        args = {}
        if 'disks' in _dict:
            args['disks'] = [BareMetalServerDisk.from_dict(v) for v in _dict.get('disks')]
        else:
            raise ValueError('Required property \'disks\' not present in BareMetalServerDiskCollection JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a BareMetalServerDiskCollection object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'disks') and self.disks is not None:
            disks_list = []
            for v in self.disks:
                if isinstance(v, dict):
                    disks_list.append(v)
                else:
                    disks_list.append(v.to_dict())
            _dict['disks'] = disks_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 BareMetalServerDiskCollection object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'BareMetalServerDiskCollection') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'BareMetalServerDiskCollection') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class BareMetalServerDiskPatch:
    """
    BareMetalServerDiskPatch.

    :attr str name: (optional) The name for this bare metal server disk. The name
          must not be used by another disk on the bare metal server.
    """

    def __init__(
        self,
        *,
        name: str = None,
    ) -> None:
        """
        Initialize a BareMetalServerDiskPatch object.

        :param str name: (optional) The name for this bare metal server disk. The
               name must not be used by another disk on the bare metal server.
        """
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'BareMetalServerDiskPatch':
        """Initialize a BareMetalServerDiskPatch 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 BareMetalServerDiskPatch object from 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 BareMetalServerDiskPatch object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'BareMetalServerDiskPatch') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'BareMetalServerDiskPatch') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class BareMetalServerDiskReferenceDeleted:
    """
    If present, this property indicates the referenced resource has been deleted, and
    provides some supplementary information.

    :attr str more_info: Link to documentation about deleted resources.
    """

    def __init__(
        self,
        more_info: str,
    ) -> None:
        """
        Initialize a BareMetalServerDiskReferenceDeleted object.

        :param str more_info: Link to documentation about deleted resources.
        """
        self.more_info = more_info

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'BareMetalServerDiskReferenceDeleted':
        """Initialize a BareMetalServerDiskReferenceDeleted object from a json dictionary."""
        args = {}
        if 'more_info' in _dict:
            args['more_info'] = _dict.get('more_info')
        else:
            raise ValueError('Required property \'more_info\' not present in BareMetalServerDiskReferenceDeleted JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a BareMetalServerDiskReferenceDeleted object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'more_info') and self.more_info is not None:
            _dict['more_info'] = self.more_info
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this BareMetalServerDiskReferenceDeleted object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'BareMetalServerDiskReferenceDeleted') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'BareMetalServerDiskReferenceDeleted') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class BareMetalServerInitialization:
    """
    BareMetalServerInitialization.

    :attr ImageReference image: The image the bare metal server was provisioned
          from.
    :attr List[KeyReference] keys: The public SSH keys used at initialization.
    :attr List[BareMetalServerInitializationUserAccount] user_accounts: The user
          accounts that are created at initialization. There can be multiple account types
          distinguished by the `resource_type` property.
    """

    def __init__(
        self,
        image: 'ImageReference',
        keys: List['KeyReference'],
        user_accounts: List['BareMetalServerInitializationUserAccount'],
    ) -> None:
        """
        Initialize a BareMetalServerInitialization object.

        :param ImageReference image: The image the bare metal server was
               provisioned from.
        :param List[KeyReference] keys: The public SSH keys used at initialization.
        :param List[BareMetalServerInitializationUserAccount] user_accounts: The
               user accounts that are created at initialization. There can be multiple
               account types distinguished by the `resource_type` property.
        """
        self.image = image
        self.keys = keys
        self.user_accounts = user_accounts

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'BareMetalServerInitialization':
        """Initialize a BareMetalServerInitialization object from a json dictionary."""
        args = {}
        if 'image' in _dict:
            args['image'] = ImageReference.from_dict(_dict.get('image'))
        else:
            raise ValueError('Required property \'image\' not present in BareMetalServerInitialization JSON')
        if 'keys' in _dict:
            args['keys'] = [KeyReference.from_dict(v) for v in _dict.get('keys')]
        else:
            raise ValueError('Required property \'keys\' not present in BareMetalServerInitialization JSON')
        if 'user_accounts' in _dict:
            args['user_accounts'] = _dict.get('user_accounts')
        else:
            raise ValueError('Required property \'user_accounts\' not present in BareMetalServerInitialization JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a BareMetalServerInitialization object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _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, 'keys') and self.keys is not None:
            keys_list = []
            for v in self.keys:
                if isinstance(v, dict):
                    keys_list.append(v)
                else:
                    keys_list.append(v.to_dict())
            _dict['keys'] = keys_list
        if hasattr(self, 'user_accounts') and self.user_accounts is not None:
            user_accounts_list = []
            for v in self.user_accounts:
                if isinstance(v, dict):
                    user_accounts_list.append(v)
                else:
                    user_accounts_list.append(v.to_dict())
            _dict['user_accounts'] = user_accounts_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 BareMetalServerInitialization object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'BareMetalServerInitialization') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'BareMetalServerInitialization') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class BareMetalServerInitializationPrototype:
    """
    BareMetalServerInitializationPrototype.

    :attr ImageIdentity image: The image to be used when provisioning the bare metal
          server.
    :attr List[KeyIdentity] keys: The public SSH keys to install on the bare metal
          server. Keys will be made available to the bare metal server as cloud-init
          vendor data. For cloud-init enabled images, these keys will also be added as SSH
          authorized keys for the administrative user.
          For Windows images, at least one key must be specified, and one will be selected
          to encrypt the administrator password. Keys are optional for other images, but
          if no keys are specified, the instance will be inaccessible unless the specified
          image provides another means of access.
    :attr str user_data: (optional) User data to be made available when initializing
          the bare metal server.
    """

    def __init__(
        self,
        image: 'ImageIdentity',
        keys: List['KeyIdentity'],
        *,
        user_data: str = None,
    ) -> None:
        """
        Initialize a BareMetalServerInitializationPrototype object.

        :param ImageIdentity image: The image to be used when provisioning the bare
               metal server.
        :param List[KeyIdentity] keys: The public SSH keys to install on the bare
               metal server. Keys will be made available to the bare metal server as
               cloud-init vendor data. For cloud-init enabled images, these keys will also
               be added as SSH authorized keys for the administrative user.
               For Windows images, at least one key must be specified, and one will be
               selected to encrypt the administrator password. Keys are optional for other
               images, but if no keys are specified, the instance will be inaccessible
               unless the specified image provides another means of access.
        :param str user_data: (optional) User data to be made available when
               initializing the bare metal server.
        """
        self.image = image
        self.keys = keys
        self.user_data = user_data

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'BareMetalServerInitializationPrototype':
        """Initialize a BareMetalServerInitializationPrototype object from a json dictionary."""
        args = {}
        if 'image' in _dict:
            args['image'] = _dict.get('image')
        else:
            raise ValueError('Required property \'image\' not present in BareMetalServerInitializationPrototype JSON')
        if 'keys' in _dict:
            args['keys'] = _dict.get('keys')
        else:
            raise ValueError('Required property \'keys\' not present in BareMetalServerInitializationPrototype JSON')
        if 'user_data' in _dict:
            args['user_data'] = _dict.get('user_data')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a BareMetalServerInitializationPrototype object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _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, 'keys') and self.keys is not None:
            keys_list = []
            for v in self.keys:
                if isinstance(v, dict):
                    keys_list.append(v)
                else:
                    keys_list.append(v.to_dict())
            _dict['keys'] = keys_list
        if hasattr(self, 'user_data') and self.user_data is not None:
            _dict['user_data'] = self.user_data
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this BareMetalServerInitializationPrototype object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'BareMetalServerInitializationPrototype') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'BareMetalServerInitializationPrototype') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class BareMetalServerInitializationUserAccount:
    """
    BareMetalServerInitializationUserAccount.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a BareMetalServerInitializationUserAccount object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['BareMetalServerInitializationUserAccountBareMetalServerInitializationHostUserAccount'])
        )
        raise Exception(msg)


class BareMetalServerLifecycleReason:
    """
    BareMetalServerLifecycleReason.

    :attr str code: A snake case string succinctly identifying the reason for this
          lifecycle state.
    :attr str message: An explanation of the reason for this lifecycle state.
    :attr str more_info: (optional) Link to documentation about the reason for this
          lifecycle state.
    """

    def __init__(
        self,
        code: str,
        message: str,
        *,
        more_info: str = None,
    ) -> None:
        """
        Initialize a BareMetalServerLifecycleReason object.

        :param str code: A snake case string succinctly identifying the reason for
               this lifecycle state.
        :param str message: An explanation of the reason for this lifecycle state.
        :param str more_info: (optional) Link to documentation about the reason for
               this lifecycle state.
        """
        self.code = code
        self.message = message
        self.more_info = more_info

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'BareMetalServerLifecycleReason':
        """Initialize a BareMetalServerLifecycleReason object from a json dictionary."""
        args = {}
        if 'code' in _dict:
            args['code'] = _dict.get('code')
        else:
            raise ValueError('Required property \'code\' not present in BareMetalServerLifecycleReason JSON')
        if 'message' in _dict:
            args['message'] = _dict.get('message')
        else:
            raise ValueError('Required property \'message\' not present in BareMetalServerLifecycleReason JSON')
        if 'more_info' in _dict:
            args['more_info'] = _dict.get('more_info')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a BareMetalServerLifecycleReason object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'code') and self.code is not None:
            _dict['code'] = self.code
        if hasattr(self, 'message') and self.message is not None:
            _dict['message'] = self.message
        if hasattr(self, 'more_info') and self.more_info is not None:
            _dict['more_info'] = self.more_info
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this BareMetalServerLifecycleReason object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'BareMetalServerLifecycleReason') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'BareMetalServerLifecycleReason') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class CodeEnum(str, Enum):
        """
        A snake case string succinctly identifying the reason for this lifecycle state.
        """

        RESOURCE_SUSPENDED_BY_PROVIDER = 'resource_suspended_by_provider'



class BareMetalServerNetworkInterface:
    """
    BareMetalServerNetworkInterface.

    :attr bool allow_ip_spoofing: Indicates whether source IP spoofing is allowed on
          this bare metal server network interface.
    :attr datetime created_at: The date and time that the bare metal server network
          interface was created.
    :attr bool enable_infrastructure_nat: If `true`:
          - The VPC infrastructure performs any needed NAT operations.
          - `floating_ips` must not have more than one floating IP.
          If `false`:
          - Packets are passed unchanged to/from the bare metal server network interface,
            allowing the workload to perform any needed NAT operations.
          - `allow_ip_spoofing` must be `false`.
          - `interface_type` must not be `hipersocket`.
    :attr List[FloatingIPReference] floating_ips: The floating IPs associated with
          this bare metal server network interface.
    :attr str href: The URL for this bare metal server network interface.
    :attr str id: The unique identifier for this bare metal server network
          interface.
    :attr str interface_type: The interface type:
          - `hipersocket`: a virtual device that provides high-speed TCP/IP connectivity
            within a `s390x` based system
          - `pci`: a physical PCI device which can only be created or deleted when the
          bare metal
            server is stopped
            - Has an `allowed_vlans` property which controls the VLANs that will be
          permitted
              to use the PCI interface
            - Cannot directly use an IEEE 802.1Q tag.
          - `vlan`: a virtual device, used through a `pci` device that has the `vlan` in
          its
            array of `allowed_vlans`.
            - Must use an IEEE 802.1Q tag.
            - Has its own security groups and does not inherit those of the PCI device
          through
              which traffic flows.
          The enumerated values for this property are expected to expand in the future.
          When processing this property, check for and log unknown values. Optionally halt
          processing and surface the error, or bypass the resource on which the unexpected
          property value was encountered.
    :attr str mac_address: The MAC address of this bare metal server network
          interface. If the MAC address has not yet been selected, the value will be an
          empty string.
    :attr str name: The name for this bare metal server network interface.
    :attr int port_speed: The bare metal server network interface port speed in
          Mbps.
    :attr ReservedIPReference primary_ip:
    :attr str resource_type: The resource type.
    :attr List[SecurityGroupReference] security_groups: The security groups
          targeting this bare metal server network interface.
    :attr str status: The status of the bare metal server network interface.
    :attr SubnetReference subnet: The associated subnet.
    :attr str type: The bare metal server network interface type.
    """

    def __init__(
        self,
        allow_ip_spoofing: bool,
        created_at: datetime,
        enable_infrastructure_nat: bool,
        floating_ips: List['FloatingIPReference'],
        href: str,
        id: str,
        interface_type: str,
        mac_address: str,
        name: str,
        port_speed: int,
        primary_ip: 'ReservedIPReference',
        resource_type: str,
        security_groups: List['SecurityGroupReference'],
        status: str,
        subnet: 'SubnetReference',
        type: str,
    ) -> None:
        """
        Initialize a BareMetalServerNetworkInterface object.

        :param bool allow_ip_spoofing: Indicates whether source IP spoofing is
               allowed on this bare metal server network interface.
        :param datetime created_at: The date and time that the bare metal server
               network interface was created.
        :param bool enable_infrastructure_nat: If `true`:
               - The VPC infrastructure performs any needed NAT operations.
               - `floating_ips` must not have more than one floating IP.
               If `false`:
               - Packets are passed unchanged to/from the bare metal server network
               interface,
                 allowing the workload to perform any needed NAT operations.
               - `allow_ip_spoofing` must be `false`.
               - `interface_type` must not be `hipersocket`.
        :param List[FloatingIPReference] floating_ips: The floating IPs associated
               with this bare metal server network interface.
        :param str href: The URL for this bare metal server network interface.
        :param str id: The unique identifier for this bare metal server network
               interface.
        :param str interface_type: The interface type:
               - `hipersocket`: a virtual device that provides high-speed TCP/IP
               connectivity
                 within a `s390x` based system
               - `pci`: a physical PCI device which can only be created or deleted when
               the bare metal
                 server is stopped
                 - Has an `allowed_vlans` property which controls the VLANs that will be
               permitted
                   to use the PCI interface
                 - Cannot directly use an IEEE 802.1Q tag.
               - `vlan`: a virtual device, used through a `pci` device that has the `vlan`
               in its
                 array of `allowed_vlans`.
                 - Must use an IEEE 802.1Q tag.
                 - Has its own security groups and does not inherit those of the PCI
               device through
                   which traffic flows.
               The enumerated values for this property are expected to expand in the
               future. When processing this property, check for and log unknown values.
               Optionally halt processing and surface the error, or bypass the resource on
               which the unexpected property value was encountered.
        :param str mac_address: The MAC address of this bare metal server network
               interface. If the MAC address has not yet been selected, the value will be
               an empty string.
        :param str name: The name for this bare metal server network interface.
        :param int port_speed: The bare metal server network interface port speed
               in Mbps.
        :param ReservedIPReference primary_ip:
        :param str resource_type: The resource type.
        :param List[SecurityGroupReference] security_groups: The security groups
               targeting this bare metal server network interface.
        :param str status: The status of the bare metal server network interface.
        :param SubnetReference subnet: The associated subnet.
        :param str type: The bare metal server network interface type.
        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['BareMetalServerNetworkInterfaceByHiperSocket', 'BareMetalServerNetworkInterfaceByPCI', 'BareMetalServerNetworkInterfaceByVLAN'])
        )
        raise Exception(msg)

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'BareMetalServerNetworkInterface':
        """Initialize a BareMetalServerNetworkInterface 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 'BareMetalServerNetworkInterface'. The discriminator value should map to a valid subclass: {1}".format(
            ", ".join(['BareMetalServerNetworkInterfaceByHiperSocket', 'BareMetalServerNetworkInterfaceByPCI', 'BareMetalServerNetworkInterfaceByVLAN'])
        )
        raise Exception(msg)

    @classmethod
    def _from_dict(cls, _dict: Dict):
        """Initialize a BareMetalServerNetworkInterface object from a json dictionary."""
        return cls.from_dict(_dict)

    @classmethod
    def _get_class_by_discriminator(cls, _dict: Dict) -> object:
        mapping = {}
        mapping['hipersocket'] = 'BareMetalServerNetworkInterfaceByHiperSocket'
        mapping['pci'] = 'BareMetalServerNetworkInterfaceByPCI'
        mapping['vlan'] = 'BareMetalServerNetworkInterfaceByVLAN'
        disc_value = _dict.get('interface_type')
        if disc_value is None:
            raise ValueError('Discriminator property \'interface_type\' not found in BareMetalServerNetworkInterface 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 InterfaceTypeEnum(str, Enum):
        """
        The interface type:
        - `hipersocket`: a virtual device that provides high-speed TCP/IP connectivity
          within a `s390x` based system
        - `pci`: a physical PCI device which can only be created or deleted when the bare
        metal
          server is stopped
          - Has an `allowed_vlans` property which controls the VLANs that will be
        permitted
            to use the PCI interface
          - Cannot directly use an IEEE 802.1Q tag.
        - `vlan`: a virtual device, used through a `pci` device that has the `vlan` in its
          array of `allowed_vlans`.
          - Must use an IEEE 802.1Q tag.
          - Has its own security groups and does not inherit those of the PCI device
        through
            which traffic flows.
        The enumerated values for this property are expected to expand in the future. When
        processing this property, check for and log unknown values. Optionally halt
        processing and surface the error, or bypass the resource on which the unexpected
        property value was encountered.
        """

        HIPERSOCKET = 'hipersocket'
        PCI = 'pci'
        VLAN = 'vlan'


    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        NETWORK_INTERFACE = 'network_interface'


    class StatusEnum(str, Enum):
        """
        The status of the bare metal server network interface.
        """

        AVAILABLE = 'available'
        DELETING = 'deleting'
        FAILED = 'failed'
        PENDING = 'pending'


    class TypeEnum(str, Enum):
        """
        The bare metal server network interface type.
        """

        PRIMARY = 'primary'
        SECONDARY = 'secondary'



class BareMetalServerNetworkInterfaceCollection:
    """
    BareMetalServerNetworkInterfaceCollection.

    :attr BareMetalServerNetworkInterfaceCollectionFirst 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[BareMetalServerNetworkInterface] network_interfaces: Collection of
          bare metal server network interfaces.
    :attr BareMetalServerNetworkInterfaceCollectionNext 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: 'BareMetalServerNetworkInterfaceCollectionFirst',
        limit: int,
        network_interfaces: List['BareMetalServerNetworkInterface'],
        total_count: int,
        *,
        next: 'BareMetalServerNetworkInterfaceCollectionNext' = None,
    ) -> None:
        """
        Initialize a BareMetalServerNetworkInterfaceCollection object.

        :param BareMetalServerNetworkInterfaceCollectionFirst 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[BareMetalServerNetworkInterface] network_interfaces: Collection
               of bare metal server network interfaces.
        :param int total_count: The total number of resources across all pages.
        :param BareMetalServerNetworkInterfaceCollectionNext next: (optional) A
               link to the next page of resources. This property is present for all pages
               except the last page.
        """
        self.first = first
        self.limit = limit
        self.network_interfaces = network_interfaces
        self.next = next
        self.total_count = total_count

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'BareMetalServerNetworkInterfaceCollection':
        """Initialize a BareMetalServerNetworkInterfaceCollection object from a json dictionary."""
        args = {}
        if 'first' in _dict:
            args['first'] = BareMetalServerNetworkInterfaceCollectionFirst.from_dict(_dict.get('first'))
        else:
            raise ValueError('Required property \'first\' not present in BareMetalServerNetworkInterfaceCollection JSON')
        if 'limit' in _dict:
            args['limit'] = _dict.get('limit')
        else:
            raise ValueError('Required property \'limit\' not present in BareMetalServerNetworkInterfaceCollection JSON')
        if 'network_interfaces' in _dict:
            args['network_interfaces'] = [BareMetalServerNetworkInterface.from_dict(v) for v in _dict.get('network_interfaces')]
        else:
            raise ValueError('Required property \'network_interfaces\' not present in BareMetalServerNetworkInterfaceCollection JSON')
        if 'next' in _dict:
            args['next'] = BareMetalServerNetworkInterfaceCollectionNext.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 BareMetalServerNetworkInterfaceCollection JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a BareMetalServerNetworkInterfaceCollection object from 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:
            if isinstance(self.first, dict):
                _dict['first'] = self.first
            else:
                _dict['first'] = self.first.to_dict()
        if hasattr(self, 'limit') and self.limit is not None:
            _dict['limit'] = self.limit
        if hasattr(self, 'network_interfaces') and self.network_interfaces is not None:
            network_interfaces_list = []
            for v in self.network_interfaces:
                if isinstance(v, dict):
                    network_interfaces_list.append(v)
                else:
                    network_interfaces_list.append(v.to_dict())
            _dict['network_interfaces'] = network_interfaces_list
        if hasattr(self, 'next') and self.next is not None:
            if isinstance(self.next, dict):
                _dict['next'] = self.next
            else:
                _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 BareMetalServerNetworkInterfaceCollection object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'BareMetalServerNetworkInterfaceCollection') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'BareMetalServerNetworkInterfaceCollection') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class BareMetalServerNetworkInterfaceCollectionFirst:
    """
    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 BareMetalServerNetworkInterfaceCollectionFirst object.

        :param str href: The URL for a page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'BareMetalServerNetworkInterfaceCollectionFirst':
        """Initialize a BareMetalServerNetworkInterfaceCollectionFirst object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in BareMetalServerNetworkInterfaceCollectionFirst JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a BareMetalServerNetworkInterfaceCollectionFirst object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(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 BareMetalServerNetworkInterfaceCollectionFirst object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'BareMetalServerNetworkInterfaceCollectionFirst') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'BareMetalServerNetworkInterfaceCollectionFirst') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class BareMetalServerNetworkInterfaceCollectionNext:
    """
    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 BareMetalServerNetworkInterfaceCollectionNext object.

        :param str href: The URL for a page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'BareMetalServerNetworkInterfaceCollectionNext':
        """Initialize a BareMetalServerNetworkInterfaceCollectionNext object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in BareMetalServerNetworkInterfaceCollectionNext JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a BareMetalServerNetworkInterfaceCollectionNext object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(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 BareMetalServerNetworkInterfaceCollectionNext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'BareMetalServerNetworkInterfaceCollectionNext') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'BareMetalServerNetworkInterfaceCollectionNext') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class BareMetalServerNetworkInterfacePatch:
    """
    BareMetalServerNetworkInterfacePatch.

    :attr bool allow_ip_spoofing: (optional) Indicates whether source IP spoofing is
          allowed on this bare metal server network interface.
    :attr List[int] allowed_vlans: (optional) The VLAN IDs to allow for `vlan`
          interfaces using this PCI interface, replacing any existing VLAN IDs. The
          specified values must include IDs for all `vlan` interfaces currently using this
          PCI interface.
    :attr bool enable_infrastructure_nat: (optional) If `true`:
          - The VPC infrastructure performs any needed NAT operations.
          - `floating_ips` must not have more than one floating IP.
          If `false`:
          - Packets are passed unchanged to/from the bare metal server network interface,
            allowing the workload to perform any needed NAT operations.
          - `allow_ip_spoofing` must be `false`.
          - `interface_type` must not be `hipersocket`.
    :attr str name: (optional) The name for this bare metal server network
          interface. The name must not be used by another network interface on the bare
          metal server.
    """

    def __init__(
        self,
        *,
        allow_ip_spoofing: bool = None,
        allowed_vlans: List[int] = None,
        enable_infrastructure_nat: bool = None,
        name: str = None,
    ) -> None:
        """
        Initialize a BareMetalServerNetworkInterfacePatch object.

        :param bool allow_ip_spoofing: (optional) Indicates whether source IP
               spoofing is allowed on this bare metal server network interface.
        :param List[int] allowed_vlans: (optional) The VLAN IDs to allow for `vlan`
               interfaces using this PCI interface, replacing any existing VLAN IDs. The
               specified values must include IDs for all `vlan` interfaces currently using
               this PCI interface.
        :param bool enable_infrastructure_nat: (optional) If `true`:
               - The VPC infrastructure performs any needed NAT operations.
               - `floating_ips` must not have more than one floating IP.
               If `false`:
               - Packets are passed unchanged to/from the bare metal server network
               interface,
                 allowing the workload to perform any needed NAT operations.
               - `allow_ip_spoofing` must be `false`.
               - `interface_type` must not be `hipersocket`.
        :param str name: (optional) The name for this bare metal server network
               interface. The name must not be used by another network interface on the
               bare metal server.
        """
        self.allow_ip_spoofing = allow_ip_spoofing
        self.allowed_vlans = allowed_vlans
        self.enable_infrastructure_nat = enable_infrastructure_nat
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'BareMetalServerNetworkInterfacePatch':
        """Initialize a BareMetalServerNetworkInterfacePatch object from a json dictionary."""
        args = {}
        if 'allow_ip_spoofing' in _dict:
            args['allow_ip_spoofing'] = _dict.get('allow_ip_spoofing')
        if 'allowed_vlans' in _dict:
            args['allowed_vlans'] = _dict.get('allowed_vlans')
        if 'enable_infrastructure_nat' in _dict:
            args['enable_infrastructure_nat'] = _dict.get('enable_infrastructure_nat')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a BareMetalServerNetworkInterfacePatch object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'allow_ip_spoofing') and self.allow_ip_spoofing is not None:
            _dict['allow_ip_spoofing'] = self.allow_ip_spoofing
        if hasattr(self, 'allowed_vlans') and self.allowed_vlans is not None:
            _dict['allowed_vlans'] = self.allowed_vlans
        if hasattr(self, 'enable_infrastructure_nat') and self.enable_infrastructure_nat is not None:
            _dict['enable_infrastructure_nat'] = self.enable_infrastructure_nat
        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 BareMetalServerNetworkInterfacePatch object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'BareMetalServerNetworkInterfacePatch') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'BareMetalServerNetworkInterfacePatch') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class BareMetalServerNetworkInterfacePrototype:
    """
    BareMetalServerNetworkInterfacePrototype.

    :attr bool allow_ip_spoofing: (optional) Indicates whether source IP spoofing is
          allowed on this bare metal server network interface.
    :attr bool enable_infrastructure_nat: (optional) If `true`:
          - The VPC infrastructure performs any needed NAT operations.
          - `floating_ips` must not have more than one floating IP.
          If `false`:
          - Packets are passed unchanged to/from the bare metal server network interface,
            allowing the workload to perform any needed NAT operations.
          - `allow_ip_spoofing` must be `false`.
          - `interface_type` must not be `hipersocket`.
    :attr str interface_type: The interface type:
          - `hipersocket`: a virtual device that provides high-speed TCP/IP connectivity
            within a `s390x` based system
            - Not supported on bare metal servers with a `cpu.architecture` of `amd64`
          - `pci`: a physical PCI device which can only be created or deleted when the
          bare metal
            server is stopped
            - Has an `allowed_vlans` property which controls the VLANs that will be
          permitted
              to use the PCI interface
            - Cannot directly use an IEEE 802.1Q tag.
            - Not supported on bare metal servers with a `cpu.architecture` of `s390x`
          - `vlan`: a virtual device, used through a `pci` device that has the `vlan` in
          its
            array of `allowed_vlans`.
            - Must use an IEEE 802.1Q tag.
            - Has its own security groups and does not inherit those of the PCI device
          through
              which traffic flows.
            - Not supported on bare metal servers with a `cpu.architecture` of `s390x`.
    :attr str name: (optional) The name for this bare metal server network
          interface. The name must not be used by another network interface on the bare
          metal server. If unspecified, the name will be a hyphenated list of
          randomly-selected words.
    :attr NetworkInterfaceIPPrototype primary_ip: (optional) The primary IP address
          to bind to the bare metal server network interface. This can be
          specified using an existing reserved IP, or a prototype object for a new
          reserved IP.
          If an existing reserved IP or a prototype object with an address is specified,
          it must
          be available on the bare metal server network interface's subnet. Otherwise, an
          available address on the subnet will be automatically selected and reserved.
    :attr List[SecurityGroupIdentity] security_groups: (optional) The security
          groups to use for this bare metal server network interface. If unspecified, the
          VPC's default security group is used.
    :attr SubnetIdentity subnet: The associated subnet.
    """

    def __init__(
        self,
        interface_type: str,
        subnet: 'SubnetIdentity',
        *,
        allow_ip_spoofing: bool = None,
        enable_infrastructure_nat: bool = None,
        name: str = None,
        primary_ip: 'NetworkInterfaceIPPrototype' = None,
        security_groups: List['SecurityGroupIdentity'] = None,
    ) -> None:
        """
        Initialize a BareMetalServerNetworkInterfacePrototype object.

        :param str interface_type: The interface type:
               - `hipersocket`: a virtual device that provides high-speed TCP/IP
               connectivity
                 within a `s390x` based system
                 - Not supported on bare metal servers with a `cpu.architecture` of
               `amd64`
               - `pci`: a physical PCI device which can only be created or deleted when
               the bare metal
                 server is stopped
                 - Has an `allowed_vlans` property which controls the VLANs that will be
               permitted
                   to use the PCI interface
                 - Cannot directly use an IEEE 802.1Q tag.
                 - Not supported on bare metal servers with a `cpu.architecture` of
               `s390x`
               - `vlan`: a virtual device, used through a `pci` device that has the `vlan`
               in its
                 array of `allowed_vlans`.
                 - Must use an IEEE 802.1Q tag.
                 - Has its own security groups and does not inherit those of the PCI
               device through
                   which traffic flows.
                 - Not supported on bare metal servers with a `cpu.architecture` of
               `s390x`.
        :param SubnetIdentity subnet: The associated subnet.
        :param bool allow_ip_spoofing: (optional) Indicates whether source IP
               spoofing is allowed on this bare metal server network interface.
        :param bool enable_infrastructure_nat: (optional) If `true`:
               - The VPC infrastructure performs any needed NAT operations.
               - `floating_ips` must not have more than one floating IP.
               If `false`:
               - Packets are passed unchanged to/from the bare metal server network
               interface,
                 allowing the workload to perform any needed NAT operations.
               - `allow_ip_spoofing` must be `false`.
               - `interface_type` must not be `hipersocket`.
        :param str name: (optional) The name for this bare metal server network
               interface. The name must not be used by another network interface on the
               bare metal server. If unspecified, the name will be a hyphenated list of
               randomly-selected words.
        :param NetworkInterfaceIPPrototype primary_ip: (optional) The primary IP
               address to bind to the bare metal server network interface. This can be
               specified using an existing reserved IP, or a prototype object for a new
               reserved IP.
               If an existing reserved IP or a prototype object with an address is
               specified, it must
               be available on the bare metal server network interface's subnet.
               Otherwise, an
               available address on the subnet will be automatically selected and
               reserved.
        :param List[SecurityGroupIdentity] security_groups: (optional) The security
               groups to use for this bare metal server network interface. If unspecified,
               the VPC's default security group is used.
        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['BareMetalServerNetworkInterfacePrototypeBareMetalServerNetworkInterfaceByHiperSocketPrototype', 'BareMetalServerNetworkInterfacePrototypeBareMetalServerNetworkInterfaceByPCIPrototype', 'BareMetalServerNetworkInterfacePrototypeBareMetalServerNetworkInterfaceByVLANPrototype'])
        )
        raise Exception(msg)

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'BareMetalServerNetworkInterfacePrototype':
        """Initialize a BareMetalServerNetworkInterfacePrototype 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 'BareMetalServerNetworkInterfacePrototype'. The discriminator value should map to a valid subclass: {1}".format(
            ", ".join(['BareMetalServerNetworkInterfacePrototypeBareMetalServerNetworkInterfaceByHiperSocketPrototype', 'BareMetalServerNetworkInterfacePrototypeBareMetalServerNetworkInterfaceByPCIPrototype', 'BareMetalServerNetworkInterfacePrototypeBareMetalServerNetworkInterfaceByVLANPrototype'])
        )
        raise Exception(msg)

    @classmethod
    def _from_dict(cls, _dict: Dict):
        """Initialize a BareMetalServerNetworkInterfacePrototype object from a json dictionary."""
        return cls.from_dict(_dict)

    @classmethod
    def _get_class_by_discriminator(cls, _dict: Dict) -> object:
        mapping = {}
        mapping['hipersocket'] = 'BareMetalServerNetworkInterfacePrototypeBareMetalServerNetworkInterfaceByHiperSocketPrototype'
        mapping['pci'] = 'BareMetalServerNetworkInterfacePrototypeBareMetalServerNetworkInterfaceByPCIPrototype'
        mapping['vlan'] = 'BareMetalServerNetworkInterfacePrototypeBareMetalServerNetworkInterfaceByVLANPrototype'
        disc_value = _dict.get('interface_type')
        if disc_value is None:
            raise ValueError('Discriminator property \'interface_type\' not found in BareMetalServerNetworkInterfacePrototype 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 InterfaceTypeEnum(str, Enum):
        """
        The interface type:
        - `hipersocket`: a virtual device that provides high-speed TCP/IP connectivity
          within a `s390x` based system
          - Not supported on bare metal servers with a `cpu.architecture` of `amd64`
        - `pci`: a physical PCI device which can only be created or deleted when the bare
        metal
          server is stopped
          - Has an `allowed_vlans` property which controls the VLANs that will be
        permitted
            to use the PCI interface
          - Cannot directly use an IEEE 802.1Q tag.
          - Not supported on bare metal servers with a `cpu.architecture` of `s390x`
        - `vlan`: a virtual device, used through a `pci` device that has the `vlan` in its
          array of `allowed_vlans`.
          - Must use an IEEE 802.1Q tag.
          - Has its own security groups and does not inherit those of the PCI device
        through
            which traffic flows.
          - Not supported on bare metal servers with a `cpu.architecture` of `s390x`.
        """

        HIPERSOCKET = 'hipersocket'
        PCI = 'pci'
        VLAN = 'vlan'



class BareMetalServerNetworkInterfaceReferenceDeleted:
    """
    If present, this property indicates the referenced resource has been deleted, and
    provides some supplementary information.

    :attr str more_info: Link to documentation about deleted resources.
    """

    def __init__(
        self,
        more_info: str,
    ) -> None:
        """
        Initialize a BareMetalServerNetworkInterfaceReferenceDeleted object.

        :param str more_info: Link to documentation about deleted resources.
        """
        self.more_info = more_info

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'BareMetalServerNetworkInterfaceReferenceDeleted':
        """Initialize a BareMetalServerNetworkInterfaceReferenceDeleted object from a json dictionary."""
        args = {}
        if 'more_info' in _dict:
            args['more_info'] = _dict.get('more_info')
        else:
            raise ValueError('Required property \'more_info\' not present in BareMetalServerNetworkInterfaceReferenceDeleted JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a BareMetalServerNetworkInterfaceReferenceDeleted object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'more_info') and self.more_info is not None:
            _dict['more_info'] = self.more_info
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this BareMetalServerNetworkInterfaceReferenceDeleted object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'BareMetalServerNetworkInterfaceReferenceDeleted') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'BareMetalServerNetworkInterfaceReferenceDeleted') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class BareMetalServerNetworkInterfaceReferenceTargetContextDeleted:
    """
    If present, this property indicates the referenced resource has been deleted, and
    provides some supplementary information.

    :attr str more_info: Link to documentation about deleted resources.
    """

    def __init__(
        self,
        more_info: str,
    ) -> None:
        """
        Initialize a BareMetalServerNetworkInterfaceReferenceTargetContextDeleted object.

        :param str more_info: Link to documentation about deleted resources.
        """
        self.more_info = more_info

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'BareMetalServerNetworkInterfaceReferenceTargetContextDeleted':
        """Initialize a BareMetalServerNetworkInterfaceReferenceTargetContextDeleted object from a json dictionary."""
        args = {}
        if 'more_info' in _dict:
            args['more_info'] = _dict.get('more_info')
        else:
            raise ValueError('Required property \'more_info\' not present in BareMetalServerNetworkInterfaceReferenceTargetContextDeleted JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a BareMetalServerNetworkInterfaceReferenceTargetContextDeleted object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'more_info') and self.more_info is not None:
            _dict['more_info'] = self.more_info
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this BareMetalServerNetworkInterfaceReferenceTargetContextDeleted object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'BareMetalServerNetworkInterfaceReferenceTargetContextDeleted') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'BareMetalServerNetworkInterfaceReferenceTargetContextDeleted') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class BareMetalServerPatch:
    """
    BareMetalServerPatch.

    :attr bool enable_secure_boot: (optional) Indicates whether secure boot is
          enabled. If enabled, the image must support secure boot or the bare metal server
          will fail to boot.
          For `enable_secure_boot` to be changed, the bare metal server `status` must be
          `stopped`.
    :attr str name: (optional) The name for this bare metal server. The name must
          not be used by another bare metal server in the region. Changing the name will
          not affect the system hostname.
    :attr BareMetalServerTrustedPlatformModulePatch trusted_platform_module:
          (optional)
    """

    def __init__(
        self,
        *,
        enable_secure_boot: bool = None,
        name: str = None,
        trusted_platform_module: 'BareMetalServerTrustedPlatformModulePatch' = None,
    ) -> None:
        """
        Initialize a BareMetalServerPatch object.

        :param bool enable_secure_boot: (optional) Indicates whether secure boot is
               enabled. If enabled, the image must support secure boot or the bare metal
               server will fail to boot.
               For `enable_secure_boot` to be changed, the bare metal server `status` must
               be
               `stopped`.
        :param str name: (optional) The name for this bare metal server. The name
               must not be used by another bare metal server in the region. Changing the
               name will not affect the system hostname.
        :param BareMetalServerTrustedPlatformModulePatch trusted_platform_module:
               (optional)
        """
        self.enable_secure_boot = enable_secure_boot
        self.name = name
        self.trusted_platform_module = trusted_platform_module

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'BareMetalServerPatch':
        """Initialize a BareMetalServerPatch object from a json dictionary."""
        args = {}
        if 'enable_secure_boot' in _dict:
            args['enable_secure_boot'] = _dict.get('enable_secure_boot')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        if 'trusted_platform_module' in _dict:
            args['trusted_platform_module'] = BareMetalServerTrustedPlatformModulePatch.from_dict(_dict.get('trusted_platform_module'))
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a BareMetalServerPatch object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'enable_secure_boot') and self.enable_secure_boot is not None:
            _dict['enable_secure_boot'] = self.enable_secure_boot
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'trusted_platform_module') and self.trusted_platform_module is not None:
            if isinstance(self.trusted_platform_module, dict):
                _dict['trusted_platform_module'] = self.trusted_platform_module
            else:
                _dict['trusted_platform_module'] = self.trusted_platform_module.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 BareMetalServerPatch object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'BareMetalServerPatch') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'BareMetalServerPatch') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class BareMetalServerPrimaryNetworkInterfacePrototype:
    """
    BareMetalServerPrimaryNetworkInterfacePrototype.

    :attr bool allow_ip_spoofing: (optional) Indicates whether source IP spoofing is
          allowed on this bare metal server network interface.
    :attr List[int] allowed_vlans: (optional) The VLAN IDs allowed for `vlan`
          interfaces using this PCI interface.
    :attr bool enable_infrastructure_nat: (optional) If `true`:
          - The VPC infrastructure performs any needed NAT operations.
          - `floating_ips` must not have more than one floating IP.
          If `false`:
          - Packets are passed unchanged to/from the bare metal server network interface,
            allowing the workload to perform any needed NAT operations.
          - `allow_ip_spoofing` must be `false`.
          - `interface_type` must not be `hipersocket`.
    :attr str interface_type: (optional) The interface type:
          - `hipersocket`: a virtual device that provides high-speed TCP/IP connectivity
            within a `s390x` based system.
            - Not supported on bare metal servers with a `cpu.architecture` of `amd64`
          - `pci`: a physical PCI device which can only be created or deleted when the
          bare metal
            server is stopped
            - Has an `allowed_vlans` property which controls the VLANs that will be
          permitted
              to use the PCI interface
            - Cannot directly use an IEEE 802.1Q tag.
            - Not supported on bare metal servers with a `cpu.architecture` of `s390x`.
    :attr str name: (optional) The name for this bare metal server network
          interface. The name must not be used by another network interface on the bare
          metal server. If unspecified, the name will be a hyphenated list of
          randomly-selected words.
    :attr NetworkInterfaceIPPrototype primary_ip: (optional) The primary IP address
          to bind to the bare metal server network interface. This can be
          specified using an existing reserved IP, or a prototype object for a new
          reserved IP.
          If an existing reserved IP or a prototype object with an address is specified,
          it must
          be available on the bare metal server network interface's subnet. Otherwise, an
          available address on the subnet will be automatically selected and reserved.
    :attr List[SecurityGroupIdentity] security_groups: (optional) The security
          groups to use for this bare metal server network interface. If unspecified, the
          VPC's default security group is used.
    :attr SubnetIdentity subnet: The associated subnet.
    """

    def __init__(
        self,
        subnet: 'SubnetIdentity',
        *,
        allow_ip_spoofing: bool = None,
        allowed_vlans: List[int] = None,
        enable_infrastructure_nat: bool = None,
        interface_type: str = None,
        name: str = None,
        primary_ip: 'NetworkInterfaceIPPrototype' = None,
        security_groups: List['SecurityGroupIdentity'] = None,
    ) -> None:
        """
        Initialize a BareMetalServerPrimaryNetworkInterfacePrototype object.

        :param SubnetIdentity subnet: The associated subnet.
        :param bool allow_ip_spoofing: (optional) Indicates whether source IP
               spoofing is allowed on this bare metal server network interface.
        :param List[int] allowed_vlans: (optional) The VLAN IDs allowed for `vlan`
               interfaces using this PCI interface.
        :param bool enable_infrastructure_nat: (optional) If `true`:
               - The VPC infrastructure performs any needed NAT operations.
               - `floating_ips` must not have more than one floating IP.
               If `false`:
               - Packets are passed unchanged to/from the bare metal server network
               interface,
                 allowing the workload to perform any needed NAT operations.
               - `allow_ip_spoofing` must be `false`.
               - `interface_type` must not be `hipersocket`.
        :param str interface_type: (optional) The interface type:
               - `hipersocket`: a virtual device that provides high-speed TCP/IP
               connectivity
                 within a `s390x` based system.
                 - Not supported on bare metal servers with a `cpu.architecture` of
               `amd64`
               - `pci`: a physical PCI device which can only be created or deleted when
               the bare metal
                 server is stopped
                 - Has an `allowed_vlans` property which controls the VLANs that will be
               permitted
                   to use the PCI interface
                 - Cannot directly use an IEEE 802.1Q tag.
                 - Not supported on bare metal servers with a `cpu.architecture` of
               `s390x`.
        :param str name: (optional) The name for this bare metal server network
               interface. The name must not be used by another network interface on the
               bare metal server. If unspecified, the name will be a hyphenated list of
               randomly-selected words.
        :param NetworkInterfaceIPPrototype primary_ip: (optional) The primary IP
               address to bind to the bare metal server network interface. This can be
               specified using an existing reserved IP, or a prototype object for a new
               reserved IP.
               If an existing reserved IP or a prototype object with an address is
               specified, it must
               be available on the bare metal server network interface's subnet.
               Otherwise, an
               available address on the subnet will be automatically selected and
               reserved.
        :param List[SecurityGroupIdentity] security_groups: (optional) The security
               groups to use for this bare metal server network interface. If unspecified,
               the VPC's default security group is used.
        """
        self.allow_ip_spoofing = allow_ip_spoofing
        self.allowed_vlans = allowed_vlans
        self.enable_infrastructure_nat = enable_infrastructure_nat
        self.interface_type = interface_type
        self.name = name
        self.primary_ip = primary_ip
        self.security_groups = security_groups
        self.subnet = subnet

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'BareMetalServerPrimaryNetworkInterfacePrototype':
        """Initialize a BareMetalServerPrimaryNetworkInterfacePrototype object from a json dictionary."""
        args = {}
        if 'allow_ip_spoofing' in _dict:
            args['allow_ip_spoofing'] = _dict.get('allow_ip_spoofing')
        if 'allowed_vlans' in _dict:
            args['allowed_vlans'] = _dict.get('allowed_vlans')
        if 'enable_infrastructure_nat' in _dict:
            args['enable_infrastructure_nat'] = _dict.get('enable_infrastructure_nat')
        if 'interface_type' in _dict:
            args['interface_type'] = _dict.get('interface_type')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        if 'primary_ip' in _dict:
            args['primary_ip'] = _dict.get('primary_ip')
        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 BareMetalServerPrimaryNetworkInterfacePrototype JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a BareMetalServerPrimaryNetworkInterfacePrototype object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'allow_ip_spoofing') and self.allow_ip_spoofing is not None:
            _dict['allow_ip_spoofing'] = self.allow_ip_spoofing
        if hasattr(self, 'allowed_vlans') and self.allowed_vlans is not None:
            _dict['allowed_vlans'] = self.allowed_vlans
        if hasattr(self, 'enable_infrastructure_nat') and self.enable_infrastructure_nat is not None:
            _dict['enable_infrastructure_nat'] = self.enable_infrastructure_nat
        if hasattr(self, 'interface_type') and self.interface_type is not None:
            _dict['interface_type'] = self.interface_type
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'primary_ip') and self.primary_ip is not None:
            if isinstance(self.primary_ip, dict):
                _dict['primary_ip'] = self.primary_ip
            else:
                _dict['primary_ip'] = self.primary_ip.to_dict()
        if hasattr(self, 'security_groups') and self.security_groups is not None:
            security_groups_list = []
            for v in self.security_groups:
                if isinstance(v, dict):
                    security_groups_list.append(v)
                else:
                    security_groups_list.append(v.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 BareMetalServerPrimaryNetworkInterfacePrototype object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'BareMetalServerPrimaryNetworkInterfacePrototype') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'BareMetalServerPrimaryNetworkInterfacePrototype') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class InterfaceTypeEnum(str, Enum):
        """
        The interface type:
        - `hipersocket`: a virtual device that provides high-speed TCP/IP connectivity
          within a `s390x` based system.
          - Not supported on bare metal servers with a `cpu.architecture` of `amd64`
        - `pci`: a physical PCI device which can only be created or deleted when the bare
        metal
          server is stopped
          - Has an `allowed_vlans` property which controls the VLANs that will be
        permitted
            to use the PCI interface
          - Cannot directly use an IEEE 802.1Q tag.
          - Not supported on bare metal servers with a `cpu.architecture` of `s390x`.
        """

        HIPERSOCKET = 'hipersocket'
        PCI = 'pci'



class BareMetalServerProfile:
    """
    BareMetalServerProfile.

    :attr BareMetalServerProfileBandwidth bandwidth:
    :attr BareMetalServerProfileConsoleTypes console_types: The console type
          configuration for a bare metal server with this profile.
    :attr BareMetalServerProfileCPUArchitecture cpu_architecture:
    :attr BareMetalServerProfileCPUCoreCount cpu_core_count:
    :attr BareMetalServerProfileCPUSocketCount cpu_socket_count:
    :attr List[BareMetalServerProfileDisk] disks: Collection of the bare metal
          server profile's disks.
    :attr str family: The product family this bare metal server profile belongs to.
    :attr str href: The URL for this bare metal server profile.
    :attr BareMetalServerProfileMemory memory:
    :attr str name: The name for this bare metal server profile.
    :attr BareMetalServerProfileNetworkInterfaceCount network_interface_count:
    :attr BareMetalServerProfileOSArchitecture os_architecture:
    :attr str resource_type: The resource type.
    :attr BareMetalServerProfileSupportedTrustedPlatformModuleModes
          supported_trusted_platform_module_modes: The supported trusted platform module
          modes for this bare metal server profile.
    """

    def __init__(
        self,
        bandwidth: 'BareMetalServerProfileBandwidth',
        console_types: 'BareMetalServerProfileConsoleTypes',
        cpu_architecture: 'BareMetalServerProfileCPUArchitecture',
        cpu_core_count: 'BareMetalServerProfileCPUCoreCount',
        cpu_socket_count: 'BareMetalServerProfileCPUSocketCount',
        disks: List['BareMetalServerProfileDisk'],
        family: str,
        href: str,
        memory: 'BareMetalServerProfileMemory',
        name: str,
        network_interface_count: 'BareMetalServerProfileNetworkInterfaceCount',
        os_architecture: 'BareMetalServerProfileOSArchitecture',
        resource_type: str,
        supported_trusted_platform_module_modes: 'BareMetalServerProfileSupportedTrustedPlatformModuleModes',
    ) -> None:
        """
        Initialize a BareMetalServerProfile object.

        :param BareMetalServerProfileBandwidth bandwidth:
        :param BareMetalServerProfileConsoleTypes console_types: The console type
               configuration for a bare metal server with this profile.
        :param BareMetalServerProfileCPUArchitecture cpu_architecture:
        :param BareMetalServerProfileCPUCoreCount cpu_core_count:
        :param BareMetalServerProfileCPUSocketCount cpu_socket_count:
        :param List[BareMetalServerProfileDisk] disks: Collection of the bare metal
               server profile's disks.
        :param str family: The product family this bare metal server profile
               belongs to.
        :param str href: The URL for this bare metal server profile.
        :param BareMetalServerProfileMemory memory:
        :param str name: The name for this bare metal server profile.
        :param BareMetalServerProfileNetworkInterfaceCount network_interface_count:
        :param BareMetalServerProfileOSArchitecture os_architecture:
        :param str resource_type: The resource type.
        :param BareMetalServerProfileSupportedTrustedPlatformModuleModes
               supported_trusted_platform_module_modes: The supported trusted platform
               module modes for this bare metal server profile.
        """
        self.bandwidth = bandwidth
        self.console_types = console_types
        self.cpu_architecture = cpu_architecture
        self.cpu_core_count = cpu_core_count
        self.cpu_socket_count = cpu_socket_count
        self.disks = disks
        self.family = family
        self.href = href
        self.memory = memory
        self.name = name
        self.network_interface_count = network_interface_count
        self.os_architecture = os_architecture
        self.resource_type = resource_type
        self.supported_trusted_platform_module_modes = supported_trusted_platform_module_modes

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'BareMetalServerProfile':
        """Initialize a BareMetalServerProfile object from a json dictionary."""
        args = {}
        if 'bandwidth' in _dict:
            args['bandwidth'] = _dict.get('bandwidth')
        else:
            raise ValueError('Required property \'bandwidth\' not present in BareMetalServerProfile JSON')
        if 'console_types' in _dict:
            args['console_types'] = BareMetalServerProfileConsoleTypes.from_dict(_dict.get('console_types'))
        else:
            raise ValueError('Required property \'console_types\' not present in BareMetalServerProfile JSON')
        if 'cpu_architecture' in _dict:
            args['cpu_architecture'] = BareMetalServerProfileCPUArchitecture.from_dict(_dict.get('cpu_architecture'))
        else:
            raise ValueError('Required property \'cpu_architecture\' not present in BareMetalServerProfile JSON')
        if 'cpu_core_count' in _dict:
            args['cpu_core_count'] = _dict.get('cpu_core_count')
        else:
            raise ValueError('Required property \'cpu_core_count\' not present in BareMetalServerProfile JSON')
        if 'cpu_socket_count' in _dict:
            args['cpu_socket_count'] = _dict.get('cpu_socket_count')
        else:
            raise ValueError('Required property \'cpu_socket_count\' not present in BareMetalServerProfile JSON')
        if 'disks' in _dict:
            args['disks'] = [BareMetalServerProfileDisk.from_dict(v) for v in _dict.get('disks')]
        else:
            raise ValueError('Required property \'disks\' not present in BareMetalServerProfile JSON')
        if 'family' in _dict:
            args['family'] = _dict.get('family')
        else:
            raise ValueError('Required property \'family\' not present in BareMetalServerProfile JSON')
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in BareMetalServerProfile JSON')
        if 'memory' in _dict:
            args['memory'] = _dict.get('memory')
        else:
            raise ValueError('Required property \'memory\' not present in BareMetalServerProfile JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in BareMetalServerProfile JSON')
        if 'network_interface_count' in _dict:
            args['network_interface_count'] = _dict.get('network_interface_count')
        else:
            raise ValueError('Required property \'network_interface_count\' not present in BareMetalServerProfile JSON')
        if 'os_architecture' in _dict:
            args['os_architecture'] = BareMetalServerProfileOSArchitecture.from_dict(_dict.get('os_architecture'))
        else:
            raise ValueError('Required property \'os_architecture\' not present in BareMetalServerProfile JSON')
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError('Required property \'resource_type\' not present in BareMetalServerProfile JSON')
        if 'supported_trusted_platform_module_modes' in _dict:
            args['supported_trusted_platform_module_modes'] = BareMetalServerProfileSupportedTrustedPlatformModuleModes.from_dict(_dict.get('supported_trusted_platform_module_modes'))
        else:
            raise ValueError('Required property \'supported_trusted_platform_module_modes\' not present in BareMetalServerProfile JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a BareMetalServerProfile object from 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, 'console_types') and self.console_types is not None:
            if isinstance(self.console_types, dict):
                _dict['console_types'] = self.console_types
            else:
                _dict['console_types'] = self.console_types.to_dict()
        if hasattr(self, 'cpu_architecture') and self.cpu_architecture is not None:
            if isinstance(self.cpu_architecture, dict):
                _dict['cpu_architecture'] = self.cpu_architecture
            else:
                _dict['cpu_architecture'] = self.cpu_architecture.to_dict()
        if hasattr(self, 'cpu_core_count') and self.cpu_core_count is not None:
            if isinstance(self.cpu_core_count, dict):
                _dict['cpu_core_count'] = self.cpu_core_count
            else:
                _dict['cpu_core_count'] = self.cpu_core_count.to_dict()
        if hasattr(self, 'cpu_socket_count') and self.cpu_socket_count is not None:
            if isinstance(self.cpu_socket_count, dict):
                _dict['cpu_socket_count'] = self.cpu_socket_count
            else:
                _dict['cpu_socket_count'] = self.cpu_socket_count.to_dict()
        if hasattr(self, 'disks') and self.disks is not None:
            disks_list = []
            for v in self.disks:
                if isinstance(v, dict):
                    disks_list.append(v)
                else:
                    disks_list.append(v.to_dict())
            _dict['disks'] = disks_list
        if hasattr(self, 'family') and self.family is not None:
            _dict['family'] = self.family
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'memory') and self.memory is not None:
            if isinstance(self.memory, dict):
                _dict['memory'] = self.memory
            else:
                _dict['memory'] = self.memory.to_dict()
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'network_interface_count') and self.network_interface_count is not None:
            if isinstance(self.network_interface_count, dict):
                _dict['network_interface_count'] = self.network_interface_count
            else:
                _dict['network_interface_count'] = self.network_interface_count.to_dict()
        if hasattr(self, 'os_architecture') and self.os_architecture is not None:
            if isinstance(self.os_architecture, dict):
                _dict['os_architecture'] = self.os_architecture
            else:
                _dict['os_architecture'] = self.os_architecture.to_dict()
        if hasattr(self, 'resource_type') and self.resource_type is not None:
            _dict['resource_type'] = self.resource_type
        if hasattr(self, 'supported_trusted_platform_module_modes') and self.supported_trusted_platform_module_modes is not None:
            if isinstance(self.supported_trusted_platform_module_modes, dict):
                _dict['supported_trusted_platform_module_modes'] = self.supported_trusted_platform_module_modes
            else:
                _dict['supported_trusted_platform_module_modes'] = self.supported_trusted_platform_module_modes.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 BareMetalServerProfile object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'BareMetalServerProfile') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'BareMetalServerProfile') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        BARE_METAL_SERVER_PROFILE = 'bare_metal_server_profile'



class BareMetalServerProfileBandwidth:
    """
    BareMetalServerProfileBandwidth.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a BareMetalServerProfileBandwidth object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['BareMetalServerProfileBandwidthFixed', 'BareMetalServerProfileBandwidthRange', 'BareMetalServerProfileBandwidthEnum', 'BareMetalServerProfileBandwidthDependent'])
        )
        raise Exception(msg)


class BareMetalServerProfileCPUArchitecture:
    """
    BareMetalServerProfileCPUArchitecture.

    :attr str default: (optional) The default CPU architecture for a bare metal
          server with this profile.
    :attr str type: The type for this profile field.
    :attr str value: The CPU architecture for a bare metal server with this profile.
    """

    def __init__(
        self,
        type: str,
        value: str,
        *,
        default: str = None,
    ) -> None:
        """
        Initialize a BareMetalServerProfileCPUArchitecture object.

        :param str type: The type for this profile field.
        :param str value: The CPU architecture for a bare metal server with this
               profile.
        :param str default: (optional) The default CPU architecture for a bare
               metal server with this profile.
        """
        self.default = default
        self.type = type
        self.value = value

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'BareMetalServerProfileCPUArchitecture':
        """Initialize a BareMetalServerProfileCPUArchitecture object from a json dictionary."""
        args = {}
        if 'default' in _dict:
            args['default'] = _dict.get('default')
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in BareMetalServerProfileCPUArchitecture JSON')
        if 'value' in _dict:
            args['value'] = _dict.get('value')
        else:
            raise ValueError('Required property \'value\' not present in BareMetalServerProfileCPUArchitecture JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a BareMetalServerProfileCPUArchitecture object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'default') and self.default is not None:
            _dict['default'] = self.default
        if hasattr(self, 'type') and self.type is not None:
            _dict['type'] = self.type
        if hasattr(self, 'value') and self.value is not None:
            _dict['value'] = self.value
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this BareMetalServerProfileCPUArchitecture object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'BareMetalServerProfileCPUArchitecture') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'BareMetalServerProfileCPUArchitecture') -> 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 BareMetalServerProfileCPUCoreCount:
    """
    BareMetalServerProfileCPUCoreCount.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a BareMetalServerProfileCPUCoreCount object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['BareMetalServerProfileCPUCoreCountFixed', 'BareMetalServerProfileCPUCoreCountRange', 'BareMetalServerProfileCPUCoreCountEnum', 'BareMetalServerProfileCPUCoreCountDependent'])
        )
        raise Exception(msg)


class BareMetalServerProfileCPUSocketCount:
    """
    BareMetalServerProfileCPUSocketCount.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a BareMetalServerProfileCPUSocketCount object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['BareMetalServerProfileCPUSocketCountFixed', 'BareMetalServerProfileCPUSocketCountRange', 'BareMetalServerProfileCPUSocketCountEnum', 'BareMetalServerProfileCPUSocketCountDependent'])
        )
        raise Exception(msg)


class BareMetalServerProfileCollection:
    """
    BareMetalServerProfileCollection.

    :attr BareMetalServerProfileCollectionFirst 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 BareMetalServerProfileCollectionNext next: (optional) A link to the next
          page of resources. This property is present for all pages
          except the last page.
    :attr List[BareMetalServerProfile] profiles: Collection of bare metal server
          profiles.
    :attr int total_count: The total number of resources across all pages.
    """

    def __init__(
        self,
        first: 'BareMetalServerProfileCollectionFirst',
        limit: int,
        profiles: List['BareMetalServerProfile'],
        total_count: int,
        *,
        next: 'BareMetalServerProfileCollectionNext' = None,
    ) -> None:
        """
        Initialize a BareMetalServerProfileCollection object.

        :param BareMetalServerProfileCollectionFirst 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[BareMetalServerProfile] profiles: Collection of bare metal
               server profiles.
        :param int total_count: The total number of resources across all pages.
        :param BareMetalServerProfileCollectionNext 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) -> 'BareMetalServerProfileCollection':
        """Initialize a BareMetalServerProfileCollection object from a json dictionary."""
        args = {}
        if 'first' in _dict:
            args['first'] = BareMetalServerProfileCollectionFirst.from_dict(_dict.get('first'))
        else:
            raise ValueError('Required property \'first\' not present in BareMetalServerProfileCollection JSON')
        if 'limit' in _dict:
            args['limit'] = _dict.get('limit')
        else:
            raise ValueError('Required property \'limit\' not present in BareMetalServerProfileCollection JSON')
        if 'next' in _dict:
            args['next'] = BareMetalServerProfileCollectionNext.from_dict(_dict.get('next'))
        if 'profiles' in _dict:
            args['profiles'] = [BareMetalServerProfile.from_dict(v) for v in _dict.get('profiles')]
        else:
            raise ValueError('Required property \'profiles\' not present in BareMetalServerProfileCollection JSON')
        if 'total_count' in _dict:
            args['total_count'] = _dict.get('total_count')
        else:
            raise ValueError('Required property \'total_count\' not present in BareMetalServerProfileCollection JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a BareMetalServerProfileCollection object from 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:
            if isinstance(self.first, dict):
                _dict['first'] = self.first
            else:
                _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:
            if isinstance(self.next, dict):
                _dict['next'] = self.next
            else:
                _dict['next'] = self.next.to_dict()
        if hasattr(self, 'profiles') and self.profiles is not None:
            profiles_list = []
            for v in self.profiles:
                if isinstance(v, dict):
                    profiles_list.append(v)
                else:
                    profiles_list.append(v.to_dict())
            _dict['profiles'] = profiles_list
        if hasattr(self, 'total_count') and self.total_count is not None:
            _dict['total_count'] = self.total_count
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this BareMetalServerProfileCollection object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'BareMetalServerProfileCollection') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'BareMetalServerProfileCollection') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class BareMetalServerProfileCollectionFirst:
    """
    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 BareMetalServerProfileCollectionFirst object.

        :param str href: The URL for a page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'BareMetalServerProfileCollectionFirst':
        """Initialize a BareMetalServerProfileCollectionFirst object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in BareMetalServerProfileCollectionFirst JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a BareMetalServerProfileCollectionFirst object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(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 BareMetalServerProfileCollectionFirst object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'BareMetalServerProfileCollectionFirst') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'BareMetalServerProfileCollectionFirst') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class BareMetalServerProfileCollectionNext:
    """
    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 BareMetalServerProfileCollectionNext object.

        :param str href: The URL for a page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'BareMetalServerProfileCollectionNext':
        """Initialize a BareMetalServerProfileCollectionNext object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in BareMetalServerProfileCollectionNext JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a BareMetalServerProfileCollectionNext object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(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 BareMetalServerProfileCollectionNext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'BareMetalServerProfileCollectionNext') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'BareMetalServerProfileCollectionNext') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class BareMetalServerProfileConsoleTypes:
    """
    The console type configuration for a bare metal server with this profile.

    :attr str type: The type for this profile field.
    :attr List[str] values: The console types for a bare metal server with this
          profile.
    """

    def __init__(
        self,
        type: str,
        values: List[str],
    ) -> None:
        """
        Initialize a BareMetalServerProfileConsoleTypes object.

        :param str type: The type for this profile field.
        :param List[str] values: The console types for a bare metal server with
               this profile.
        """
        self.type = type
        self.values = values

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'BareMetalServerProfileConsoleTypes':
        """Initialize a BareMetalServerProfileConsoleTypes object from a json dictionary."""
        args = {}
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in BareMetalServerProfileConsoleTypes JSON')
        if 'values' in _dict:
            args['values'] = _dict.get('values')
        else:
            raise ValueError('Required property \'values\' not present in BareMetalServerProfileConsoleTypes JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a BareMetalServerProfileConsoleTypes object from 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, '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 BareMetalServerProfileConsoleTypes object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'BareMetalServerProfileConsoleTypes') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'BareMetalServerProfileConsoleTypes') -> 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 ValuesEnum(str, Enum):
        """
        A console type.
        """

        SERIAL = 'serial'
        VNC = 'vnc'



class BareMetalServerProfileDisk:
    """
    Disks provided by this profile.

    :attr BareMetalServerProfileDiskQuantity quantity:
    :attr BareMetalServerProfileDiskSize size:
    :attr BareMetalServerProfileDiskSupportedInterfaces supported_interface_types:
    """

    def __init__(
        self,
        quantity: 'BareMetalServerProfileDiskQuantity',
        size: 'BareMetalServerProfileDiskSize',
        supported_interface_types: 'BareMetalServerProfileDiskSupportedInterfaces',
    ) -> None:
        """
        Initialize a BareMetalServerProfileDisk object.

        :param BareMetalServerProfileDiskQuantity quantity:
        :param BareMetalServerProfileDiskSize size:
        :param BareMetalServerProfileDiskSupportedInterfaces
               supported_interface_types:
        """
        self.quantity = quantity
        self.size = size
        self.supported_interface_types = supported_interface_types

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'BareMetalServerProfileDisk':
        """Initialize a BareMetalServerProfileDisk object from a json dictionary."""
        args = {}
        if 'quantity' in _dict:
            args['quantity'] = _dict.get('quantity')
        else:
            raise ValueError('Required property \'quantity\' not present in BareMetalServerProfileDisk JSON')
        if 'size' in _dict:
            args['size'] = _dict.get('size')
        else:
            raise ValueError('Required property \'size\' not present in BareMetalServerProfileDisk JSON')
        if 'supported_interface_types' in _dict:
            args['supported_interface_types'] = BareMetalServerProfileDiskSupportedInterfaces.from_dict(_dict.get('supported_interface_types'))
        else:
            raise ValueError('Required property \'supported_interface_types\' not present in BareMetalServerProfileDisk JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a BareMetalServerProfileDisk object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'quantity') and self.quantity is not None:
            if isinstance(self.quantity, dict):
                _dict['quantity'] = self.quantity
            else:
                _dict['quantity'] = self.quantity.to_dict()
        if hasattr(self, 'size') and self.size is not None:
            if isinstance(self.size, dict):
                _dict['size'] = self.size
            else:
                _dict['size'] = self.size.to_dict()
        if hasattr(self, 'supported_interface_types') and self.supported_interface_types is not None:
            if isinstance(self.supported_interface_types, dict):
                _dict['supported_interface_types'] = self.supported_interface_types
            else:
                _dict['supported_interface_types'] = self.supported_interface_types.to_dict()
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this BareMetalServerProfileDisk object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'BareMetalServerProfileDisk') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'BareMetalServerProfileDisk') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class BareMetalServerProfileDiskQuantity:
    """
    BareMetalServerProfileDiskQuantity.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a BareMetalServerProfileDiskQuantity object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['BareMetalServerProfileDiskQuantityFixed', 'BareMetalServerProfileDiskQuantityRange', 'BareMetalServerProfileDiskQuantityEnum', 'BareMetalServerProfileDiskQuantityDependent'])
        )
        raise Exception(msg)


class BareMetalServerProfileDiskSize:
    """
    BareMetalServerProfileDiskSize.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a BareMetalServerProfileDiskSize object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['BareMetalServerProfileDiskSizeFixed', 'BareMetalServerProfileDiskSizeRange', 'BareMetalServerProfileDiskSizeEnum', 'BareMetalServerProfileDiskSizeDependent'])
        )
        raise Exception(msg)


class BareMetalServerProfileDiskSupportedInterfaces:
    """
    BareMetalServerProfileDiskSupportedInterfaces.

    :attr str default: The disk interface used for attaching the disk.
          - `fcp`: Attached using Fiber Channel Protocol
          - `sata`: Attached using Serial Advanced Technology Attachment
          - `nvme`: Attached using Non-Volatile Memory Express
          The enumerated values for this property are expected to expand in the future.
          When processing this property, check for and log unknown values. Optionally halt
          processing and surface the error, or bypass the resource on which the unexpected
          property value was encountered.
    :attr str type: The type for this profile field.
    :attr List[str] values: The supported disk interfaces used for attaching the
          disk.
    """

    def __init__(
        self,
        default: str,
        type: str,
        values: List[str],
    ) -> None:
        """
        Initialize a BareMetalServerProfileDiskSupportedInterfaces object.

        :param str default: The disk interface used for attaching the disk.
               - `fcp`: Attached using Fiber Channel Protocol
               - `sata`: Attached using Serial Advanced Technology Attachment
               - `nvme`: Attached using Non-Volatile Memory Express
               The enumerated values for this property are expected to expand in the
               future. When processing this property, check for and log unknown values.
               Optionally halt processing and surface the error, or bypass the resource on
               which the unexpected property value was encountered.
        :param str type: The type for this profile field.
        :param List[str] values: The supported disk interfaces used for attaching
               the disk.
        """
        self.default = default
        self.type = type
        self.values = values

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'BareMetalServerProfileDiskSupportedInterfaces':
        """Initialize a BareMetalServerProfileDiskSupportedInterfaces object from a json dictionary."""
        args = {}
        if 'default' in _dict:
            args['default'] = _dict.get('default')
        else:
            raise ValueError('Required property \'default\' not present in BareMetalServerProfileDiskSupportedInterfaces JSON')
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in BareMetalServerProfileDiskSupportedInterfaces JSON')
        if 'values' in _dict:
            args['values'] = _dict.get('values')
        else:
            raise ValueError('Required property \'values\' not present in BareMetalServerProfileDiskSupportedInterfaces JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a BareMetalServerProfileDiskSupportedInterfaces object from 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 BareMetalServerProfileDiskSupportedInterfaces object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'BareMetalServerProfileDiskSupportedInterfaces') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'BareMetalServerProfileDiskSupportedInterfaces') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class DefaultEnum(str, Enum):
        """
        The disk interface used for attaching the disk.
        - `fcp`: Attached using Fiber Channel Protocol
        - `sata`: Attached using Serial Advanced Technology Attachment
        - `nvme`: Attached using Non-Volatile Memory Express
        The enumerated values for this property are expected to expand in the future. When
        processing this property, check for and log unknown values. Optionally halt
        processing and surface the error, or bypass the resource on which the unexpected
        property value was encountered.
        """

        FCP = 'fcp'
        NVME = 'nvme'
        SATA = 'sata'


    class TypeEnum(str, Enum):
        """
        The type for this profile field.
        """

        ENUM = 'enum'


    class ValuesEnum(str, Enum):
        """
        The disk interface used for attaching the disk.
        - `fcp`: Attached using Fiber Channel Protocol
        - `sata`: Attached using Serial Advanced Technology Attachment
        - `nvme`: Attached using Non-Volatile Memory Express
        The enumerated values for this property are expected to expand in the future. When
        processing this property, check for and log unknown values. Optionally halt
        processing and surface the error, or bypass the resource on which the unexpected
        property value was encountered.
        """

        FCP = 'fcp'
        NVME = 'nvme'
        SATA = 'sata'



class BareMetalServerProfileIdentity:
    """
    Identifies a bare metal server profile by a unique property.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a BareMetalServerProfileIdentity object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['BareMetalServerProfileIdentityByName', 'BareMetalServerProfileIdentityByHref'])
        )
        raise Exception(msg)


class BareMetalServerProfileMemory:
    """
    BareMetalServerProfileMemory.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a BareMetalServerProfileMemory object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['BareMetalServerProfileMemoryFixed', 'BareMetalServerProfileMemoryRange', 'BareMetalServerProfileMemoryEnum', 'BareMetalServerProfileMemoryDependent'])
        )
        raise Exception(msg)


class BareMetalServerProfileNetworkInterfaceCount:
    """
    BareMetalServerProfileNetworkInterfaceCount.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a BareMetalServerProfileNetworkInterfaceCount object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['BareMetalServerProfileNetworkInterfaceCountRange', 'BareMetalServerProfileNetworkInterfaceCountDependent'])
        )
        raise Exception(msg)


class BareMetalServerProfileOSArchitecture:
    """
    BareMetalServerProfileOSArchitecture.

    :attr str default: The default OS architecture for a bare metal server with this
          profile.
    :attr str type: The type for this profile field.
    :attr List[str] values: The supported OS architecture(s) for a bare metal server
          with this profile.
    """

    def __init__(
        self,
        default: str,
        type: str,
        values: List[str],
    ) -> None:
        """
        Initialize a BareMetalServerProfileOSArchitecture object.

        :param str default: The default OS architecture for a bare metal server
               with this profile.
        :param str type: The type for this profile field.
        :param List[str] values: The supported OS architecture(s) for a bare metal
               server with this profile.
        """
        self.default = default
        self.type = type
        self.values = values

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'BareMetalServerProfileOSArchitecture':
        """Initialize a BareMetalServerProfileOSArchitecture object from a json dictionary."""
        args = {}
        if 'default' in _dict:
            args['default'] = _dict.get('default')
        else:
            raise ValueError('Required property \'default\' not present in BareMetalServerProfileOSArchitecture JSON')
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in BareMetalServerProfileOSArchitecture JSON')
        if 'values' in _dict:
            args['values'] = _dict.get('values')
        else:
            raise ValueError('Required property \'values\' not present in BareMetalServerProfileOSArchitecture JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a BareMetalServerProfileOSArchitecture object from 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 BareMetalServerProfileOSArchitecture object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'BareMetalServerProfileOSArchitecture') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'BareMetalServerProfileOSArchitecture') -> 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 BareMetalServerProfileReference:
    """
    BareMetalServerProfileReference.

    :attr str href: The URL for this bare metal server profile.
    :attr str name: The name for this bare metal server profile.
    :attr str resource_type: The resource type.
    """

    def __init__(
        self,
        href: str,
        name: str,
        resource_type: str,
    ) -> None:
        """
        Initialize a BareMetalServerProfileReference object.

        :param str href: The URL for this bare metal server profile.
        :param str name: The name for this bare metal server profile.
        :param str resource_type: The resource type.
        """
        self.href = href
        self.name = name
        self.resource_type = resource_type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'BareMetalServerProfileReference':
        """Initialize a BareMetalServerProfileReference object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in BareMetalServerProfileReference JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in BareMetalServerProfileReference JSON')
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError('Required property \'resource_type\' not present in BareMetalServerProfileReference JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a BareMetalServerProfileReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(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, '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 BareMetalServerProfileReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'BareMetalServerProfileReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'BareMetalServerProfileReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        BARE_METAL_SERVER_PROFILE = 'bare_metal_server_profile'



class BareMetalServerProfileSupportedTrustedPlatformModuleModes:
    """
    The supported trusted platform module modes for this bare metal server profile.

    :attr str type: The type for this profile field.
    :attr List[str] values: The supported trusted platform module modes.
    """

    def __init__(
        self,
        type: str,
        values: List[str],
    ) -> None:
        """
        Initialize a BareMetalServerProfileSupportedTrustedPlatformModuleModes object.

        :param str type: The type for this profile field.
        :param List[str] values: The supported trusted platform module modes.
        """
        self.type = type
        self.values = values

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'BareMetalServerProfileSupportedTrustedPlatformModuleModes':
        """Initialize a BareMetalServerProfileSupportedTrustedPlatformModuleModes object from a json dictionary."""
        args = {}
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in BareMetalServerProfileSupportedTrustedPlatformModuleModes JSON')
        if 'values' in _dict:
            args['values'] = _dict.get('values')
        else:
            raise ValueError('Required property \'values\' not present in BareMetalServerProfileSupportedTrustedPlatformModuleModes JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a BareMetalServerProfileSupportedTrustedPlatformModuleModes object from 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, '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 BareMetalServerProfileSupportedTrustedPlatformModuleModes object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'BareMetalServerProfileSupportedTrustedPlatformModuleModes') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'BareMetalServerProfileSupportedTrustedPlatformModuleModes') -> 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 ValuesEnum(str, Enum):
        """
        The trusted platform module (TPM) mode:
        - `disabled`: No TPM functionality
        - `tpm_2`: TPM 2.0
        The enumerated values for this property are expected to expand in the future. When
        processing this property, check for and log unknown values. Optionally halt
        processing and surface the error, or bypass the resource on which the unexpected
        property value was encountered.
        """

        DISABLED = 'disabled'
        TPM_2 = 'tpm_2'



class BareMetalServerStatusReason:
    """
    BareMetalServerStatusReason.

    :attr str code: The status reason code:
          - `cannot_start`: Failed to start due to an internal error
          - `cannot_start_capacity`: Insufficient capacity within the selected zone
          - `cannot_start_compute`: An error occurred while allocating compute resources
          - `cannot_start_ip_address`: An error occurred while allocating an IP address
          - `cannot_start_network`: An error occurred while allocating network resources.
    :attr str message: An explanation of the status reason.
    :attr str more_info: (optional) Link to documentation about this status reason.
    """

    def __init__(
        self,
        code: str,
        message: str,
        *,
        more_info: str = None,
    ) -> None:
        """
        Initialize a BareMetalServerStatusReason object.

        :param str code: The status reason code:
               - `cannot_start`: Failed to start due to an internal error
               - `cannot_start_capacity`: Insufficient capacity within the selected zone
               - `cannot_start_compute`: An error occurred while allocating compute
               resources
               - `cannot_start_ip_address`: An error occurred while allocating an IP
               address
               - `cannot_start_network`: An error occurred while allocating network
               resources.
        :param str message: An explanation of the status reason.
        :param str more_info: (optional) Link to documentation about this status
               reason.
        """
        self.code = code
        self.message = message
        self.more_info = more_info

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'BareMetalServerStatusReason':
        """Initialize a BareMetalServerStatusReason object from a json dictionary."""
        args = {}
        if 'code' in _dict:
            args['code'] = _dict.get('code')
        else:
            raise ValueError('Required property \'code\' not present in BareMetalServerStatusReason JSON')
        if 'message' in _dict:
            args['message'] = _dict.get('message')
        else:
            raise ValueError('Required property \'message\' not present in BareMetalServerStatusReason JSON')
        if 'more_info' in _dict:
            args['more_info'] = _dict.get('more_info')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a BareMetalServerStatusReason object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'code') and self.code is not None:
            _dict['code'] = self.code
        if hasattr(self, 'message') and self.message is not None:
            _dict['message'] = self.message
        if hasattr(self, 'more_info') and self.more_info is not None:
            _dict['more_info'] = self.more_info
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this BareMetalServerStatusReason object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'BareMetalServerStatusReason') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'BareMetalServerStatusReason') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class CodeEnum(str, Enum):
        """
        The status reason code:
        - `cannot_start`: Failed to start due to an internal error
        - `cannot_start_capacity`: Insufficient capacity within the selected zone
        - `cannot_start_compute`: An error occurred while allocating compute resources
        - `cannot_start_ip_address`: An error occurred while allocating an IP address
        - `cannot_start_network`: An error occurred while allocating network resources.
        """

        CANNOT_START = 'cannot_start'
        CANNOT_START_CAPACITY = 'cannot_start_capacity'
        CANNOT_START_COMPUTE = 'cannot_start_compute'
        CANNOT_START_IP_ADDRESS = 'cannot_start_ip_address'
        CANNOT_START_NETWORK = 'cannot_start_network'



class BareMetalServerTrustedPlatformModule:
    """
    BareMetalServerTrustedPlatformModule.

    :attr bool enabled: Indicates whether the trusted platform module is enabled.
    :attr str mode: The trusted platform module (TPM) mode:
          - `disabled`: No TPM functionality
          - `tpm_2`: TPM 2.0
          The enumerated values for this property are expected to expand in the future.
          When processing this property, check for and log unknown values. Optionally halt
          processing and surface the error, or bypass the resource on which the unexpected
          property value was encountered.
    :attr List[str] supported_modes: The supported trusted platform module modes.
    """

    def __init__(
        self,
        enabled: bool,
        mode: str,
        supported_modes: List[str],
    ) -> None:
        """
        Initialize a BareMetalServerTrustedPlatformModule object.

        :param bool enabled: Indicates whether the trusted platform module is
               enabled.
        :param str mode: The trusted platform module (TPM) mode:
               - `disabled`: No TPM functionality
               - `tpm_2`: TPM 2.0
               The enumerated values for this property are expected to expand in the
               future. When processing this property, check for and log unknown values.
               Optionally halt processing and surface the error, or bypass the resource on
               which the unexpected property value was encountered.
        :param List[str] supported_modes: The supported trusted platform module
               modes.
        """
        self.enabled = enabled
        self.mode = mode
        self.supported_modes = supported_modes

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'BareMetalServerTrustedPlatformModule':
        """Initialize a BareMetalServerTrustedPlatformModule object from a json dictionary."""
        args = {}
        if 'enabled' in _dict:
            args['enabled'] = _dict.get('enabled')
        else:
            raise ValueError('Required property \'enabled\' not present in BareMetalServerTrustedPlatformModule JSON')
        if 'mode' in _dict:
            args['mode'] = _dict.get('mode')
        else:
            raise ValueError('Required property \'mode\' not present in BareMetalServerTrustedPlatformModule JSON')
        if 'supported_modes' in _dict:
            args['supported_modes'] = _dict.get('supported_modes')
        else:
            raise ValueError('Required property \'supported_modes\' not present in BareMetalServerTrustedPlatformModule JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a BareMetalServerTrustedPlatformModule object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'enabled') and self.enabled is not None:
            _dict['enabled'] = self.enabled
        if hasattr(self, 'mode') and self.mode is not None:
            _dict['mode'] = self.mode
        if hasattr(self, 'supported_modes') and self.supported_modes is not None:
            _dict['supported_modes'] = self.supported_modes
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this BareMetalServerTrustedPlatformModule object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'BareMetalServerTrustedPlatformModule') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'BareMetalServerTrustedPlatformModule') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ModeEnum(str, Enum):
        """
        The trusted platform module (TPM) mode:
        - `disabled`: No TPM functionality
        - `tpm_2`: TPM 2.0
        The enumerated values for this property are expected to expand in the future. When
        processing this property, check for and log unknown values. Optionally halt
        processing and surface the error, or bypass the resource on which the unexpected
        property value was encountered.
        """

        DISABLED = 'disabled'
        TPM_2 = 'tpm_2'


    class SupportedModesEnum(str, Enum):
        """
        The trusted platform module (TPM) mode:
        - `disabled`: No TPM functionality
        - `tpm_2`: TPM 2.0
        The enumerated values for this property are expected to expand in the future. When
        processing this property, check for and log unknown values. Optionally halt
        processing and surface the error, or bypass the resource on which the unexpected
        property value was encountered.
        """

        DISABLED = 'disabled'
        TPM_2 = 'tpm_2'



class BareMetalServerTrustedPlatformModulePatch:
    """
    BareMetalServerTrustedPlatformModulePatch.

    :attr str mode: (optional) The trusted platform module mode to use. The
          specified value must be listed in the bare metal server's `supported_modes`.
          For the trusted platform module mode to be changed, the bare metal server
          `status` must be `stopped`.
    """

    def __init__(
        self,
        *,
        mode: str = None,
    ) -> None:
        """
        Initialize a BareMetalServerTrustedPlatformModulePatch object.

        :param str mode: (optional) The trusted platform module mode to use. The
               specified value must be listed in the bare metal server's
               `supported_modes`.
               For the trusted platform module mode to be changed, the bare metal server
               `status` must be `stopped`.
        """
        self.mode = mode

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'BareMetalServerTrustedPlatformModulePatch':
        """Initialize a BareMetalServerTrustedPlatformModulePatch object from a json dictionary."""
        args = {}
        if 'mode' in _dict:
            args['mode'] = _dict.get('mode')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a BareMetalServerTrustedPlatformModulePatch object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _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 BareMetalServerTrustedPlatformModulePatch object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'BareMetalServerTrustedPlatformModulePatch') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'BareMetalServerTrustedPlatformModulePatch') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ModeEnum(str, Enum):
        """
        The trusted platform module mode to use. The specified value must be listed in the
        bare metal server's `supported_modes`.
        For the trusted platform module mode to be changed, the bare metal server `status`
        must be `stopped`.
        """

        DISABLED = 'disabled'
        TPM_2 = 'tpm_2'



class BareMetalServerTrustedPlatformModulePrototype:
    """
    BareMetalServerTrustedPlatformModulePrototype.

    :attr str mode: (optional) The trusted platform module mode to use. The
          specified value must be listed in the bare metal server profile's
          `supported_trusted_platform_module_modes`.
    """

    def __init__(
        self,
        *,
        mode: str = None,
    ) -> None:
        """
        Initialize a BareMetalServerTrustedPlatformModulePrototype object.

        :param str mode: (optional) The trusted platform module mode to use. The
               specified value must be listed in the bare metal server profile's
               `supported_trusted_platform_module_modes`.
        """
        self.mode = mode

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'BareMetalServerTrustedPlatformModulePrototype':
        """Initialize a BareMetalServerTrustedPlatformModulePrototype object from a json dictionary."""
        args = {}
        if 'mode' in _dict:
            args['mode'] = _dict.get('mode')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a BareMetalServerTrustedPlatformModulePrototype object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _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 BareMetalServerTrustedPlatformModulePrototype object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'BareMetalServerTrustedPlatformModulePrototype') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'BareMetalServerTrustedPlatformModulePrototype') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ModeEnum(str, Enum):
        """
        The trusted platform module mode to use. The specified value must be listed in the
        bare metal server profile's `supported_trusted_platform_module_modes`.
        """

        DISABLED = 'disabled'
        TPM_2 = 'tpm_2'



class CatalogOfferingIdentity:
    """
    Identifies a
    [catalog](https://cloud.ibm.com/docs/account?topic=account-restrict-by-user) offering
    by a unique property.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a CatalogOfferingIdentity object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['CatalogOfferingIdentityCatalogOfferingByCRN'])
        )
        raise Exception(msg)


class CatalogOfferingVersionIdentity:
    """
    Identifies a version of a
    [catalog](https://cloud.ibm.com/docs/account?topic=account-restrict-by-user) offering
    by a unique property.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a CatalogOfferingVersionIdentity object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['CatalogOfferingVersionIdentityCatalogOfferingVersionByCRN'])
        )
        raise Exception(msg)


class CatalogOfferingVersionReference:
    """
    CatalogOfferingVersionReference.

    :attr str crn: The CRN for this version of a
          [catalog](https://cloud.ibm.com/docs/account?topic=account-restrict-by-user)
          offering.
    """

    def __init__(
        self,
        crn: str,
    ) -> None:
        """
        Initialize a CatalogOfferingVersionReference object.

        :param str crn: The CRN for this version of a
               [catalog](https://cloud.ibm.com/docs/account?topic=account-restrict-by-user)
               offering.
        """
        self.crn = crn

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'CatalogOfferingVersionReference':
        """Initialize a CatalogOfferingVersionReference object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError('Required property \'crn\' not present in CatalogOfferingVersionReference JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a CatalogOfferingVersionReference object from 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 CatalogOfferingVersionReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'CatalogOfferingVersionReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'CatalogOfferingVersionReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class CertificateInstanceIdentity:
    """
    Identifies a certificate instance by a unique property.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a CertificateInstanceIdentity object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['CertificateInstanceIdentityByCRN'])
        )
        raise Exception(msg)


class CertificateInstanceReference:
    """
    CertificateInstanceReference.

    :attr str crn: The CRN for this certificate instance.
    """

    def __init__(
        self,
        crn: str,
    ) -> None:
        """
        Initialize a CertificateInstanceReference object.

        :param str crn: The CRN for this certificate instance.
        """
        self.crn = crn

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'CertificateInstanceReference':
        """Initialize a CertificateInstanceReference object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError('Required property \'crn\' not present in CertificateInstanceReference JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a CertificateInstanceReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this CertificateInstanceReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'CertificateInstanceReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'CertificateInstanceReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class CloudObjectStorageBucketIdentity:
    """
    Identifies a Cloud Object Storage bucket by a unique property.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a CloudObjectStorageBucketIdentity object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['CloudObjectStorageBucketIdentityCloudObjectStorageBucketIdentityByName', 'CloudObjectStorageBucketIdentityByCRN'])
        )
        raise Exception(msg)


class CloudObjectStorageBucketReference:
    """
    CloudObjectStorageBucketReference.

    :attr str crn: The CRN of this Cloud Object Storage bucket.
    :attr str name: The globally unique name of this Cloud Object Storage bucket.
    """

    def __init__(
        self,
        crn: str,
        name: str,
    ) -> None:
        """
        Initialize a CloudObjectStorageBucketReference object.

        :param str crn: The CRN of this Cloud Object Storage bucket.
        :param str name: The globally unique name of this Cloud Object Storage
               bucket.
        """
        self.crn = crn
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'CloudObjectStorageBucketReference':
        """Initialize a CloudObjectStorageBucketReference object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError('Required property \'crn\' not present in CloudObjectStorageBucketReference JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in CloudObjectStorageBucketReference JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a CloudObjectStorageBucketReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this CloudObjectStorageBucketReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'CloudObjectStorageBucketReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'CloudObjectStorageBucketReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class CloudObjectStorageObjectReference:
    """
    CloudObjectStorageObjectReference.

    :attr str name: The name of this Cloud Object Storage object. Names are unique
          within a Cloud Object Storage bucket.
    """

    def __init__(
        self,
        name: str,
    ) -> None:
        """
        Initialize a CloudObjectStorageObjectReference object.

        :param str name: The name of this Cloud Object Storage object. Names are
               unique within a Cloud Object Storage bucket.
        """
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'CloudObjectStorageObjectReference':
        """Initialize a CloudObjectStorageObjectReference object from a json dictionary."""
        args = {}
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in CloudObjectStorageObjectReference JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a CloudObjectStorageObjectReference object from 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 CloudObjectStorageObjectReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'CloudObjectStorageObjectReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'CloudObjectStorageObjectReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class DNSInstanceIdentity:
    """
    Identifies a DNS instance by a unique property.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a DNSInstanceIdentity object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['DNSInstanceIdentityByCRN'])
        )
        raise Exception(msg)


class DNSInstanceReference:
    """
    DNSInstanceReference.

    :attr str crn: The CRN for this DNS instance.
    """

    def __init__(
        self,
        crn: str,
    ) -> None:
        """
        Initialize a DNSInstanceReference object.

        :param str crn: The CRN for this DNS instance.
        """
        self.crn = crn

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'DNSInstanceReference':
        """Initialize a DNSInstanceReference object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError('Required property \'crn\' not present in DNSInstanceReference JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a DNSInstanceReference object from 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 DNSInstanceReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'DNSInstanceReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'DNSInstanceReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class DNSServer:
    """
    A DNS server.

    :attr str address: The IP address.
          This property may add support for IPv6 addresses in the future. When processing
          a value in this property, verify that the address is in an expected format. If
          it is not, log an error. Optionally halt processing and surface the error, or
          bypass the resource on which the unexpected IP address format was encountered.
    :attr ZoneReference zone_affinity: (optional) If present, DHCP configuration for
          this zone will have this DNS server listed first.
    """

    def __init__(
        self,
        address: str,
        *,
        zone_affinity: 'ZoneReference' = None,
    ) -> None:
        """
        Initialize a DNSServer object.

        :param str address: The IP address.
               This property may add support for IPv6 addresses in the future. When
               processing a value in this property, verify that the address is in an
               expected format. If it is not, log an error. Optionally halt processing and
               surface the error, or bypass the resource on which the unexpected IP
               address format was encountered.
        :param ZoneReference zone_affinity: (optional) If present, DHCP
               configuration for this zone will have this DNS server listed first.
        """
        self.address = address
        self.zone_affinity = zone_affinity

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'DNSServer':
        """Initialize a DNSServer object from a json dictionary."""
        args = {}
        if 'address' in _dict:
            args['address'] = _dict.get('address')
        else:
            raise ValueError('Required property \'address\' not present in DNSServer JSON')
        if 'zone_affinity' in _dict:
            args['zone_affinity'] = ZoneReference.from_dict(_dict.get('zone_affinity'))
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a DNSServer object from 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, 'zone_affinity') and self.zone_affinity is not None:
            if isinstance(self.zone_affinity, dict):
                _dict['zone_affinity'] = self.zone_affinity
            else:
                _dict['zone_affinity'] = self.zone_affinity.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 DNSServer object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'DNSServer') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'DNSServer') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class DNSServerPrototype:
    """
    DNSServerPrototype.

    :attr str address: The IP address.
          This property may add support for IPv6 addresses in the future. When processing
          a value in this property, verify that the address is in an expected format. If
          it is not, log an error. Optionally halt processing and surface the error, or
          bypass the resource on which the unexpected IP address format was encountered.
    :attr ZoneIdentity zone_affinity: (optional) DHCP configuration for the
          specified zone will have this DNS server listed first.
    """

    def __init__(
        self,
        address: str,
        *,
        zone_affinity: 'ZoneIdentity' = None,
    ) -> None:
        """
        Initialize a DNSServerPrototype object.

        :param str address: The IP address.
               This property may add support for IPv6 addresses in the future. When
               processing a value in this property, verify that the address is in an
               expected format. If it is not, log an error. Optionally halt processing and
               surface the error, or bypass the resource on which the unexpected IP
               address format was encountered.
        :param ZoneIdentity zone_affinity: (optional) DHCP configuration for the
               specified zone will have this DNS server listed first.
        """
        self.address = address
        self.zone_affinity = zone_affinity

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'DNSServerPrototype':
        """Initialize a DNSServerPrototype object from a json dictionary."""
        args = {}
        if 'address' in _dict:
            args['address'] = _dict.get('address')
        else:
            raise ValueError('Required property \'address\' not present in DNSServerPrototype JSON')
        if 'zone_affinity' in _dict:
            args['zone_affinity'] = _dict.get('zone_affinity')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a DNSServerPrototype object from 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, 'zone_affinity') and self.zone_affinity is not None:
            if isinstance(self.zone_affinity, dict):
                _dict['zone_affinity'] = self.zone_affinity
            else:
                _dict['zone_affinity'] = self.zone_affinity.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 DNSServerPrototype object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'DNSServerPrototype') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'DNSServerPrototype') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class DNSZoneIdentity:
    """
    Identifies a DNS zone by a unique property.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a DNSZoneIdentity object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['DNSZoneIdentityById'])
        )
        raise Exception(msg)


class DNSZoneReference:
    """
    DNSZoneReference.

    :attr str id:
    """

    def __init__(
        self,
        id: str,
    ) -> None:
        """
        Initialize a DNSZoneReference object.

        :param str id:
        """
        self.id = id

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'DNSZoneReference':
        """Initialize a DNSZoneReference object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in DNSZoneReference JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a DNSZoneReference object from 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 DNSZoneReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'DNSZoneReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'DNSZoneReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class DedicatedHost:
    """
    DedicatedHost.

    :attr int available_memory: The amount of memory in gibibytes that is currently
          available for instances.
    :attr VCPU available_vcpu: The available VCPU for the dedicated host.
    :attr datetime created_at: The date and time that the dedicated host was
          created.
    :attr str crn: The CRN for this dedicated host.
    :attr List[DedicatedHostDisk] disks: Collection of the dedicated host's disks.
    :attr DedicatedHostGroupReference group: The dedicated host group this dedicated
          host is in.
    :attr str href: The URL for this dedicated host.
    :attr str id: The unique identifier for this dedicated host.
    :attr bool instance_placement_enabled: If set to true, instances can be placed
          on this dedicated host.
    :attr List[InstanceReference] instances: The instances that are allocated to
          this dedicated host.
    :attr str lifecycle_state: The lifecycle state of the dedicated host.
    :attr int memory: The total amount of memory in gibibytes for this host.
    :attr str name: The name for this dedicated host. The name is unique across all
          dedicated hosts in the region.
    :attr DedicatedHostNUMA numa: The dedicated host NUMA configuration.
    :attr DedicatedHostProfileReference profile: The
          [profile](https://cloud.ibm.com/docs/vpc?topic=vpc-dh-profiles) for this
          dedicated host.
    :attr bool provisionable: Indicates whether this dedicated host is available for
          instance creation.
    :attr ResourceGroupReference resource_group: The resource group for this
          dedicated host.
    :attr str resource_type: The resource type.
    :attr int socket_count: The total number of sockets for this host.
    :attr str state: The administrative state of the dedicated host.
          The enumerated values for this property are expected to expand in the future.
          When processing this property, check for and log unknown values. Optionally halt
          processing and surface the error, or bypass the dedicated host on which the
          unexpected property value was encountered.
    :attr List[InstanceProfileReference] supported_instance_profiles: The instance
          profiles usable by instances placed on this dedicated host.
    :attr VCPU vcpu: The total VCPU of the dedicated host.
    :attr ZoneReference zone: The zone this dedicated host resides in.
    """

    def __init__(
        self,
        available_memory: int,
        available_vcpu: 'VCPU',
        created_at: datetime,
        crn: str,
        disks: List['DedicatedHostDisk'],
        group: 'DedicatedHostGroupReference',
        href: str,
        id: str,
        instance_placement_enabled: bool,
        instances: List['InstanceReference'],
        lifecycle_state: str,
        memory: int,
        name: str,
        numa: 'DedicatedHostNUMA',
        profile: 'DedicatedHostProfileReference',
        provisionable: bool,
        resource_group: 'ResourceGroupReference',
        resource_type: str,
        socket_count: int,
        state: str,
        supported_instance_profiles: List['InstanceProfileReference'],
        vcpu: 'VCPU',
        zone: 'ZoneReference',
    ) -> None:
        """
        Initialize a DedicatedHost object.

        :param int available_memory: The amount of memory in gibibytes that is
               currently available for instances.
        :param VCPU available_vcpu: The available VCPU for the dedicated host.
        :param datetime created_at: The date and time that the dedicated host was
               created.
        :param str crn: The CRN for this dedicated host.
        :param List[DedicatedHostDisk] disks: Collection of the dedicated host's
               disks.
        :param DedicatedHostGroupReference group: The dedicated host group this
               dedicated host is in.
        :param str href: The URL for this dedicated host.
        :param str id: The unique identifier for this dedicated host.
        :param bool instance_placement_enabled: If set to true, instances can be
               placed on this dedicated host.
        :param List[InstanceReference] instances: The instances that are allocated
               to this dedicated host.
        :param str lifecycle_state: The lifecycle state of the dedicated host.
        :param int memory: The total amount of memory in gibibytes for this host.
        :param str name: The name for this dedicated host. The name is unique
               across all dedicated hosts in the region.
        :param DedicatedHostNUMA numa: The dedicated host NUMA configuration.
        :param DedicatedHostProfileReference profile: The
               [profile](https://cloud.ibm.com/docs/vpc?topic=vpc-dh-profiles) for this
               dedicated host.
        :param bool provisionable: Indicates whether this dedicated host is
               available for instance creation.
        :param ResourceGroupReference resource_group: The resource group for this
               dedicated host.
        :param str resource_type: The resource type.
        :param int socket_count: The total number of sockets for this host.
        :param str state: The administrative state of the dedicated host.
               The enumerated values for this property are expected to expand in the
               future. When processing this property, check for and log unknown values.
               Optionally halt processing and surface the error, or bypass the dedicated
               host on which the unexpected property value was encountered.
        :param List[InstanceProfileReference] supported_instance_profiles: The
               instance profiles usable by instances placed on this dedicated host.
        :param VCPU vcpu: The total VCPU of the dedicated host.
        :param ZoneReference zone: The zone this dedicated host resides in.
        """
        self.available_memory = available_memory
        self.available_vcpu = available_vcpu
        self.created_at = created_at
        self.crn = crn
        self.disks = disks
        self.group = group
        self.href = href
        self.id = id
        self.instance_placement_enabled = instance_placement_enabled
        self.instances = instances
        self.lifecycle_state = lifecycle_state
        self.memory = memory
        self.name = name
        self.numa = numa
        self.profile = profile
        self.provisionable = provisionable
        self.resource_group = resource_group
        self.resource_type = resource_type
        self.socket_count = socket_count
        self.state = state
        self.supported_instance_profiles = supported_instance_profiles
        self.vcpu = vcpu
        self.zone = zone

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'DedicatedHost':
        """Initialize a DedicatedHost object from a json dictionary."""
        args = {}
        if 'available_memory' in _dict:
            args['available_memory'] = _dict.get('available_memory')
        else:
            raise ValueError('Required property \'available_memory\' not present in DedicatedHost JSON')
        if 'available_vcpu' in _dict:
            args['available_vcpu'] = VCPU.from_dict(_dict.get('available_vcpu'))
        else:
            raise ValueError('Required property \'available_vcpu\' not present in DedicatedHost JSON')
        if 'created_at' in _dict:
            args['created_at'] = string_to_datetime(_dict.get('created_at'))
        else:
            raise ValueError('Required property \'created_at\' not present in DedicatedHost JSON')
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError('Required property \'crn\' not present in DedicatedHost JSON')
        if 'disks' in _dict:
            args['disks'] = [DedicatedHostDisk.from_dict(v) for v in _dict.get('disks')]
        else:
            raise ValueError('Required property \'disks\' not present in DedicatedHost JSON')
        if 'group' in _dict:
            args['group'] = DedicatedHostGroupReference.from_dict(_dict.get('group'))
        else:
            raise ValueError('Required property \'group\' not present in DedicatedHost JSON')
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in DedicatedHost JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in DedicatedHost JSON')
        if 'instance_placement_enabled' in _dict:
            args['instance_placement_enabled'] = _dict.get('instance_placement_enabled')
        else:
            raise ValueError('Required property \'instance_placement_enabled\' not present in DedicatedHost JSON')
        if 'instances' in _dict:
            args['instances'] = [InstanceReference.from_dict(v) for v in _dict.get('instances')]
        else:
            raise ValueError('Required property \'instances\' not present in DedicatedHost JSON')
        if 'lifecycle_state' in _dict:
            args['lifecycle_state'] = _dict.get('lifecycle_state')
        else:
            raise ValueError('Required property \'lifecycle_state\' not present in DedicatedHost JSON')
        if 'memory' in _dict:
            args['memory'] = _dict.get('memory')
        else:
            raise ValueError('Required property \'memory\' not present in DedicatedHost JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in DedicatedHost JSON')
        if 'numa' in _dict:
            args['numa'] = DedicatedHostNUMA.from_dict(_dict.get('numa'))
        else:
            raise ValueError('Required property \'numa\' not present in DedicatedHost JSON')
        if 'profile' in _dict:
            args['profile'] = DedicatedHostProfileReference.from_dict(_dict.get('profile'))
        else:
            raise ValueError('Required property \'profile\' not present in DedicatedHost JSON')
        if 'provisionable' in _dict:
            args['provisionable'] = _dict.get('provisionable')
        else:
            raise ValueError('Required property \'provisionable\' not present in DedicatedHost JSON')
        if 'resource_group' in _dict:
            args['resource_group'] = ResourceGroupReference.from_dict(_dict.get('resource_group'))
        else:
            raise ValueError('Required property \'resource_group\' not present in DedicatedHost JSON')
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError('Required property \'resource_type\' not present in DedicatedHost JSON')
        if 'socket_count' in _dict:
            args['socket_count'] = _dict.get('socket_count')
        else:
            raise ValueError('Required property \'socket_count\' not present in DedicatedHost JSON')
        if 'state' in _dict:
            args['state'] = _dict.get('state')
        else:
            raise ValueError('Required property \'state\' not present in DedicatedHost JSON')
        if 'supported_instance_profiles' in _dict:
            args['supported_instance_profiles'] = [InstanceProfileReference.from_dict(v) for v in _dict.get('supported_instance_profiles')]
        else:
            raise ValueError('Required property \'supported_instance_profiles\' not present in DedicatedHost JSON')
        if 'vcpu' in _dict:
            args['vcpu'] = VCPU.from_dict(_dict.get('vcpu'))
        else:
            raise ValueError('Required property \'vcpu\' not present in DedicatedHost JSON')
        if 'zone' in _dict:
            args['zone'] = ZoneReference.from_dict(_dict.get('zone'))
        else:
            raise ValueError('Required property \'zone\' not present in DedicatedHost JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a DedicatedHost object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'available_memory') and self.available_memory is not None:
            _dict['available_memory'] = self.available_memory
        if hasattr(self, 'available_vcpu') and self.available_vcpu is not None:
            if isinstance(self.available_vcpu, dict):
                _dict['available_vcpu'] = self.available_vcpu
            else:
                _dict['available_vcpu'] = self.available_vcpu.to_dict()
        if hasattr(self, 'created_at') and self.created_at is not None:
            _dict['created_at'] = datetime_to_string(self.created_at)
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'disks') and self.disks is not None:
            disks_list = []
            for v in self.disks:
                if isinstance(v, dict):
                    disks_list.append(v)
                else:
                    disks_list.append(v.to_dict())
            _dict['disks'] = disks_list
        if hasattr(self, 'group') and self.group is not None:
            if isinstance(self.group, dict):
                _dict['group'] = self.group
            else:
                _dict['group'] = self.group.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'instance_placement_enabled') and self.instance_placement_enabled is not None:
            _dict['instance_placement_enabled'] = self.instance_placement_enabled
        if hasattr(self, 'instances') and self.instances is not None:
            instances_list = []
            for v in self.instances:
                if isinstance(v, dict):
                    instances_list.append(v)
                else:
                    instances_list.append(v.to_dict())
            _dict['instances'] = instances_list
        if hasattr(self, 'lifecycle_state') and self.lifecycle_state is not None:
            _dict['lifecycle_state'] = self.lifecycle_state
        if hasattr(self, 'memory') and self.memory is not None:
            _dict['memory'] = self.memory
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'numa') and self.numa is not None:
            if isinstance(self.numa, dict):
                _dict['numa'] = self.numa
            else:
                _dict['numa'] = self.numa.to_dict()
        if hasattr(self, 'profile') and self.profile is not None:
            if isinstance(self.profile, dict):
                _dict['profile'] = self.profile
            else:
                _dict['profile'] = self.profile.to_dict()
        if hasattr(self, 'provisionable') and self.provisionable is not None:
            _dict['provisionable'] = self.provisionable
        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, 'resource_type') and self.resource_type is not None:
            _dict['resource_type'] = self.resource_type
        if hasattr(self, 'socket_count') and self.socket_count is not None:
            _dict['socket_count'] = self.socket_count
        if hasattr(self, 'state') and self.state is not None:
            _dict['state'] = self.state
        if hasattr(self, 'supported_instance_profiles') and self.supported_instance_profiles is not None:
            supported_instance_profiles_list = []
            for v in self.supported_instance_profiles:
                if isinstance(v, dict):
                    supported_instance_profiles_list.append(v)
                else:
                    supported_instance_profiles_list.append(v.to_dict())
            _dict['supported_instance_profiles'] = supported_instance_profiles_list
        if hasattr(self, 'vcpu') and self.vcpu is not None:
            if isinstance(self.vcpu, dict):
                _dict['vcpu'] = self.vcpu
            else:
                _dict['vcpu'] = self.vcpu.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 DedicatedHost object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'DedicatedHost') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'DedicatedHost') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class LifecycleStateEnum(str, Enum):
        """
        The lifecycle state of the dedicated host.
        """

        DELETING = 'deleting'
        FAILED = 'failed'
        PENDING = 'pending'
        STABLE = 'stable'
        SUSPENDED = 'suspended'
        UPDATING = 'updating'
        WAITING = 'waiting'


    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        DEDICATED_HOST = 'dedicated_host'


    class StateEnum(str, Enum):
        """
        The administrative state of the dedicated host.
        The enumerated values for this property are expected to expand in the future. When
        processing this property, check for and log unknown values. Optionally halt
        processing and surface the error, or bypass the dedicated host on which the
        unexpected property value was encountered.
        """

        AVAILABLE = 'available'
        DEGRADED = 'degraded'
        MIGRATING = 'migrating'
        UNAVAILABLE = 'unavailable'



class DedicatedHostCollection:
    """
    DedicatedHostCollection.

    :attr List[DedicatedHost] dedicated_hosts: Collection of dedicated hosts.
    :attr DedicatedHostCollectionFirst first: A link to the first page of resources.
    :attr int limit: The maximum number of resources that can be returned by the
          request.
    :attr DedicatedHostCollectionNext next: (optional) A link to the next page of
          resources. This property is present for all pages
          except the last page.
    :attr int total_count: The total number of resources across all pages.
    """

    def __init__(
        self,
        dedicated_hosts: List['DedicatedHost'],
        first: 'DedicatedHostCollectionFirst',
        limit: int,
        total_count: int,
        *,
        next: 'DedicatedHostCollectionNext' = None,
    ) -> None:
        """
        Initialize a DedicatedHostCollection object.

        :param List[DedicatedHost] dedicated_hosts: Collection of dedicated hosts.
        :param DedicatedHostCollectionFirst first: A link to the first page of
               resources.
        :param int limit: The maximum number of resources that can be returned by
               the request.
        :param int total_count: The total number of resources across all pages.
        :param DedicatedHostCollectionNext next: (optional) A link to the next page
               of resources. This property is present for all pages
               except the last page.
        """
        self.dedicated_hosts = dedicated_hosts
        self.first = first
        self.limit = limit
        self.next = next
        self.total_count = total_count

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'DedicatedHostCollection':
        """Initialize a DedicatedHostCollection object from a json dictionary."""
        args = {}
        if 'dedicated_hosts' in _dict:
            args['dedicated_hosts'] = [DedicatedHost.from_dict(v) for v in _dict.get('dedicated_hosts')]
        else:
            raise ValueError('Required property \'dedicated_hosts\' not present in DedicatedHostCollection JSON')
        if 'first' in _dict:
            args['first'] = DedicatedHostCollectionFirst.from_dict(_dict.get('first'))
        else:
            raise ValueError('Required property \'first\' not present in DedicatedHostCollection JSON')
        if 'limit' in _dict:
            args['limit'] = _dict.get('limit')
        else:
            raise ValueError('Required property \'limit\' not present in DedicatedHostCollection JSON')
        if 'next' in _dict:
            args['next'] = DedicatedHostCollectionNext.from_dict(_dict.get('next'))
        if 'total_count' in _dict:
            args['total_count'] = _dict.get('total_count')
        else:
            raise ValueError('Required property \'total_count\' not present in DedicatedHostCollection JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a DedicatedHostCollection object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'dedicated_hosts') and self.dedicated_hosts is not None:
            dedicated_hosts_list = []
            for v in self.dedicated_hosts:
                if isinstance(v, dict):
                    dedicated_hosts_list.append(v)
                else:
                    dedicated_hosts_list.append(v.to_dict())
            _dict['dedicated_hosts'] = dedicated_hosts_list
        if hasattr(self, 'first') and self.first is not None:
            if isinstance(self.first, dict):
                _dict['first'] = self.first
            else:
                _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:
            if isinstance(self.next, dict):
                _dict['next'] = self.next
            else:
                _dict['next'] = self.next.to_dict()
        if hasattr(self, 'total_count') and self.total_count is not None:
            _dict['total_count'] = self.total_count
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this DedicatedHostCollection object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'DedicatedHostCollection') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'DedicatedHostCollection') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class DedicatedHostCollectionFirst:
    """
    A link to the first page of resources.

    :attr str href: The URL for a page of resources.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a DedicatedHostCollectionFirst object.

        :param str href: The URL for a page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'DedicatedHostCollectionFirst':
        """Initialize a DedicatedHostCollectionFirst object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in DedicatedHostCollectionFirst JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a DedicatedHostCollectionFirst object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this DedicatedHostCollectionFirst object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'DedicatedHostCollectionFirst') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'DedicatedHostCollectionFirst') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class DedicatedHostCollectionNext:
    """
    A link to the next page of resources. This property is present for all pages except
    the last page.

    :attr str href: The URL for a page of resources.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a DedicatedHostCollectionNext object.

        :param str href: The URL for a page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'DedicatedHostCollectionNext':
        """Initialize a DedicatedHostCollectionNext object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in DedicatedHostCollectionNext JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a DedicatedHostCollectionNext object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this DedicatedHostCollectionNext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'DedicatedHostCollectionNext') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'DedicatedHostCollectionNext') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class DedicatedHostDisk:
    """
    DedicatedHostDisk.

    :attr int available: The remaining space left for instance placement in GB
          (gigabytes).
    :attr datetime created_at: The date and time that the disk was created.
    :attr str href: The URL for this disk.
    :attr str id: The unique identifier for this disk.
    :attr List[InstanceDiskReference] instance_disks: Instance disks that are on
          this dedicated host disk.
    :attr str interface_type: The disk interface used for attaching the disk
          The enumerated values for this property are expected to expand in the future.
          When processing this property, check for and log unknown values. Optionally halt
          processing and surface the error, or bypass the resource on which the unexpected
          property value was encountered.
    :attr str lifecycle_state: (optional) The lifecycle state of this dedicated host
          disk.
    :attr str name: The name for this dedicated host disk. The name is unique across
          all disks on the dedicated host.
    :attr bool provisionable: Indicates whether this dedicated host disk is
          available for instance disk creation.
    :attr str resource_type: The resource type.
    :attr int size: The size of the disk in GB (gigabytes).
    :attr List[str] supported_instance_interface_types: The instance disk interfaces
          supported for this dedicated host disk.
    """

    def __init__(
        self,
        available: int,
        created_at: datetime,
        href: str,
        id: str,
        instance_disks: List['InstanceDiskReference'],
        interface_type: str,
        name: str,
        provisionable: bool,
        resource_type: str,
        size: int,
        supported_instance_interface_types: List[str],
        *,
        lifecycle_state: str = None,
    ) -> None:
        """
        Initialize a DedicatedHostDisk object.

        :param int available: The remaining space left for instance placement in GB
               (gigabytes).
        :param datetime created_at: The date and time that the disk was created.
        :param str href: The URL for this disk.
        :param str id: The unique identifier for this disk.
        :param List[InstanceDiskReference] instance_disks: Instance disks that are
               on this dedicated host disk.
        :param str interface_type: The disk interface used for attaching the disk
               The enumerated values for this property are expected to expand in the
               future. When processing this property, check for and log unknown values.
               Optionally halt processing and surface the error, or bypass the resource on
               which the unexpected property value was encountered.
        :param str name: The name for this dedicated host disk. The name is unique
               across all disks on the dedicated host.
        :param bool provisionable: Indicates whether this dedicated host disk is
               available for instance disk creation.
        :param str resource_type: The resource type.
        :param int size: The size of the disk in GB (gigabytes).
        :param List[str] supported_instance_interface_types: The instance disk
               interfaces supported for this dedicated host disk.
        :param str lifecycle_state: (optional) The lifecycle state of this
               dedicated host disk.
        """
        self.available = available
        self.created_at = created_at
        self.href = href
        self.id = id
        self.instance_disks = instance_disks
        self.interface_type = interface_type
        self.lifecycle_state = lifecycle_state
        self.name = name
        self.provisionable = provisionable
        self.resource_type = resource_type
        self.size = size
        self.supported_instance_interface_types = supported_instance_interface_types

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'DedicatedHostDisk':
        """Initialize a DedicatedHostDisk object from a json dictionary."""
        args = {}
        if 'available' in _dict:
            args['available'] = _dict.get('available')
        else:
            raise ValueError('Required property \'available\' not present in DedicatedHostDisk JSON')
        if 'created_at' in _dict:
            args['created_at'] = string_to_datetime(_dict.get('created_at'))
        else:
            raise ValueError('Required property \'created_at\' not present in DedicatedHostDisk JSON')
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in DedicatedHostDisk JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in DedicatedHostDisk JSON')
        if 'instance_disks' in _dict:
            args['instance_disks'] = [InstanceDiskReference.from_dict(v) for v in _dict.get('instance_disks')]
        else:
            raise ValueError('Required property \'instance_disks\' not present in DedicatedHostDisk JSON')
        if 'interface_type' in _dict:
            args['interface_type'] = _dict.get('interface_type')
        else:
            raise ValueError('Required property \'interface_type\' not present in DedicatedHostDisk JSON')
        if 'lifecycle_state' in _dict:
            args['lifecycle_state'] = _dict.get('lifecycle_state')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in DedicatedHostDisk JSON')
        if 'provisionable' in _dict:
            args['provisionable'] = _dict.get('provisionable')
        else:
            raise ValueError('Required property \'provisionable\' not present in DedicatedHostDisk JSON')
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError('Required property \'resource_type\' not present in DedicatedHostDisk JSON')
        if 'size' in _dict:
            args['size'] = _dict.get('size')
        else:
            raise ValueError('Required property \'size\' not present in DedicatedHostDisk JSON')
        if 'supported_instance_interface_types' in _dict:
            args['supported_instance_interface_types'] = _dict.get('supported_instance_interface_types')
        else:
            raise ValueError('Required property \'supported_instance_interface_types\' not present in DedicatedHostDisk JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a DedicatedHostDisk object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'available') and self.available is not None:
            _dict['available'] = self.available
        if hasattr(self, 'created_at') and self.created_at is not None:
            _dict['created_at'] = datetime_to_string(self.created_at)
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'instance_disks') and self.instance_disks is not None:
            instance_disks_list = []
            for v in self.instance_disks:
                if isinstance(v, dict):
                    instance_disks_list.append(v)
                else:
                    instance_disks_list.append(v.to_dict())
            _dict['instance_disks'] = instance_disks_list
        if hasattr(self, 'interface_type') and self.interface_type is not None:
            _dict['interface_type'] = self.interface_type
        if hasattr(self, 'lifecycle_state') and self.lifecycle_state is not None:
            _dict['lifecycle_state'] = self.lifecycle_state
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'provisionable') and self.provisionable is not None:
            _dict['provisionable'] = self.provisionable
        if hasattr(self, 'resource_type') and self.resource_type is not None:
            _dict['resource_type'] = self.resource_type
        if hasattr(self, 'size') and self.size is not None:
            _dict['size'] = self.size
        if hasattr(self, 'supported_instance_interface_types') and self.supported_instance_interface_types is not None:
            _dict['supported_instance_interface_types'] = self.supported_instance_interface_types
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this DedicatedHostDisk object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'DedicatedHostDisk') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'DedicatedHostDisk') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class InterfaceTypeEnum(str, Enum):
        """
        The disk interface used for attaching the disk
        The enumerated values for this property are expected to expand in the future. When
        processing this property, check for and log unknown values. Optionally halt
        processing and surface the error, or bypass the resource on which the unexpected
        property value was encountered.
        """

        NVME = 'nvme'


    class LifecycleStateEnum(str, Enum):
        """
        The lifecycle state of this dedicated host disk.
        """

        DELETING = 'deleting'
        FAILED = 'failed'
        PENDING = 'pending'
        STABLE = 'stable'
        SUSPENDED = 'suspended'
        UPDATING = 'updating'
        WAITING = 'waiting'


    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        DEDICATED_HOST_DISK = 'dedicated_host_disk'


    class SupportedInstanceInterfaceTypesEnum(str, Enum):
        """
        The disk interface used for attaching the disk.
        The enumerated values for this property are expected to expand in the future. When
        processing this property, check for and log unknown values. Optionally halt
        processing and surface the error, or bypass the resource on which the unexpected
        property value was encountered.
        """

        NVME = 'nvme'
        VIRTIO_BLK = 'virtio_blk'



class DedicatedHostDiskCollection:
    """
    DedicatedHostDiskCollection.

    :attr List[DedicatedHostDisk] disks: Collection of the dedicated host's disks.
    """

    def __init__(
        self,
        disks: List['DedicatedHostDisk'],
    ) -> None:
        """
        Initialize a DedicatedHostDiskCollection object.

        :param List[DedicatedHostDisk] disks: Collection of the dedicated host's
               disks.
        """
        self.disks = disks

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'DedicatedHostDiskCollection':
        """Initialize a DedicatedHostDiskCollection object from a json dictionary."""
        args = {}
        if 'disks' in _dict:
            args['disks'] = [DedicatedHostDisk.from_dict(v) for v in _dict.get('disks')]
        else:
            raise ValueError('Required property \'disks\' not present in DedicatedHostDiskCollection JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a DedicatedHostDiskCollection object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'disks') and self.disks is not None:
            disks_list = []
            for v in self.disks:
                if isinstance(v, dict):
                    disks_list.append(v)
                else:
                    disks_list.append(v.to_dict())
            _dict['disks'] = disks_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 DedicatedHostDiskCollection object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'DedicatedHostDiskCollection') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'DedicatedHostDiskCollection') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class DedicatedHostDiskPatch:
    """
    DedicatedHostDiskPatch.

    :attr str name: (optional) The name for this dedicated host disk. The name must
          not be used by another disk on the dedicated host.
    """

    def __init__(
        self,
        *,
        name: str = None,
    ) -> None:
        """
        Initialize a DedicatedHostDiskPatch object.

        :param str name: (optional) The name for this dedicated host disk. The name
               must not be used by another disk on the dedicated host.
        """
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'DedicatedHostDiskPatch':
        """Initialize a DedicatedHostDiskPatch object from a json dictionary."""
        args = {}
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a DedicatedHostDiskPatch object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this DedicatedHostDiskPatch object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'DedicatedHostDiskPatch') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'DedicatedHostDiskPatch') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class DedicatedHostGroup:
    """
    DedicatedHostGroup.

    :attr str class_: The dedicated host profile class for hosts in this group.
    :attr datetime created_at: The date and time that the dedicated host group was
          created.
    :attr str crn: The CRN for this dedicated host group.
    :attr List[DedicatedHostReference] dedicated_hosts: The dedicated hosts that are
          in this dedicated host group.
    :attr str family: The dedicated host profile family for hosts in this group.
    :attr str href: The URL for this dedicated host group.
    :attr str id: The unique identifier for this dedicated host group.
    :attr str name: The name for this dedicated host group. The name is unique
          across all dedicated host groups in the region.
    :attr ResourceGroupReference resource_group: The resource group for this
          dedicated host group.
    :attr str resource_type: The resource type.
    :attr List[InstanceProfileReference] supported_instance_profiles: The instance
          profiles usable by instances placed on this dedicated host group.
    :attr ZoneReference zone: The zone this dedicated host group resides in.
    """

    def __init__(
        self,
        class_: str,
        created_at: datetime,
        crn: str,
        dedicated_hosts: List['DedicatedHostReference'],
        family: str,
        href: str,
        id: str,
        name: str,
        resource_group: 'ResourceGroupReference',
        resource_type: str,
        supported_instance_profiles: List['InstanceProfileReference'],
        zone: 'ZoneReference',
    ) -> None:
        """
        Initialize a DedicatedHostGroup object.

        :param str class_: The dedicated host profile class for hosts in this
               group.
        :param datetime created_at: The date and time that the dedicated host group
               was created.
        :param str crn: The CRN for this dedicated host group.
        :param List[DedicatedHostReference] dedicated_hosts: The dedicated hosts
               that are in this dedicated host group.
        :param str family: The dedicated host profile family for hosts in this
               group.
        :param str href: The URL for this dedicated host group.
        :param str id: The unique identifier for this dedicated host group.
        :param str name: The name for this dedicated host group. The name is unique
               across all dedicated host groups in the region.
        :param ResourceGroupReference resource_group: The resource group for this
               dedicated host group.
        :param str resource_type: The resource type.
        :param List[InstanceProfileReference] supported_instance_profiles: The
               instance profiles usable by instances placed on this dedicated host group.
        :param ZoneReference zone: The zone this dedicated host group resides in.
        """
        self.class_ = class_
        self.created_at = created_at
        self.crn = crn
        self.dedicated_hosts = dedicated_hosts
        self.family = family
        self.href = href
        self.id = id
        self.name = name
        self.resource_group = resource_group
        self.resource_type = resource_type
        self.supported_instance_profiles = supported_instance_profiles
        self.zone = zone

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'DedicatedHostGroup':
        """Initialize a DedicatedHostGroup object from a json dictionary."""
        args = {}
        if 'class' in _dict:
            args['class_'] = _dict.get('class')
        else:
            raise ValueError('Required property \'class\' not present in DedicatedHostGroup JSON')
        if 'created_at' in _dict:
            args['created_at'] = string_to_datetime(_dict.get('created_at'))
        else:
            raise ValueError('Required property \'created_at\' not present in DedicatedHostGroup JSON')
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError('Required property \'crn\' not present in DedicatedHostGroup JSON')
        if 'dedicated_hosts' in _dict:
            args['dedicated_hosts'] = [DedicatedHostReference.from_dict(v) for v in _dict.get('dedicated_hosts')]
        else:
            raise ValueError('Required property \'dedicated_hosts\' not present in DedicatedHostGroup JSON')
        if 'family' in _dict:
            args['family'] = _dict.get('family')
        else:
            raise ValueError('Required property \'family\' not present in DedicatedHostGroup JSON')
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in DedicatedHostGroup JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in DedicatedHostGroup JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in DedicatedHostGroup JSON')
        if 'resource_group' in _dict:
            args['resource_group'] = ResourceGroupReference.from_dict(_dict.get('resource_group'))
        else:
            raise ValueError('Required property \'resource_group\' not present in DedicatedHostGroup JSON')
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError('Required property \'resource_type\' not present in DedicatedHostGroup JSON')
        if 'supported_instance_profiles' in _dict:
            args['supported_instance_profiles'] = [InstanceProfileReference.from_dict(v) for v in _dict.get('supported_instance_profiles')]
        else:
            raise ValueError('Required property \'supported_instance_profiles\' not present in DedicatedHostGroup JSON')
        if 'zone' in _dict:
            args['zone'] = ZoneReference.from_dict(_dict.get('zone'))
        else:
            raise ValueError('Required property \'zone\' not present in DedicatedHostGroup JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a DedicatedHostGroup object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'class_') and self.class_ is not None:
            _dict['class'] = self.class_
        if hasattr(self, 'created_at') and self.created_at is not None:
            _dict['created_at'] = datetime_to_string(self.created_at)
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'dedicated_hosts') and self.dedicated_hosts is not None:
            dedicated_hosts_list = []
            for v in self.dedicated_hosts:
                if isinstance(v, dict):
                    dedicated_hosts_list.append(v)
                else:
                    dedicated_hosts_list.append(v.to_dict())
            _dict['dedicated_hosts'] = dedicated_hosts_list
        if hasattr(self, 'family') and self.family is not None:
            _dict['family'] = self.family
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'resource_group') and self.resource_group is not None:
            if isinstance(self.resource_group, dict):
                _dict['resource_group'] = self.resource_group
            else:
                _dict['resource_group'] = self.resource_group.to_dict()
        if hasattr(self, 'resource_type') and self.resource_type is not None:
            _dict['resource_type'] = self.resource_type
        if hasattr(self, 'supported_instance_profiles') and self.supported_instance_profiles is not None:
            supported_instance_profiles_list = []
            for v in self.supported_instance_profiles:
                if isinstance(v, dict):
                    supported_instance_profiles_list.append(v)
                else:
                    supported_instance_profiles_list.append(v.to_dict())
            _dict['supported_instance_profiles'] = supported_instance_profiles_list
        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 DedicatedHostGroup object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'DedicatedHostGroup') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'DedicatedHostGroup') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class FamilyEnum(str, Enum):
        """
        The dedicated host profile family for hosts in this group.
        """

        BALANCED = 'balanced'
        COMPUTE = 'compute'
        MEMORY = 'memory'


    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        DEDICATED_HOST_GROUP = 'dedicated_host_group'



class DedicatedHostGroupCollection:
    """
    DedicatedHostGroupCollection.

    :attr DedicatedHostGroupCollectionFirst first: A link to the first page of
          resources.
    :attr List[DedicatedHostGroup] groups: Collection of dedicated host groups.
    :attr int limit: The maximum number of resources that can be returned by the
          request.
    :attr DedicatedHostGroupCollectionNext next: (optional) A link to the next page
          of resources. This property is present for all pages
          except the last page.
    :attr int total_count: The total number of resources across all pages.
    """

    def __init__(
        self,
        first: 'DedicatedHostGroupCollectionFirst',
        groups: List['DedicatedHostGroup'],
        limit: int,
        total_count: int,
        *,
        next: 'DedicatedHostGroupCollectionNext' = None,
    ) -> None:
        """
        Initialize a DedicatedHostGroupCollection object.

        :param DedicatedHostGroupCollectionFirst first: A link to the first page of
               resources.
        :param List[DedicatedHostGroup] groups: Collection of dedicated host
               groups.
        :param int limit: The maximum number of resources that can be returned by
               the request.
        :param int total_count: The total number of resources across all pages.
        :param DedicatedHostGroupCollectionNext next: (optional) A link to the next
               page of resources. This property is present for all pages
               except the last page.
        """
        self.first = first
        self.groups = groups
        self.limit = limit
        self.next = next
        self.total_count = total_count

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'DedicatedHostGroupCollection':
        """Initialize a DedicatedHostGroupCollection object from a json dictionary."""
        args = {}
        if 'first' in _dict:
            args['first'] = DedicatedHostGroupCollectionFirst.from_dict(_dict.get('first'))
        else:
            raise ValueError('Required property \'first\' not present in DedicatedHostGroupCollection JSON')
        if 'groups' in _dict:
            args['groups'] = [DedicatedHostGroup.from_dict(v) for v in _dict.get('groups')]
        else:
            raise ValueError('Required property \'groups\' not present in DedicatedHostGroupCollection JSON')
        if 'limit' in _dict:
            args['limit'] = _dict.get('limit')
        else:
            raise ValueError('Required property \'limit\' not present in DedicatedHostGroupCollection JSON')
        if 'next' in _dict:
            args['next'] = DedicatedHostGroupCollectionNext.from_dict(_dict.get('next'))
        if 'total_count' in _dict:
            args['total_count'] = _dict.get('total_count')
        else:
            raise ValueError('Required property \'total_count\' not present in DedicatedHostGroupCollection JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a DedicatedHostGroupCollection object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'first') and self.first is not None:
            if isinstance(self.first, dict):
                _dict['first'] = self.first
            else:
                _dict['first'] = self.first.to_dict()
        if hasattr(self, 'groups') and self.groups is not None:
            groups_list = []
            for v in self.groups:
                if isinstance(v, dict):
                    groups_list.append(v)
                else:
                    groups_list.append(v.to_dict())
            _dict['groups'] = groups_list
        if hasattr(self, 'limit') and self.limit is not None:
            _dict['limit'] = self.limit
        if hasattr(self, 'next') and self.next is not None:
            if isinstance(self.next, dict):
                _dict['next'] = self.next
            else:
                _dict['next'] = self.next.to_dict()
        if hasattr(self, 'total_count') and self.total_count is not None:
            _dict['total_count'] = self.total_count
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this DedicatedHostGroupCollection object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'DedicatedHostGroupCollection') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'DedicatedHostGroupCollection') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class DedicatedHostGroupCollectionFirst:
    """
    A link to the first page of resources.

    :attr str href: The URL for a page of resources.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a DedicatedHostGroupCollectionFirst object.

        :param str href: The URL for a page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'DedicatedHostGroupCollectionFirst':
        """Initialize a DedicatedHostGroupCollectionFirst object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in DedicatedHostGroupCollectionFirst JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a DedicatedHostGroupCollectionFirst object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this DedicatedHostGroupCollectionFirst object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'DedicatedHostGroupCollectionFirst') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'DedicatedHostGroupCollectionFirst') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class DedicatedHostGroupCollectionNext:
    """
    A link to the next page of resources. This property is present for all pages except
    the last page.

    :attr str href: The URL for a page of resources.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a DedicatedHostGroupCollectionNext object.

        :param str href: The URL for a page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'DedicatedHostGroupCollectionNext':
        """Initialize a DedicatedHostGroupCollectionNext object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in DedicatedHostGroupCollectionNext JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a DedicatedHostGroupCollectionNext object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this DedicatedHostGroupCollectionNext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'DedicatedHostGroupCollectionNext') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'DedicatedHostGroupCollectionNext') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class DedicatedHostGroupIdentity:
    """
    Identifies a dedicated host group by a unique property.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a DedicatedHostGroupIdentity object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['DedicatedHostGroupIdentityById', 'DedicatedHostGroupIdentityByCRN', 'DedicatedHostGroupIdentityByHref'])
        )
        raise Exception(msg)


class DedicatedHostGroupPatch:
    """
    DedicatedHostGroupPatch.

    :attr str name: (optional) The name for this dedicated host group. The name must
          not be used by another dedicated host group in the region.
    """

    def __init__(
        self,
        *,
        name: str = None,
    ) -> None:
        """
        Initialize a DedicatedHostGroupPatch object.

        :param str name: (optional) The name for this dedicated host group. The
               name must not be used by another dedicated host group in the region.
        """
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'DedicatedHostGroupPatch':
        """Initialize a DedicatedHostGroupPatch object from a json dictionary."""
        args = {}
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a DedicatedHostGroupPatch object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this DedicatedHostGroupPatch object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'DedicatedHostGroupPatch') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'DedicatedHostGroupPatch') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class DedicatedHostGroupPrototypeDedicatedHostByZoneContext:
    """
    DedicatedHostGroupPrototypeDedicatedHostByZoneContext.

    :attr str name: (optional) The name for this dedicated host group. The name must
          not be used by another dedicated host group in the region. If unspecified, the
          name will be a hyphenated list of randomly-selected words.
    :attr ResourceGroupIdentity resource_group: (optional) The resource group to
          use. If unspecified, the host's resource group is used.
    """

    def __init__(
        self,
        *,
        name: str = None,
        resource_group: 'ResourceGroupIdentity' = None,
    ) -> None:
        """
        Initialize a DedicatedHostGroupPrototypeDedicatedHostByZoneContext object.

        :param str name: (optional) The name for this dedicated host group. The
               name must not be used by another dedicated host group in the region. If
               unspecified, the name will be a hyphenated list of randomly-selected words.
        :param ResourceGroupIdentity resource_group: (optional) The resource group
               to use. If unspecified, the host's resource group is used.
        """
        self.name = name
        self.resource_group = resource_group

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'DedicatedHostGroupPrototypeDedicatedHostByZoneContext':
        """Initialize a DedicatedHostGroupPrototypeDedicatedHostByZoneContext object from a json dictionary."""
        args = {}
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        if 'resource_group' in _dict:
            args['resource_group'] = _dict.get('resource_group')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a DedicatedHostGroupPrototypeDedicatedHostByZoneContext object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'resource_group') and self.resource_group is not None:
            if isinstance(self.resource_group, dict):
                _dict['resource_group'] = self.resource_group
            else:
                _dict['resource_group'] = self.resource_group.to_dict()
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this DedicatedHostGroupPrototypeDedicatedHostByZoneContext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'DedicatedHostGroupPrototypeDedicatedHostByZoneContext') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'DedicatedHostGroupPrototypeDedicatedHostByZoneContext') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class DedicatedHostGroupReference:
    """
    DedicatedHostGroupReference.

    :attr str crn: The CRN for this dedicated host group.
    :attr DedicatedHostGroupReferenceDeleted deleted: (optional) If present, this
          property indicates the referenced resource has been deleted, and provides
          some supplementary information.
    :attr str href: The URL for this dedicated host group.
    :attr str id: The unique identifier for this dedicated host group.
    :attr str name: The name for this dedicated host group. The name is unique
          across all dedicated host groups in the region.
    :attr str resource_type: The resource type.
    """

    def __init__(
        self,
        crn: str,
        href: str,
        id: str,
        name: str,
        resource_type: str,
        *,
        deleted: 'DedicatedHostGroupReferenceDeleted' = None,
    ) -> None:
        """
        Initialize a DedicatedHostGroupReference object.

        :param str crn: The CRN for this dedicated host group.
        :param str href: The URL for this dedicated host group.
        :param str id: The unique identifier for this dedicated host group.
        :param str name: The name for this dedicated host group. The name is unique
               across all dedicated host groups in the region.
        :param str resource_type: The resource type.
        :param DedicatedHostGroupReferenceDeleted deleted: (optional) If present,
               this property indicates the referenced resource has been deleted, and
               provides
               some supplementary information.
        """
        self.crn = crn
        self.deleted = deleted
        self.href = href
        self.id = id
        self.name = name
        self.resource_type = resource_type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'DedicatedHostGroupReference':
        """Initialize a DedicatedHostGroupReference object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError('Required property \'crn\' not present in DedicatedHostGroupReference JSON')
        if 'deleted' in _dict:
            args['deleted'] = DedicatedHostGroupReferenceDeleted.from_dict(_dict.get('deleted'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in DedicatedHostGroupReference JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in DedicatedHostGroupReference JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in DedicatedHostGroupReference JSON')
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError('Required property \'resource_type\' not present in DedicatedHostGroupReference JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a DedicatedHostGroupReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'deleted') and self.deleted is not None:
            if isinstance(self.deleted, dict):
                _dict['deleted'] = self.deleted
            else:
                _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'resource_type') and self.resource_type is not None:
            _dict['resource_type'] = self.resource_type
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this DedicatedHostGroupReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'DedicatedHostGroupReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'DedicatedHostGroupReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        DEDICATED_HOST_GROUP = 'dedicated_host_group'



class DedicatedHostGroupReferenceDeleted:
    """
    If present, this property indicates the referenced resource has been deleted, and
    provides some supplementary information.

    :attr str more_info: Link to documentation about deleted resources.
    """

    def __init__(
        self,
        more_info: str,
    ) -> None:
        """
        Initialize a DedicatedHostGroupReferenceDeleted object.

        :param str more_info: Link to documentation about deleted resources.
        """
        self.more_info = more_info

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'DedicatedHostGroupReferenceDeleted':
        """Initialize a DedicatedHostGroupReferenceDeleted object from a json dictionary."""
        args = {}
        if 'more_info' in _dict:
            args['more_info'] = _dict.get('more_info')
        else:
            raise ValueError('Required property \'more_info\' not present in DedicatedHostGroupReferenceDeleted JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a DedicatedHostGroupReferenceDeleted object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'more_info') and self.more_info is not None:
            _dict['more_info'] = self.more_info
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this DedicatedHostGroupReferenceDeleted object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'DedicatedHostGroupReferenceDeleted') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'DedicatedHostGroupReferenceDeleted') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class DedicatedHostNUMA:
    """
    The dedicated host NUMA configuration.

    :attr int count: The total number of NUMA nodes for this dedicated host.
    :attr List[DedicatedHostNUMANode] nodes: The NUMA nodes for this dedicated host.
    """

    def __init__(
        self,
        count: int,
        nodes: List['DedicatedHostNUMANode'],
    ) -> None:
        """
        Initialize a DedicatedHostNUMA object.

        :param int count: The total number of NUMA nodes for this dedicated host.
        :param List[DedicatedHostNUMANode] nodes: The NUMA nodes for this dedicated
               host.
        """
        self.count = count
        self.nodes = nodes

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'DedicatedHostNUMA':
        """Initialize a DedicatedHostNUMA object from a json dictionary."""
        args = {}
        if 'count' in _dict:
            args['count'] = _dict.get('count')
        else:
            raise ValueError('Required property \'count\' not present in DedicatedHostNUMA JSON')
        if 'nodes' in _dict:
            args['nodes'] = [DedicatedHostNUMANode.from_dict(v) for v in _dict.get('nodes')]
        else:
            raise ValueError('Required property \'nodes\' not present in DedicatedHostNUMA JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a DedicatedHostNUMA object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'count') and self.count is not None:
            _dict['count'] = self.count
        if hasattr(self, 'nodes') and self.nodes is not None:
            nodes_list = []
            for v in self.nodes:
                if isinstance(v, dict):
                    nodes_list.append(v)
                else:
                    nodes_list.append(v.to_dict())
            _dict['nodes'] = nodes_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 DedicatedHostNUMA object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'DedicatedHostNUMA') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'DedicatedHostNUMA') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class DedicatedHostNUMANode:
    """
    The dedicated host NUMA node configuration.

    :attr int available_vcpu: The available VCPU for this NUMA node.
    :attr int vcpu: The total VCPU capacity for this NUMA node.
    """

    def __init__(
        self,
        available_vcpu: int,
        vcpu: int,
    ) -> None:
        """
        Initialize a DedicatedHostNUMANode object.

        :param int available_vcpu: The available VCPU for this NUMA node.
        :param int vcpu: The total VCPU capacity for this NUMA node.
        """
        self.available_vcpu = available_vcpu
        self.vcpu = vcpu

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'DedicatedHostNUMANode':
        """Initialize a DedicatedHostNUMANode object from a json dictionary."""
        args = {}
        if 'available_vcpu' in _dict:
            args['available_vcpu'] = _dict.get('available_vcpu')
        else:
            raise ValueError('Required property \'available_vcpu\' not present in DedicatedHostNUMANode JSON')
        if 'vcpu' in _dict:
            args['vcpu'] = _dict.get('vcpu')
        else:
            raise ValueError('Required property \'vcpu\' not present in DedicatedHostNUMANode JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a DedicatedHostNUMANode object from 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_vcpu') and self.available_vcpu is not None:
            _dict['available_vcpu'] = self.available_vcpu
        if hasattr(self, 'vcpu') and self.vcpu is not None:
            _dict['vcpu'] = self.vcpu
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this DedicatedHostNUMANode object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'DedicatedHostNUMANode') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'DedicatedHostNUMANode') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class DedicatedHostPatch:
    """
    DedicatedHostPatch.

    :attr bool instance_placement_enabled: (optional) If set to true, instances can
          be placed on this dedicated host.
    :attr str name: (optional) The name for this dedicated host. The name must not
          be used by another dedicated host in the region.
    """

    def __init__(
        self,
        *,
        instance_placement_enabled: bool = None,
        name: str = None,
    ) -> None:
        """
        Initialize a DedicatedHostPatch object.

        :param bool instance_placement_enabled: (optional) If set to true,
               instances can be placed on this dedicated host.
        :param str name: (optional) The name for this dedicated host. The name must
               not be used by another dedicated host in the region.
        """
        self.instance_placement_enabled = instance_placement_enabled
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'DedicatedHostPatch':
        """Initialize a DedicatedHostPatch object from a json dictionary."""
        args = {}
        if 'instance_placement_enabled' in _dict:
            args['instance_placement_enabled'] = _dict.get('instance_placement_enabled')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a DedicatedHostPatch object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'instance_placement_enabled') and self.instance_placement_enabled is not None:
            _dict['instance_placement_enabled'] = self.instance_placement_enabled
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this DedicatedHostPatch object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'DedicatedHostPatch') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'DedicatedHostPatch') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class DedicatedHostProfile:
    """
    DedicatedHostProfile.

    :attr str class_: The product class this dedicated host profile belongs to.
    :attr List[DedicatedHostProfileDisk] disks: Collection of the dedicated host
          profile's disks.
    :attr str family: The product family this dedicated host profile belongs to
          The enumerated values for this property are expected to expand in the future.
          When processing this property, check for and log unknown values. Optionally halt
          processing and surface the error, or bypass the resource on which the unexpected
          property value was encountered.
    :attr str href: The URL for this dedicated host.
    :attr DedicatedHostProfileMemory memory:
    :attr str name: The globally unique name for this dedicated host profile.
    :attr DedicatedHostProfileSocket socket_count:
    :attr str status: The status of the dedicated host profile:
            - `previous`:  This dedicated host profile is an older revision, but remains
          provisionable
            and usable.
            - `current`:  This profile is the latest revision.
          Note that revisions are indicated by the generation of a dedicated host profile.
           Refer to the [profile naming conventions]
          (https://cloud.ibm.com/docs/vpc?topic=vpc-dh-profiles&interface=ui#profiles-naming-rule)
          for information on how generations are defined within a dedicated host profile.
          The enumerated values for this property are expected to expand in the future.
          When processing this property, check for and log unknown values. Optionally halt
          processing and surface the error, or bypass the profile on which the unexpected
          property value was encountered.
    :attr List[InstanceProfileReference] supported_instance_profiles: The instance
          profiles usable by instances placed on dedicated hosts with this profile.
    :attr DedicatedHostProfileVCPUArchitecture vcpu_architecture:
    :attr DedicatedHostProfileVCPU vcpu_count:
    :attr DedicatedHostProfileVCPUManufacturer vcpu_manufacturer:
    """

    def __init__(
        self,
        class_: str,
        disks: List['DedicatedHostProfileDisk'],
        family: str,
        href: str,
        memory: 'DedicatedHostProfileMemory',
        name: str,
        socket_count: 'DedicatedHostProfileSocket',
        status: str,
        supported_instance_profiles: List['InstanceProfileReference'],
        vcpu_architecture: 'DedicatedHostProfileVCPUArchitecture',
        vcpu_count: 'DedicatedHostProfileVCPU',
        vcpu_manufacturer: 'DedicatedHostProfileVCPUManufacturer',
    ) -> None:
        """
        Initialize a DedicatedHostProfile object.

        :param str class_: The product class this dedicated host profile belongs
               to.
        :param List[DedicatedHostProfileDisk] disks: Collection of the dedicated
               host profile's disks.
        :param str family: The product family this dedicated host profile belongs
               to
               The enumerated values for this property are expected to expand in the
               future. When processing this property, check for and log unknown values.
               Optionally halt processing and surface the error, or bypass the resource on
               which the unexpected property value was encountered.
        :param str href: The URL for this dedicated host.
        :param DedicatedHostProfileMemory memory:
        :param str name: The globally unique name for this dedicated host profile.
        :param DedicatedHostProfileSocket socket_count:
        :param str status: The status of the dedicated host profile:
                 - `previous`:  This dedicated host profile is an older revision, but
               remains provisionable
                 and usable.
                 - `current`:  This profile is the latest revision.
               Note that revisions are indicated by the generation of a dedicated host
               profile.  Refer to the [profile naming conventions]
               (https://cloud.ibm.com/docs/vpc?topic=vpc-dh-profiles&interface=ui#profiles-naming-rule)
               for information on how generations are defined within a dedicated host
               profile.
               The enumerated values for this property are expected to expand in the
               future. When processing this property, check for and log unknown values.
               Optionally halt processing and surface the error, or bypass the profile on
               which the unexpected property value was encountered.
        :param List[InstanceProfileReference] supported_instance_profiles: The
               instance profiles usable by instances placed on dedicated hosts with this
               profile.
        :param DedicatedHostProfileVCPUArchitecture vcpu_architecture:
        :param DedicatedHostProfileVCPU vcpu_count:
        :param DedicatedHostProfileVCPUManufacturer vcpu_manufacturer:
        """
        self.class_ = class_
        self.disks = disks
        self.family = family
        self.href = href
        self.memory = memory
        self.name = name
        self.socket_count = socket_count
        self.status = status
        self.supported_instance_profiles = supported_instance_profiles
        self.vcpu_architecture = vcpu_architecture
        self.vcpu_count = vcpu_count
        self.vcpu_manufacturer = vcpu_manufacturer

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'DedicatedHostProfile':
        """Initialize a DedicatedHostProfile object from a json dictionary."""
        args = {}
        if 'class' in _dict:
            args['class_'] = _dict.get('class')
        else:
            raise ValueError('Required property \'class\' not present in DedicatedHostProfile JSON')
        if 'disks' in _dict:
            args['disks'] = [DedicatedHostProfileDisk.from_dict(v) for v in _dict.get('disks')]
        else:
            raise ValueError('Required property \'disks\' not present in DedicatedHostProfile JSON')
        if 'family' in _dict:
            args['family'] = _dict.get('family')
        else:
            raise ValueError('Required property \'family\' not present in DedicatedHostProfile JSON')
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in DedicatedHostProfile JSON')
        if 'memory' in _dict:
            args['memory'] = _dict.get('memory')
        else:
            raise ValueError('Required property \'memory\' not present in DedicatedHostProfile JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in DedicatedHostProfile JSON')
        if 'socket_count' in _dict:
            args['socket_count'] = _dict.get('socket_count')
        else:
            raise ValueError('Required property \'socket_count\' not present in DedicatedHostProfile JSON')
        if 'status' in _dict:
            args['status'] = _dict.get('status')
        else:
            raise ValueError('Required property \'status\' not present in DedicatedHostProfile JSON')
        if 'supported_instance_profiles' in _dict:
            args['supported_instance_profiles'] = [InstanceProfileReference.from_dict(v) for v in _dict.get('supported_instance_profiles')]
        else:
            raise ValueError('Required property \'supported_instance_profiles\' not present in DedicatedHostProfile JSON')
        if 'vcpu_architecture' in _dict:
            args['vcpu_architecture'] = DedicatedHostProfileVCPUArchitecture.from_dict(_dict.get('vcpu_architecture'))
        else:
            raise ValueError('Required property \'vcpu_architecture\' not present in DedicatedHostProfile JSON')
        if 'vcpu_count' in _dict:
            args['vcpu_count'] = _dict.get('vcpu_count')
        else:
            raise ValueError('Required property \'vcpu_count\' not present in DedicatedHostProfile JSON')
        if 'vcpu_manufacturer' in _dict:
            args['vcpu_manufacturer'] = DedicatedHostProfileVCPUManufacturer.from_dict(_dict.get('vcpu_manufacturer'))
        else:
            raise ValueError('Required property \'vcpu_manufacturer\' not present in DedicatedHostProfile JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a DedicatedHostProfile object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'class_') and self.class_ is not None:
            _dict['class'] = self.class_
        if hasattr(self, 'disks') and self.disks is not None:
            disks_list = []
            for v in self.disks:
                if isinstance(v, dict):
                    disks_list.append(v)
                else:
                    disks_list.append(v.to_dict())
            _dict['disks'] = disks_list
        if hasattr(self, 'family') and self.family is not None:
            _dict['family'] = self.family
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'memory') and self.memory is not None:
            if isinstance(self.memory, dict):
                _dict['memory'] = self.memory
            else:
                _dict['memory'] = self.memory.to_dict()
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'socket_count') and self.socket_count is not None:
            if isinstance(self.socket_count, dict):
                _dict['socket_count'] = self.socket_count
            else:
                _dict['socket_count'] = self.socket_count.to_dict()
        if hasattr(self, 'status') and self.status is not None:
            _dict['status'] = self.status
        if hasattr(self, 'supported_instance_profiles') and self.supported_instance_profiles is not None:
            supported_instance_profiles_list = []
            for v in self.supported_instance_profiles:
                if isinstance(v, dict):
                    supported_instance_profiles_list.append(v)
                else:
                    supported_instance_profiles_list.append(v.to_dict())
            _dict['supported_instance_profiles'] = supported_instance_profiles_list
        if hasattr(self, 'vcpu_architecture') and self.vcpu_architecture is not None:
            if isinstance(self.vcpu_architecture, dict):
                _dict['vcpu_architecture'] = self.vcpu_architecture
            else:
                _dict['vcpu_architecture'] = self.vcpu_architecture.to_dict()
        if hasattr(self, 'vcpu_count') and self.vcpu_count is not None:
            if isinstance(self.vcpu_count, dict):
                _dict['vcpu_count'] = self.vcpu_count
            else:
                _dict['vcpu_count'] = self.vcpu_count.to_dict()
        if hasattr(self, 'vcpu_manufacturer') and self.vcpu_manufacturer is not None:
            if isinstance(self.vcpu_manufacturer, dict):
                _dict['vcpu_manufacturer'] = self.vcpu_manufacturer
            else:
                _dict['vcpu_manufacturer'] = self.vcpu_manufacturer.to_dict()
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this DedicatedHostProfile object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'DedicatedHostProfile') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'DedicatedHostProfile') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class FamilyEnum(str, Enum):
        """
        The product family this dedicated host profile belongs to
        The enumerated values for this property are expected to expand in the future. When
        processing this property, check for and log unknown values. Optionally halt
        processing and surface the error, or bypass the resource on which the unexpected
        property value was encountered.
        """

        BALANCED = 'balanced'
        COMPUTE = 'compute'
        MEMORY = 'memory'


    class StatusEnum(str, Enum):
        """
        The status of the dedicated host profile:
          - `previous`:  This dedicated host profile is an older revision, but remains
        provisionable
          and usable.
          - `current`:  This profile is the latest revision.
        Note that revisions are indicated by the generation of a dedicated host profile.
        Refer to the [profile naming conventions]
        (https://cloud.ibm.com/docs/vpc?topic=vpc-dh-profiles&interface=ui#profiles-naming-rule)
        for information on how generations are defined within a dedicated host profile.
        The enumerated values for this property are expected to expand in the future. When
        processing this property, check for and log unknown values. Optionally halt
        processing and surface the error, or bypass the profile on which the unexpected
        property value was encountered.
        """

        CURRENT = 'current'
        PREVIOUS = 'previous'



class DedicatedHostProfileCollection:
    """
    DedicatedHostProfileCollection.

    :attr DedicatedHostProfileCollectionFirst first: A link to the first page of
          resources.
    :attr int limit: The maximum number of resources that can be returned by the
          request.
    :attr DedicatedHostProfileCollectionNext next: (optional) A link to the next
          page of resources. This property is present for all pages
          except the last page.
    :attr List[DedicatedHostProfile] profiles: Collection of dedicated host
          profiles.
    :attr int total_count: The total number of resources across all pages.
    """

    def __init__(
        self,
        first: 'DedicatedHostProfileCollectionFirst',
        limit: int,
        profiles: List['DedicatedHostProfile'],
        total_count: int,
        *,
        next: 'DedicatedHostProfileCollectionNext' = None,
    ) -> None:
        """
        Initialize a DedicatedHostProfileCollection object.

        :param DedicatedHostProfileCollectionFirst first: A link to the first page
               of resources.
        :param int limit: The maximum number of resources that can be returned by
               the request.
        :param List[DedicatedHostProfile] profiles: Collection of dedicated host
               profiles.
        :param int total_count: The total number of resources across all pages.
        :param DedicatedHostProfileCollectionNext next: (optional) A link to the
               next page of resources. This property is present for all pages
               except the last page.
        """
        self.first = first
        self.limit = limit
        self.next = next
        self.profiles = profiles
        self.total_count = total_count

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'DedicatedHostProfileCollection':
        """Initialize a DedicatedHostProfileCollection object from a json dictionary."""
        args = {}
        if 'first' in _dict:
            args['first'] = DedicatedHostProfileCollectionFirst.from_dict(_dict.get('first'))
        else:
            raise ValueError('Required property \'first\' not present in DedicatedHostProfileCollection JSON')
        if 'limit' in _dict:
            args['limit'] = _dict.get('limit')
        else:
            raise ValueError('Required property \'limit\' not present in DedicatedHostProfileCollection JSON')
        if 'next' in _dict:
            args['next'] = DedicatedHostProfileCollectionNext.from_dict(_dict.get('next'))
        if 'profiles' in _dict:
            args['profiles'] = [DedicatedHostProfile.from_dict(v) for v in _dict.get('profiles')]
        else:
            raise ValueError('Required property \'profiles\' not present in DedicatedHostProfileCollection JSON')
        if 'total_count' in _dict:
            args['total_count'] = _dict.get('total_count')
        else:
            raise ValueError('Required property \'total_count\' not present in DedicatedHostProfileCollection JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a DedicatedHostProfileCollection object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'first') and self.first is not None:
            if isinstance(self.first, dict):
                _dict['first'] = self.first
            else:
                _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:
            if isinstance(self.next, dict):
                _dict['next'] = self.next
            else:
                _dict['next'] = self.next.to_dict()
        if hasattr(self, 'profiles') and self.profiles is not None:
            profiles_list = []
            for v in self.profiles:
                if isinstance(v, dict):
                    profiles_list.append(v)
                else:
                    profiles_list.append(v.to_dict())
            _dict['profiles'] = profiles_list
        if hasattr(self, 'total_count') and self.total_count is not None:
            _dict['total_count'] = self.total_count
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this DedicatedHostProfileCollection object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'DedicatedHostProfileCollection') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'DedicatedHostProfileCollection') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class DedicatedHostProfileCollectionFirst:
    """
    A link to the first page of resources.

    :attr str href: The URL for a page of resources.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a DedicatedHostProfileCollectionFirst object.

        :param str href: The URL for a page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'DedicatedHostProfileCollectionFirst':
        """Initialize a DedicatedHostProfileCollectionFirst object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in DedicatedHostProfileCollectionFirst JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a DedicatedHostProfileCollectionFirst object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this DedicatedHostProfileCollectionFirst object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'DedicatedHostProfileCollectionFirst') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'DedicatedHostProfileCollectionFirst') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class DedicatedHostProfileCollectionNext:
    """
    A link to the next page of resources. This property is present for all pages except
    the last page.

    :attr str href: The URL for a page of resources.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a DedicatedHostProfileCollectionNext object.

        :param str href: The URL for a page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'DedicatedHostProfileCollectionNext':
        """Initialize a DedicatedHostProfileCollectionNext object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in DedicatedHostProfileCollectionNext JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a DedicatedHostProfileCollectionNext object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this DedicatedHostProfileCollectionNext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'DedicatedHostProfileCollectionNext') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'DedicatedHostProfileCollectionNext') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class DedicatedHostProfileDisk:
    """
    Disks provided by this profile.

    :attr DedicatedHostProfileDiskInterface interface_type:
    :attr DedicatedHostProfileDiskQuantity quantity: The number of disks of this
          type for a dedicated host with this profile.
    :attr DedicatedHostProfileDiskSize size: The size of the disk in GB (gigabytes).
    :attr DedicatedHostProfileDiskSupportedInterfaces
          supported_instance_interface_types:
    """

    def __init__(
        self,
        interface_type: 'DedicatedHostProfileDiskInterface',
        quantity: 'DedicatedHostProfileDiskQuantity',
        size: 'DedicatedHostProfileDiskSize',
        supported_instance_interface_types: 'DedicatedHostProfileDiskSupportedInterfaces',
    ) -> None:
        """
        Initialize a DedicatedHostProfileDisk object.

        :param DedicatedHostProfileDiskInterface interface_type:
        :param DedicatedHostProfileDiskQuantity quantity: The number of disks of
               this type for a dedicated host with this profile.
        :param DedicatedHostProfileDiskSize size: The size of the disk in GB
               (gigabytes).
        :param DedicatedHostProfileDiskSupportedInterfaces
               supported_instance_interface_types:
        """
        self.interface_type = interface_type
        self.quantity = quantity
        self.size = size
        self.supported_instance_interface_types = supported_instance_interface_types

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'DedicatedHostProfileDisk':
        """Initialize a DedicatedHostProfileDisk object from a json dictionary."""
        args = {}
        if 'interface_type' in _dict:
            args['interface_type'] = DedicatedHostProfileDiskInterface.from_dict(_dict.get('interface_type'))
        else:
            raise ValueError('Required property \'interface_type\' not present in DedicatedHostProfileDisk JSON')
        if 'quantity' in _dict:
            args['quantity'] = DedicatedHostProfileDiskQuantity.from_dict(_dict.get('quantity'))
        else:
            raise ValueError('Required property \'quantity\' not present in DedicatedHostProfileDisk JSON')
        if 'size' in _dict:
            args['size'] = DedicatedHostProfileDiskSize.from_dict(_dict.get('size'))
        else:
            raise ValueError('Required property \'size\' not present in DedicatedHostProfileDisk JSON')
        if 'supported_instance_interface_types' in _dict:
            args['supported_instance_interface_types'] = DedicatedHostProfileDiskSupportedInterfaces.from_dict(_dict.get('supported_instance_interface_types'))
        else:
            raise ValueError('Required property \'supported_instance_interface_types\' not present in DedicatedHostProfileDisk JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a DedicatedHostProfileDisk object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'interface_type') and self.interface_type is not None:
            if isinstance(self.interface_type, dict):
                _dict['interface_type'] = self.interface_type
            else:
                _dict['interface_type'] = self.interface_type.to_dict()
        if hasattr(self, 'quantity') and self.quantity is not None:
            if isinstance(self.quantity, dict):
                _dict['quantity'] = self.quantity
            else:
                _dict['quantity'] = self.quantity.to_dict()
        if hasattr(self, 'size') and self.size is not None:
            if isinstance(self.size, dict):
                _dict['size'] = self.size
            else:
                _dict['size'] = self.size.to_dict()
        if hasattr(self, 'supported_instance_interface_types') and self.supported_instance_interface_types is not None:
            if isinstance(self.supported_instance_interface_types, dict):
                _dict['supported_instance_interface_types'] = self.supported_instance_interface_types
            else:
                _dict['supported_instance_interface_types'] = self.supported_instance_interface_types.to_dict()
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this DedicatedHostProfileDisk object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'DedicatedHostProfileDisk') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'DedicatedHostProfileDisk') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class DedicatedHostProfileDiskInterface:
    """
    DedicatedHostProfileDiskInterface.

    :attr str type: The type for this profile field.
    :attr str value: The interface of the disk for a dedicated host with this
          profile
          The enumerated values for this property are expected to expand in the future.
          When processing this property, check for and log unknown values. Optionally halt
          processing and surface the error, or bypass the resource on which the unexpected
          property value was encountered.
    """

    def __init__(
        self,
        type: str,
        value: str,
    ) -> None:
        """
        Initialize a DedicatedHostProfileDiskInterface object.

        :param str type: The type for this profile field.
        :param str value: The interface of the disk for a dedicated host with this
               profile
               The enumerated values for this property are expected to expand in the
               future. When processing this property, check for and log unknown values.
               Optionally halt processing and surface the error, or bypass the resource on
               which the unexpected property value was encountered.
        """
        self.type = type
        self.value = value

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'DedicatedHostProfileDiskInterface':
        """Initialize a DedicatedHostProfileDiskInterface object from a json dictionary."""
        args = {}
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in DedicatedHostProfileDiskInterface JSON')
        if 'value' in _dict:
            args['value'] = _dict.get('value')
        else:
            raise ValueError('Required property \'value\' not present in DedicatedHostProfileDiskInterface JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a DedicatedHostProfileDiskInterface object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'type') and self.type is not None:
            _dict['type'] = self.type
        if hasattr(self, 'value') and self.value is not None:
            _dict['value'] = self.value
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this DedicatedHostProfileDiskInterface object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'DedicatedHostProfileDiskInterface') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'DedicatedHostProfileDiskInterface') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class TypeEnum(str, Enum):
        """
        The type for this profile field.
        """

        FIXED = 'fixed'


    class ValueEnum(str, Enum):
        """
        The interface of the disk for a dedicated host with this profile
        The enumerated values for this property are expected to expand in the future. When
        processing this property, check for and log unknown values. Optionally halt
        processing and surface the error, or bypass the resource on which the unexpected
        property value was encountered.
        """

        NVME = 'nvme'



class DedicatedHostProfileDiskQuantity:
    """
    The number of disks of this type for a dedicated host with this profile.

    :attr str type: The type for this profile field.
    :attr int value: The value for this profile field.
    """

    def __init__(
        self,
        type: str,
        value: int,
    ) -> None:
        """
        Initialize a DedicatedHostProfileDiskQuantity object.

        :param str type: The type for this profile field.
        :param int value: The value for this profile field.
        """
        self.type = type
        self.value = value

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'DedicatedHostProfileDiskQuantity':
        """Initialize a DedicatedHostProfileDiskQuantity object from a json dictionary."""
        args = {}
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in DedicatedHostProfileDiskQuantity JSON')
        if 'value' in _dict:
            args['value'] = _dict.get('value')
        else:
            raise ValueError('Required property \'value\' not present in DedicatedHostProfileDiskQuantity JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a DedicatedHostProfileDiskQuantity object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'type') and self.type is not None:
            _dict['type'] = self.type
        if hasattr(self, 'value') and self.value is not None:
            _dict['value'] = self.value
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this DedicatedHostProfileDiskQuantity object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'DedicatedHostProfileDiskQuantity') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'DedicatedHostProfileDiskQuantity') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class TypeEnum(str, Enum):
        """
        The type for this profile field.
        """

        FIXED = 'fixed'



class DedicatedHostProfileDiskSize:
    """
    The size of the disk in GB (gigabytes).

    :attr str type: The type for this profile field.
    :attr int value: The size of the disk in GB (gigabytes).
    """

    def __init__(
        self,
        type: str,
        value: int,
    ) -> None:
        """
        Initialize a DedicatedHostProfileDiskSize object.

        :param str type: The type for this profile field.
        :param int value: The size of the disk in GB (gigabytes).
        """
        self.type = type
        self.value = value

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'DedicatedHostProfileDiskSize':
        """Initialize a DedicatedHostProfileDiskSize object from a json dictionary."""
        args = {}
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in DedicatedHostProfileDiskSize JSON')
        if 'value' in _dict:
            args['value'] = _dict.get('value')
        else:
            raise ValueError('Required property \'value\' not present in DedicatedHostProfileDiskSize JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a DedicatedHostProfileDiskSize object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'type') and self.type is not None:
            _dict['type'] = self.type
        if hasattr(self, 'value') and self.value is not None:
            _dict['value'] = self.value
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this DedicatedHostProfileDiskSize object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'DedicatedHostProfileDiskSize') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'DedicatedHostProfileDiskSize') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class TypeEnum(str, Enum):
        """
        The type for this profile field.
        """

        FIXED = 'fixed'



class DedicatedHostProfileDiskSupportedInterfaces:
    """
    DedicatedHostProfileDiskSupportedInterfaces.

    :attr str type: The type for this profile field.
    :attr List[str] value: The instance disk interfaces supported for a dedicated
          host with this profile.
    """

    def __init__(
        self,
        type: str,
        value: List[str],
    ) -> None:
        """
        Initialize a DedicatedHostProfileDiskSupportedInterfaces object.

        :param str type: The type for this profile field.
        :param List[str] value: The instance disk interfaces supported for a
               dedicated host with this profile.
        """
        self.type = type
        self.value = value

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'DedicatedHostProfileDiskSupportedInterfaces':
        """Initialize a DedicatedHostProfileDiskSupportedInterfaces object from a json dictionary."""
        args = {}
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in DedicatedHostProfileDiskSupportedInterfaces JSON')
        if 'value' in _dict:
            args['value'] = _dict.get('value')
        else:
            raise ValueError('Required property \'value\' not present in DedicatedHostProfileDiskSupportedInterfaces JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a DedicatedHostProfileDiskSupportedInterfaces object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'type') and self.type is not None:
            _dict['type'] = self.type
        if hasattr(self, 'value') and self.value is not None:
            _dict['value'] = self.value
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this DedicatedHostProfileDiskSupportedInterfaces object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'DedicatedHostProfileDiskSupportedInterfaces') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'DedicatedHostProfileDiskSupportedInterfaces') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class TypeEnum(str, Enum):
        """
        The type for this profile field.
        """

        FIXED = 'fixed'


    class ValueEnum(str, Enum):
        """
        The disk interface used for attaching the disk.
        The enumerated values for this property are expected to expand in the future. When
        processing this property, check for and log unknown values. Optionally halt
        processing and surface the error, or bypass the resource on which the unexpected
        property value was encountered.
        """

        NVME = 'nvme'
        VIRTIO_BLK = 'virtio_blk'



class DedicatedHostProfileIdentity:
    """
    Identifies a dedicated host profile by a unique property.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a DedicatedHostProfileIdentity object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['DedicatedHostProfileIdentityByName', 'DedicatedHostProfileIdentityByHref'])
        )
        raise Exception(msg)


class DedicatedHostProfileMemory:
    """
    DedicatedHostProfileMemory.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a DedicatedHostProfileMemory object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['DedicatedHostProfileMemoryFixed', 'DedicatedHostProfileMemoryRange', 'DedicatedHostProfileMemoryEnum', 'DedicatedHostProfileMemoryDependent'])
        )
        raise Exception(msg)


class DedicatedHostProfileReference:
    """
    DedicatedHostProfileReference.

    :attr str href: The URL for this dedicated host.
    :attr str name: The globally unique name for this dedicated host profile.
    """

    def __init__(
        self,
        href: str,
        name: str,
    ) -> None:
        """
        Initialize a DedicatedHostProfileReference object.

        :param str href: The URL for this dedicated host.
        :param str name: The globally unique name for this dedicated host profile.
        """
        self.href = href
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'DedicatedHostProfileReference':
        """Initialize a DedicatedHostProfileReference object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in DedicatedHostProfileReference JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in DedicatedHostProfileReference JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a DedicatedHostProfileReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this DedicatedHostProfileReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'DedicatedHostProfileReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'DedicatedHostProfileReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class DedicatedHostProfileSocket:
    """
    DedicatedHostProfileSocket.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a DedicatedHostProfileSocket object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['DedicatedHostProfileSocketFixed', 'DedicatedHostProfileSocketRange', 'DedicatedHostProfileSocketEnum', 'DedicatedHostProfileSocketDependent'])
        )
        raise Exception(msg)


class DedicatedHostProfileVCPU:
    """
    DedicatedHostProfileVCPU.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a DedicatedHostProfileVCPU object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['DedicatedHostProfileVCPUFixed', 'DedicatedHostProfileVCPURange', 'DedicatedHostProfileVCPUEnum', 'DedicatedHostProfileVCPUDependent'])
        )
        raise Exception(msg)


class DedicatedHostProfileVCPUArchitecture:
    """
    DedicatedHostProfileVCPUArchitecture.

    :attr str type: The type for this profile field.
    :attr str value: The VCPU architecture for a dedicated host with this profile.
    """

    def __init__(
        self,
        type: str,
        value: str,
    ) -> None:
        """
        Initialize a DedicatedHostProfileVCPUArchitecture object.

        :param str type: The type for this profile field.
        :param str value: The VCPU architecture for a dedicated host with this
               profile.
        """
        self.type = type
        self.value = value

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'DedicatedHostProfileVCPUArchitecture':
        """Initialize a DedicatedHostProfileVCPUArchitecture object from a json dictionary."""
        args = {}
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in DedicatedHostProfileVCPUArchitecture JSON')
        if 'value' in _dict:
            args['value'] = _dict.get('value')
        else:
            raise ValueError('Required property \'value\' not present in DedicatedHostProfileVCPUArchitecture JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a DedicatedHostProfileVCPUArchitecture object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'type') and self.type is not None:
            _dict['type'] = self.type
        if hasattr(self, 'value') and self.value is not None:
            _dict['value'] = self.value
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this DedicatedHostProfileVCPUArchitecture object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'DedicatedHostProfileVCPUArchitecture') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'DedicatedHostProfileVCPUArchitecture') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class TypeEnum(str, Enum):
        """
        The type for this profile field.
        """

        FIXED = 'fixed'



class DedicatedHostProfileVCPUManufacturer:
    """
    DedicatedHostProfileVCPUManufacturer.

    :attr str type: The type for this profile field.
    :attr str value: The VCPU manufacturer for a dedicated host with this profile.
    """

    def __init__(
        self,
        type: str,
        value: str,
    ) -> None:
        """
        Initialize a DedicatedHostProfileVCPUManufacturer object.

        :param str type: The type for this profile field.
        :param str value: The VCPU manufacturer for a dedicated host with this
               profile.
        """
        self.type = type
        self.value = value

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'DedicatedHostProfileVCPUManufacturer':
        """Initialize a DedicatedHostProfileVCPUManufacturer object from a json dictionary."""
        args = {}
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in DedicatedHostProfileVCPUManufacturer JSON')
        if 'value' in _dict:
            args['value'] = _dict.get('value')
        else:
            raise ValueError('Required property \'value\' not present in DedicatedHostProfileVCPUManufacturer JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a DedicatedHostProfileVCPUManufacturer object from 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 DedicatedHostProfileVCPUManufacturer object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'DedicatedHostProfileVCPUManufacturer') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'DedicatedHostProfileVCPUManufacturer') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class TypeEnum(str, Enum):
        """
        The type for this profile field.
        """

        FIXED = 'fixed'



class DedicatedHostPrototype:
    """
    DedicatedHostPrototype.

    :attr bool instance_placement_enabled: (optional) If set to true, instances can
          be placed on this dedicated host.
    :attr str name: (optional) The name for this dedicated host. The name must not
          be used by another dedicated host in the region. If unspecified, the name will
          be a hyphenated list of randomly-selected words.
    :attr DedicatedHostProfileIdentity profile: The
          [profile](https://cloud.ibm.com/docs/vpc?topic=vpc-dh-profiles) to use for this
          dedicated host.
    :attr ResourceGroupIdentity resource_group: (optional) The resource group to
          use. If unspecified, the account's [default resource
          group](https://cloud.ibm.com/apidocs/resource-manager#introduction) will be
          used.
    """

    def __init__(
        self,
        profile: 'DedicatedHostProfileIdentity',
        *,
        instance_placement_enabled: bool = None,
        name: str = None,
        resource_group: 'ResourceGroupIdentity' = None,
    ) -> None:
        """
        Initialize a DedicatedHostPrototype object.

        :param DedicatedHostProfileIdentity profile: The
               [profile](https://cloud.ibm.com/docs/vpc?topic=vpc-dh-profiles) to use for
               this
               dedicated host.
        :param bool instance_placement_enabled: (optional) If set to true,
               instances can be placed on this dedicated host.
        :param str name: (optional) The name for this dedicated host. The name must
               not be used by another dedicated host in the region. 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) will be
               used.
        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['DedicatedHostPrototypeDedicatedHostByGroup', 'DedicatedHostPrototypeDedicatedHostByZone'])
        )
        raise Exception(msg)


class DedicatedHostReference:
    """
    DedicatedHostReference.

    :attr str crn: The CRN for this dedicated host.
    :attr DedicatedHostReferenceDeleted deleted: (optional) If present, this
          property indicates the referenced resource has been deleted, and provides
          some supplementary information.
    :attr str href: The URL for this dedicated host.
    :attr str id: The unique identifier for this dedicated host.
    :attr str name: The name for this dedicated host. The name is unique across all
          dedicated hosts in the region.
    :attr str resource_type: The resource type.
    """

    def __init__(
        self,
        crn: str,
        href: str,
        id: str,
        name: str,
        resource_type: str,
        *,
        deleted: 'DedicatedHostReferenceDeleted' = None,
    ) -> None:
        """
        Initialize a DedicatedHostReference object.

        :param str crn: The CRN for this dedicated host.
        :param str href: The URL for this dedicated host.
        :param str id: The unique identifier for this dedicated host.
        :param str name: The name for this dedicated host. The name is unique
               across all dedicated hosts in the region.
        :param str resource_type: The resource type.
        :param DedicatedHostReferenceDeleted deleted: (optional) If present, this
               property indicates the referenced resource has been deleted, and provides
               some supplementary information.
        """
        self.crn = crn
        self.deleted = deleted
        self.href = href
        self.id = id
        self.name = name
        self.resource_type = resource_type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'DedicatedHostReference':
        """Initialize a DedicatedHostReference object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError('Required property \'crn\' not present in DedicatedHostReference JSON')
        if 'deleted' in _dict:
            args['deleted'] = DedicatedHostReferenceDeleted.from_dict(_dict.get('deleted'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in DedicatedHostReference JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in DedicatedHostReference JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in DedicatedHostReference JSON')
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError('Required property \'resource_type\' not present in DedicatedHostReference JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a DedicatedHostReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'deleted') and self.deleted is not None:
            if isinstance(self.deleted, dict):
                _dict['deleted'] = self.deleted
            else:
                _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'resource_type') and self.resource_type is not None:
            _dict['resource_type'] = self.resource_type
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this DedicatedHostReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'DedicatedHostReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'DedicatedHostReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        DEDICATED_HOST = 'dedicated_host'



class DedicatedHostReferenceDeleted:
    """
    If present, this property indicates the referenced resource has been deleted, and
    provides some supplementary information.

    :attr str more_info: Link to documentation about deleted resources.
    """

    def __init__(
        self,
        more_info: str,
    ) -> None:
        """
        Initialize a DedicatedHostReferenceDeleted object.

        :param str more_info: Link to documentation about deleted resources.
        """
        self.more_info = more_info

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'DedicatedHostReferenceDeleted':
        """Initialize a DedicatedHostReferenceDeleted object from a json dictionary."""
        args = {}
        if 'more_info' in _dict:
            args['more_info'] = _dict.get('more_info')
        else:
            raise ValueError('Required property \'more_info\' not present in DedicatedHostReferenceDeleted JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a DedicatedHostReferenceDeleted object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'more_info') and self.more_info is not None:
            _dict['more_info'] = self.more_info
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this DedicatedHostReferenceDeleted object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'DedicatedHostReferenceDeleted') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'DedicatedHostReferenceDeleted') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class DefaultNetworkACL:
    """
    DefaultNetworkACL.

    :attr datetime created_at: The date and time that the network ACL was created.
    :attr str crn: The CRN for this network ACL.
    :attr str href: The URL for this network ACL.
    :attr str id: The unique identifier for this network ACL.
    :attr str name: The name of the default network ACL created for a VPC. The name
          will be a hyphenated list of randomly-selected words at creation, but may be
          changed.
    :attr ResourceGroupReference resource_group: The resource group for the default
          network ACL for a VPC. Set to the VPC's
          resource group at creation.
    :attr List[NetworkACLRuleItem] rules: The ordered rules for the default network
          ACL for a VPC. Defaults to two rules which allow all inbound and outbound
          traffic, respectively. Rules for the default network ACL may be changed, added,
          or removed.
    :attr List[SubnetReference] subnets: The subnets to which this network ACL is
          attached.
    :attr VPCReference vpc: The VPC this network ACL resides in.
    """

    def __init__(
        self,
        created_at: datetime,
        crn: str,
        href: str,
        id: str,
        name: str,
        resource_group: 'ResourceGroupReference',
        rules: List['NetworkACLRuleItem'],
        subnets: List['SubnetReference'],
        vpc: 'VPCReference',
    ) -> None:
        """
        Initialize a DefaultNetworkACL object.

        :param datetime created_at: The date and time that the network ACL was
               created.
        :param str crn: The CRN for this network ACL.
        :param str href: The URL for this network ACL.
        :param str id: The unique identifier for this network ACL.
        :param str name: The name of the default network ACL created for a VPC. The
               name will be a hyphenated list of randomly-selected words at creation, but
               may be changed.
        :param ResourceGroupReference resource_group: The resource group for the
               default network ACL for a VPC. Set to the VPC's
               resource group at creation.
        :param List[NetworkACLRuleItem] rules: The ordered rules for the default
               network ACL for a VPC. Defaults to two rules which allow all inbound and
               outbound traffic, respectively. Rules for the default network ACL may be
               changed, added, or removed.
        :param List[SubnetReference] subnets: The subnets to which this network ACL
               is attached.
        :param VPCReference vpc: The VPC this network ACL resides in.
        """
        self.created_at = created_at
        self.crn = crn
        self.href = href
        self.id = id
        self.name = name
        self.resource_group = resource_group
        self.rules = rules
        self.subnets = subnets
        self.vpc = vpc

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'DefaultNetworkACL':
        """Initialize a DefaultNetworkACL object from a json dictionary."""
        args = {}
        if 'created_at' in _dict:
            args['created_at'] = string_to_datetime(_dict.get('created_at'))
        else:
            raise ValueError('Required property \'created_at\' not present in DefaultNetworkACL JSON')
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError('Required property \'crn\' not present in DefaultNetworkACL JSON')
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in DefaultNetworkACL JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in DefaultNetworkACL JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in DefaultNetworkACL JSON')
        if 'resource_group' in _dict:
            args['resource_group'] = ResourceGroupReference.from_dict(_dict.get('resource_group'))
        else:
            raise ValueError('Required property \'resource_group\' not present in DefaultNetworkACL JSON')
        if 'rules' in _dict:
            args['rules'] = [NetworkACLRuleItem.from_dict(v) for v in _dict.get('rules')]
        else:
            raise ValueError('Required property \'rules\' not present in DefaultNetworkACL JSON')
        if 'subnets' in _dict:
            args['subnets'] = [SubnetReference.from_dict(v) for v in _dict.get('subnets')]
        else:
            raise ValueError('Required property \'subnets\' not present in DefaultNetworkACL JSON')
        if 'vpc' in _dict:
            args['vpc'] = VPCReference.from_dict(_dict.get('vpc'))
        else:
            raise ValueError('Required property \'vpc\' not present in DefaultNetworkACL JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a DefaultNetworkACL object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'created_at') and self.created_at is not None:
            _dict['created_at'] = datetime_to_string(self.created_at)
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'resource_group') and self.resource_group is not None:
            if isinstance(self.resource_group, dict):
                _dict['resource_group'] = self.resource_group
            else:
                _dict['resource_group'] = self.resource_group.to_dict()
        if hasattr(self, 'rules') and self.rules is not None:
            rules_list = []
            for v in self.rules:
                if isinstance(v, dict):
                    rules_list.append(v)
                else:
                    rules_list.append(v.to_dict())
            _dict['rules'] = rules_list
        if hasattr(self, 'subnets') and self.subnets is not None:
            subnets_list = []
            for v in self.subnets:
                if isinstance(v, dict):
                    subnets_list.append(v)
                else:
                    subnets_list.append(v.to_dict())
            _dict['subnets'] = subnets_list
        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()
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this DefaultNetworkACL object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'DefaultNetworkACL') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'DefaultNetworkACL') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class DefaultRoutingTable:
    """
    DefaultRoutingTable.

    :attr List[ResourceFilter] accept_routes_from: The filters specifying the
          resources that may create routes in this routing table.
          At present, only the `resource_type` filter is permitted, and only the
          `vpn_server` value is supported, but filter support is expected to expand in the
          future.
    :attr datetime created_at: The date and time that this routing table was
          created.
    :attr str href: The URL for this routing table.
    :attr str id: The unique identifier for this routing table.
    :attr bool is_default: Indicates whether this is the default routing table for
          this VPC.
    :attr str lifecycle_state: The lifecycle state of the routing table.
    :attr str name: The name of the default routing table created for this VPC. The
          name will be a hyphenated list of randomly-selected words at creation, but may
          be changed.
    :attr str resource_type: The resource type.
    :attr bool route_direct_link_ingress: Indicates whether this routing table is
          used to route traffic that originates from
          [Direct Link](https://cloud.ibm.com/docs/dl) to this VPC.
          Incoming traffic will be routed according to the routing table with one
          exception: routes with an `action` of `deliver` are treated as `drop` unless the
          `next_hop` is an IP address in a subnet in the route's `zone` that is able to
          accept traffic. Therefore, if an incoming packet matches a route with a
          `next_hop` of a VPN gateway connection, the packet will be dropped.
    :attr bool route_internet_ingress: Indicates whether this routing table is used
          to route traffic that originates from the internet.
          Incoming traffic will be routed according to the routing table with two
          exceptions:
          - Traffic destined for IP addresses associated with public gateways will not be
            subject to routes in this routing table.
          - Routes with an `action` of `deliver` are treated as `drop` unless the
          `next_hop` is
            an IP address in a subnet in the route's `zone` that is able to accept
          traffic.
            Therefore, if an incoming packet matches a route with a `next_hop` of a VPN
          gateway
            connection, the packet will be dropped.
    :attr bool route_transit_gateway_ingress: Indicates whether this routing table
          is used to route traffic that originates from from [Transit
          Gateway](https://cloud.ibm.com/docs/transit-gateway) to this VPC.
          Incoming traffic will be routed according to the routing table with one
          exception: routes with an `action` of `deliver` are treated as `drop` unless the
          `next_hop` is an IP address in a subnet in the route's `zone` that is able to
          accept traffic. Therefore, if an incoming packet matches a route with a
          `next_hop` of a VPN gateway connection, the packet will be dropped.
    :attr bool route_vpc_zone_ingress: Indicates whether this routing table is used
          to route traffic that originates from subnets in other zones in this VPC.
          Incoming traffic will be routed according to the routing table with one
          exception: routes with an `action` of `deliver` are treated as `drop` unless the
          `next_hop` is an IP address in a subnet in the route's `zone` that is able to
          accept traffic. Therefore, if an incoming packet matches a route with a
          `next_hop` of a VPN gateway connection, the packet will be dropped.
    :attr List[RouteReference] routes: The routes for the default routing table for
          this VPC. The table is created with no routes, but routes may be added, changed,
          or removed with a subsequent request.
    :attr List[SubnetReference] subnets: The subnets to which this routing table is
          attached.
    """

    def __init__(
        self,
        accept_routes_from: List['ResourceFilter'],
        created_at: datetime,
        href: str,
        id: str,
        is_default: bool,
        lifecycle_state: str,
        name: str,
        resource_type: str,
        route_direct_link_ingress: bool,
        route_internet_ingress: bool,
        route_transit_gateway_ingress: bool,
        route_vpc_zone_ingress: bool,
        routes: List['RouteReference'],
        subnets: List['SubnetReference'],
    ) -> None:
        """
        Initialize a DefaultRoutingTable object.

        :param List[ResourceFilter] accept_routes_from: The filters specifying the
               resources that may create routes in this routing table.
               At present, only the `resource_type` filter is permitted, and only the
               `vpn_server` value is supported, but filter support is expected to expand
               in the future.
        :param datetime created_at: The date and time that this routing table was
               created.
        :param str href: The URL for this routing table.
        :param str id: The unique identifier for this routing table.
        :param bool is_default: Indicates whether this is the default routing table
               for this VPC.
        :param str lifecycle_state: The lifecycle state of the routing table.
        :param str name: The name of the default routing table created for this
               VPC. The name will be a hyphenated list of randomly-selected words at
               creation, but may be changed.
        :param str resource_type: The resource type.
        :param bool route_direct_link_ingress: Indicates whether this routing table
               is used to route traffic that originates from
               [Direct Link](https://cloud.ibm.com/docs/dl) to this VPC.
               Incoming traffic will be routed according to the routing table with one
               exception: routes with an `action` of `deliver` are treated as `drop`
               unless the `next_hop` is an IP address in a subnet in the route's `zone`
               that is able to accept traffic. Therefore, if an incoming packet matches a
               route with a `next_hop` of a VPN gateway connection, the packet will be
               dropped.
        :param bool route_internet_ingress: Indicates whether this routing table is
               used to route traffic that originates from the internet.
               Incoming traffic will be routed according to the routing table with two
               exceptions:
               - Traffic destined for IP addresses associated with public gateways will
               not be
                 subject to routes in this routing table.
               - Routes with an `action` of `deliver` are treated as `drop` unless the
               `next_hop` is
                 an IP address in a subnet in the route's `zone` that is able to accept
               traffic.
                 Therefore, if an incoming packet matches a route with a `next_hop` of a
               VPN gateway
                 connection, the packet will be dropped.
        :param bool route_transit_gateway_ingress: Indicates whether this routing
               table is used to route traffic that originates from from [Transit
               Gateway](https://cloud.ibm.com/docs/transit-gateway) to this VPC.
               Incoming traffic will be routed according to the routing table with one
               exception: routes with an `action` of `deliver` are treated as `drop`
               unless the `next_hop` is an IP address in a subnet in the route's `zone`
               that is able to accept traffic. Therefore, if an incoming packet matches a
               route with a `next_hop` of a VPN gateway connection, the packet will be
               dropped.
        :param bool route_vpc_zone_ingress: Indicates whether this routing table is
               used to route traffic that originates from subnets in other zones in this
               VPC.
               Incoming traffic will be routed according to the routing table with one
               exception: routes with an `action` of `deliver` are treated as `drop`
               unless the `next_hop` is an IP address in a subnet in the route's `zone`
               that is able to accept traffic. Therefore, if an incoming packet matches a
               route with a `next_hop` of a VPN gateway connection, the packet will be
               dropped.
        :param List[RouteReference] routes: The routes for the default routing
               table for this VPC. The table is created with no routes, but routes may be
               added, changed, or removed with a subsequent request.
        :param List[SubnetReference] subnets: The subnets to which this routing
               table is attached.
        """
        self.accept_routes_from = accept_routes_from
        self.created_at = created_at
        self.href = href
        self.id = id
        self.is_default = is_default
        self.lifecycle_state = lifecycle_state
        self.name = name
        self.resource_type = resource_type
        self.route_direct_link_ingress = route_direct_link_ingress
        self.route_internet_ingress = route_internet_ingress
        self.route_transit_gateway_ingress = route_transit_gateway_ingress
        self.route_vpc_zone_ingress = route_vpc_zone_ingress
        self.routes = routes
        self.subnets = subnets

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'DefaultRoutingTable':
        """Initialize a DefaultRoutingTable object from a json dictionary."""
        args = {}
        if 'accept_routes_from' in _dict:
            args['accept_routes_from'] = [ResourceFilter.from_dict(v) for v in _dict.get('accept_routes_from')]
        else:
            raise ValueError('Required property \'accept_routes_from\' not present in DefaultRoutingTable 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 DefaultRoutingTable JSON')
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in DefaultRoutingTable JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in DefaultRoutingTable JSON')
        if 'is_default' in _dict:
            args['is_default'] = _dict.get('is_default')
        else:
            raise ValueError('Required property \'is_default\' not present in DefaultRoutingTable JSON')
        if 'lifecycle_state' in _dict:
            args['lifecycle_state'] = _dict.get('lifecycle_state')
        else:
            raise ValueError('Required property \'lifecycle_state\' not present in DefaultRoutingTable JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in DefaultRoutingTable JSON')
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError('Required property \'resource_type\' not present in DefaultRoutingTable JSON')
        if 'route_direct_link_ingress' in _dict:
            args['route_direct_link_ingress'] = _dict.get('route_direct_link_ingress')
        else:
            raise ValueError('Required property \'route_direct_link_ingress\' not present in DefaultRoutingTable JSON')
        if 'route_internet_ingress' in _dict:
            args['route_internet_ingress'] = _dict.get('route_internet_ingress')
        else:
            raise ValueError('Required property \'route_internet_ingress\' not present in DefaultRoutingTable JSON')
        if 'route_transit_gateway_ingress' in _dict:
            args['route_transit_gateway_ingress'] = _dict.get('route_transit_gateway_ingress')
        else:
            raise ValueError('Required property \'route_transit_gateway_ingress\' not present in DefaultRoutingTable JSON')
        if 'route_vpc_zone_ingress' in _dict:
            args['route_vpc_zone_ingress'] = _dict.get('route_vpc_zone_ingress')
        else:
            raise ValueError('Required property \'route_vpc_zone_ingress\' not present in DefaultRoutingTable JSON')
        if 'routes' in _dict:
            args['routes'] = [RouteReference.from_dict(v) for v in _dict.get('routes')]
        else:
            raise ValueError('Required property \'routes\' not present in DefaultRoutingTable JSON')
        if 'subnets' in _dict:
            args['subnets'] = [SubnetReference.from_dict(v) for v in _dict.get('subnets')]
        else:
            raise ValueError('Required property \'subnets\' not present in DefaultRoutingTable JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a DefaultRoutingTable object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'accept_routes_from') and self.accept_routes_from is not None:
            accept_routes_from_list = []
            for v in self.accept_routes_from:
                if isinstance(v, dict):
                    accept_routes_from_list.append(v)
                else:
                    accept_routes_from_list.append(v.to_dict())
            _dict['accept_routes_from'] = accept_routes_from_list
        if hasattr(self, 'created_at') and self.created_at is not None:
            _dict['created_at'] = datetime_to_string(self.created_at)
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'is_default') and self.is_default is not None:
            _dict['is_default'] = self.is_default
        if hasattr(self, 'lifecycle_state') and self.lifecycle_state is not None:
            _dict['lifecycle_state'] = self.lifecycle_state
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'resource_type') and self.resource_type is not None:
            _dict['resource_type'] = self.resource_type
        if hasattr(self, 'route_direct_link_ingress') and self.route_direct_link_ingress is not None:
            _dict['route_direct_link_ingress'] = self.route_direct_link_ingress
        if hasattr(self, 'route_internet_ingress') and self.route_internet_ingress is not None:
            _dict['route_internet_ingress'] = self.route_internet_ingress
        if hasattr(self, 'route_transit_gateway_ingress') and self.route_transit_gateway_ingress is not None:
            _dict['route_transit_gateway_ingress'] = self.route_transit_gateway_ingress
        if hasattr(self, 'route_vpc_zone_ingress') and self.route_vpc_zone_ingress is not None:
            _dict['route_vpc_zone_ingress'] = self.route_vpc_zone_ingress
        if hasattr(self, 'routes') and self.routes is not None:
            routes_list = []
            for v in self.routes:
                if isinstance(v, dict):
                    routes_list.append(v)
                else:
                    routes_list.append(v.to_dict())
            _dict['routes'] = routes_list
        if hasattr(self, 'subnets') and self.subnets is not None:
            subnets_list = []
            for v in self.subnets:
                if isinstance(v, dict):
                    subnets_list.append(v)
                else:
                    subnets_list.append(v.to_dict())
            _dict['subnets'] = subnets_list
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this DefaultRoutingTable object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'DefaultRoutingTable') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'DefaultRoutingTable') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class LifecycleStateEnum(str, Enum):
        """
        The lifecycle state of the routing table.
        """

        DELETING = 'deleting'
        FAILED = 'failed'
        PENDING = 'pending'
        STABLE = 'stable'
        SUSPENDED = 'suspended'
        UPDATING = 'updating'
        WAITING = 'waiting'


    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        ROUTING_TABLE = 'routing_table'



class DefaultSecurityGroup:
    """
    DefaultSecurityGroup.

    :attr datetime created_at: The date and time that this security group was
          created.
    :attr str crn: The security group's CRN.
    :attr str href: The security group's canonical URL.
    :attr str id: The unique identifier for this security group.
    :attr str name: The name for the default security group for a VPC. The name will
          be a hyphenated list of randomly-selected words at creation, but may changed.
    :attr ResourceGroupReference resource_group: The resource group for this
          security group.
    :attr List[SecurityGroupRule] rules: The 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 for the
          default security group may be changed, added or removed.
    :attr List[SecurityGroupTargetReference] targets: The targets for this security
          group.
    :attr VPCReference vpc: The VPC this security group resides in.
    """

    def __init__(
        self,
        created_at: datetime,
        crn: str,
        href: str,
        id: str,
        name: str,
        resource_group: 'ResourceGroupReference',
        rules: List['SecurityGroupRule'],
        targets: List['SecurityGroupTargetReference'],
        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 for the default security group for a VPC. The
               name will be a hyphenated list of randomly-selected words at creation, but
               may changed.
        :param ResourceGroupReference resource_group: The resource group for this
               security group.
        :param List[SecurityGroupRule] rules: The 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 for the default security group may be changed, added or
               removed.
        :param List[SecurityGroupTargetReference] targets: The targets for this
               security group.
        :param VPCReference vpc: The VPC this security group resides in.
        """
        self.created_at = created_at
        self.crn = crn
        self.href = href
        self.id = id
        self.name = name
        self.resource_group = resource_group
        self.rules = rules
        self.targets = targets
        self.vpc = vpc

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'DefaultSecurityGroup':
        """Initialize a DefaultSecurityGroup object from a json dictionary."""
        args = {}
        if 'created_at' in _dict:
            args['created_at'] = string_to_datetime(_dict.get('created_at'))
        else:
            raise ValueError('Required property \'created_at\' not present in DefaultSecurityGroup JSON')
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError('Required property \'crn\' not present in DefaultSecurityGroup JSON')
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in DefaultSecurityGroup JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in DefaultSecurityGroup JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in DefaultSecurityGroup JSON')
        if 'resource_group' in _dict:
            args['resource_group'] = ResourceGroupReference.from_dict(_dict.get('resource_group'))
        else:
            raise ValueError('Required property \'resource_group\' not present in DefaultSecurityGroup JSON')
        if 'rules' in _dict:
            args['rules'] = [SecurityGroupRule.from_dict(v) for v in _dict.get('rules')]
        else:
            raise ValueError('Required property \'rules\' not present in DefaultSecurityGroup JSON')
        if 'targets' in _dict:
            args['targets'] = _dict.get('targets')
        else:
            raise ValueError('Required property \'targets\' not present in DefaultSecurityGroup JSON')
        if 'vpc' in _dict:
            args['vpc'] = VPCReference.from_dict(_dict.get('vpc'))
        else:
            raise ValueError('Required property \'vpc\' not present in DefaultSecurityGroup JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a DefaultSecurityGroup object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'created_at') and self.created_at is not None:
            _dict['created_at'] = datetime_to_string(self.created_at)
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'resource_group') and self.resource_group is not None:
            if isinstance(self.resource_group, dict):
                _dict['resource_group'] = self.resource_group
            else:
                _dict['resource_group'] = self.resource_group.to_dict()
        if hasattr(self, 'rules') and self.rules is not None:
            rules_list = []
            for v in self.rules:
                if isinstance(v, dict):
                    rules_list.append(v)
                else:
                    rules_list.append(v.to_dict())
            _dict['rules'] = rules_list
        if hasattr(self, 'targets') and self.targets is not None:
            targets_list = []
            for v in self.targets:
                if isinstance(v, dict):
                    targets_list.append(v)
                else:
                    targets_list.append(v.to_dict())
            _dict['targets'] = targets_list
        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()
        return _dict

    def _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 Services 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 Services Root
               Key](https://cloud.ibm.com/docs/hs-crypto?topic=hs-crypto-get-started) for
               this resource.
        """
        self.crn = crn

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'EncryptionKeyReference':
        """Initialize a EncryptionKeyReference object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError('Required property \'crn\' not present in EncryptionKeyReference JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a EncryptionKeyReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this EncryptionKeyReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'EncryptionKeyReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'EncryptionKeyReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class EndpointGateway:
    """
    EndpointGateway.

    :attr bool allow_dns_resolution_binding: Indicates whether to allow DNS
          resolution for this endpoint gateway when the VPC this endpoint gateway resides
          in has a DNS resolution binding to a VPC with `dns.enable_hub` set to `true`.
    :attr datetime created_at: The date and time that the endpoint gateway was
          created.
    :attr str crn: The CRN for this endpoint gateway.
    :attr str health_state: The health of this resource.
          - `ok`: No abnormal behavior detected
          - `degraded`: Experiencing compromised performance, capacity, or connectivity
          - `faulted`: Completely unreachable, inoperative, or otherwise entirely
          incapacitated
          - `inapplicable`: The health state does not apply because of the current
          lifecycle state. A resource with a lifecycle state of `failed` or `deleting`
          will have a health state of `inapplicable`. A `pending` resource may also have
          this state.
    :attr str href: The URL for this endpoint gateway.
    :attr str id: The unique identifier for this endpoint gateway.
    :attr List[ReservedIPReference] ips: The reserved IPs bound to this endpoint
          gateway.
    :attr str lifecycle_state: The lifecycle state of the endpoint gateway.
    :attr str name: The name for this endpoint gateway. The name is unique across
          all endpoint gateways in the VPC.
    :attr ResourceGroupReference resource_group: The resource group for this
          endpoint gateway.
    :attr str resource_type: The resource type.
    :attr List[SecurityGroupReference] security_groups: The security groups
          targeting this endpoint gateway.
    :attr str service_endpoint: (optional) Deprecated: The fully qualified domain
          name for the target service.
    :attr List[str] service_endpoints: The fully qualified domain names for the
          target service.
    :attr EndpointGatewayTarget target: The target for this endpoint gateway.
    :attr VPCReference vpc: The VPC this endpoint gateway resides in.
    """

    def __init__(
        self,
        allow_dns_resolution_binding: bool,
        created_at: datetime,
        crn: str,
        health_state: str,
        href: str,
        id: str,
        ips: List['ReservedIPReference'],
        lifecycle_state: str,
        name: str,
        resource_group: 'ResourceGroupReference',
        resource_type: str,
        security_groups: List['SecurityGroupReference'],
        service_endpoints: List[str],
        target: 'EndpointGatewayTarget',
        vpc: 'VPCReference',
        *,
        service_endpoint: str = None,
    ) -> None:
        """
        Initialize a EndpointGateway object.

        :param bool allow_dns_resolution_binding: Indicates whether to allow DNS
               resolution for this endpoint gateway when the VPC this endpoint gateway
               resides in has a DNS resolution binding to a VPC with `dns.enable_hub` set
               to `true`.
        :param datetime created_at: The date and time that the endpoint gateway was
               created.
        :param str crn: The CRN for this endpoint gateway.
        :param str health_state: The health of this resource.
               - `ok`: No abnormal behavior detected
               - `degraded`: Experiencing compromised performance, capacity, or
               connectivity
               - `faulted`: Completely unreachable, inoperative, or otherwise entirely
               incapacitated
               - `inapplicable`: The health state does not apply because of the current
               lifecycle state. A resource with a lifecycle state of `failed` or
               `deleting` will have a health state of `inapplicable`. A `pending` resource
               may also have this state.
        :param str href: The URL for this endpoint gateway.
        :param str id: The unique identifier for this endpoint gateway.
        :param List[ReservedIPReference] ips: The reserved IPs bound to this
               endpoint gateway.
        :param str lifecycle_state: The lifecycle state of the endpoint gateway.
        :param str name: The name for this endpoint gateway. The name is unique
               across all endpoint gateways in the VPC.
        :param ResourceGroupReference resource_group: The resource group for this
               endpoint gateway.
        :param str resource_type: The resource type.
        :param List[SecurityGroupReference] security_groups: The security groups
               targeting this endpoint gateway.
        :param List[str] service_endpoints: The fully qualified domain names for
               the target service.
        :param EndpointGatewayTarget target: The target for this endpoint gateway.
        :param VPCReference vpc: The VPC this endpoint gateway resides in.
        :param str service_endpoint: (optional) Deprecated: The fully qualified
               domain name for the target service.
        """
        self.allow_dns_resolution_binding = allow_dns_resolution_binding
        self.created_at = created_at
        self.crn = crn
        self.health_state = health_state
        self.href = href
        self.id = id
        self.ips = ips
        self.lifecycle_state = lifecycle_state
        self.name = name
        self.resource_group = resource_group
        self.resource_type = resource_type
        self.security_groups = security_groups
        self.service_endpoint = service_endpoint
        self.service_endpoints = service_endpoints
        self.target = target
        self.vpc = vpc

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'EndpointGateway':
        """Initialize a EndpointGateway object from a json dictionary."""
        args = {}
        if 'allow_dns_resolution_binding' in _dict:
            args['allow_dns_resolution_binding'] = _dict.get('allow_dns_resolution_binding')
        else:
            raise ValueError('Required property \'allow_dns_resolution_binding\' not present in EndpointGateway 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 EndpointGateway JSON')
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError('Required property \'crn\' not present in EndpointGateway JSON')
        if 'health_state' in _dict:
            args['health_state'] = _dict.get('health_state')
        else:
            raise ValueError('Required property \'health_state\' not present in EndpointGateway JSON')
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in EndpointGateway JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in EndpointGateway JSON')
        if 'ips' in _dict:
            args['ips'] = [ReservedIPReference.from_dict(v) for v in _dict.get('ips')]
        else:
            raise ValueError('Required property \'ips\' not present in EndpointGateway JSON')
        if 'lifecycle_state' in _dict:
            args['lifecycle_state'] = _dict.get('lifecycle_state')
        else:
            raise ValueError('Required property \'lifecycle_state\' not present in EndpointGateway JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in EndpointGateway JSON')
        if 'resource_group' in _dict:
            args['resource_group'] = ResourceGroupReference.from_dict(_dict.get('resource_group'))
        else:
            raise ValueError('Required property \'resource_group\' not present in EndpointGateway JSON')
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError('Required property \'resource_type\' not present in EndpointGateway JSON')
        if 'security_groups' in _dict:
            args['security_groups'] = [SecurityGroupReference.from_dict(v) for v in _dict.get('security_groups')]
        else:
            raise ValueError('Required property \'security_groups\' not present in EndpointGateway JSON')
        if 'service_endpoint' in _dict:
            args['service_endpoint'] = _dict.get('service_endpoint')
        if 'service_endpoints' in _dict:
            args['service_endpoints'] = _dict.get('service_endpoints')
        else:
            raise ValueError('Required property \'service_endpoints\' not present in EndpointGateway JSON')
        if 'target' in _dict:
            args['target'] = _dict.get('target')
        else:
            raise ValueError('Required property \'target\' not present in EndpointGateway JSON')
        if 'vpc' in _dict:
            args['vpc'] = VPCReference.from_dict(_dict.get('vpc'))
        else:
            raise ValueError('Required property \'vpc\' not present in EndpointGateway JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a EndpointGateway object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'allow_dns_resolution_binding') and self.allow_dns_resolution_binding is not None:
            _dict['allow_dns_resolution_binding'] = self.allow_dns_resolution_binding
        if hasattr(self, 'created_at') and self.created_at is not None:
            _dict['created_at'] = datetime_to_string(self.created_at)
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'health_state') and self.health_state is not None:
            _dict['health_state'] = self.health_state
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'ips') and self.ips is not None:
            ips_list = []
            for v in self.ips:
                if isinstance(v, dict):
                    ips_list.append(v)
                else:
                    ips_list.append(v.to_dict())
            _dict['ips'] = ips_list
        if hasattr(self, 'lifecycle_state') and self.lifecycle_state is not None:
            _dict['lifecycle_state'] = self.lifecycle_state
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'resource_group') and self.resource_group is not None:
            if isinstance(self.resource_group, dict):
                _dict['resource_group'] = self.resource_group
            else:
                _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, 'security_groups') and self.security_groups is not None:
            security_groups_list = []
            for v in self.security_groups:
                if isinstance(v, dict):
                    security_groups_list.append(v)
                else:
                    security_groups_list.append(v.to_dict())
            _dict['security_groups'] = security_groups_list
        if hasattr(self, 'service_endpoint') and self.service_endpoint is not None:
            _dict['service_endpoint'] = self.service_endpoint
        if hasattr(self, 'service_endpoints') and self.service_endpoints is not None:
            _dict['service_endpoints'] = self.service_endpoints
        if hasattr(self, 'target') and self.target is not None:
            if isinstance(self.target, dict):
                _dict['target'] = self.target
            else:
                _dict['target'] = self.target.to_dict()
        if hasattr(self, 'vpc') and self.vpc is not None:
            if isinstance(self.vpc, dict):
                _dict['vpc'] = self.vpc
            else:
                _dict['vpc'] = self.vpc.to_dict()
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this EndpointGateway object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'EndpointGateway') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'EndpointGateway') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class HealthStateEnum(str, Enum):
        """
        The health of this resource.
        - `ok`: No abnormal behavior detected
        - `degraded`: Experiencing compromised performance, capacity, or connectivity
        - `faulted`: Completely unreachable, inoperative, or otherwise entirely
        incapacitated
        - `inapplicable`: The health state does not apply because of the current lifecycle
        state. A resource with a lifecycle state of `failed` or `deleting` will have a
        health state of `inapplicable`. A `pending` resource may also have this state.
        """

        DEGRADED = 'degraded'
        FAULTED = 'faulted'
        INAPPLICABLE = 'inapplicable'
        OK = 'ok'


    class LifecycleStateEnum(str, Enum):
        """
        The lifecycle state of the endpoint gateway.
        """

        DELETING = 'deleting'
        FAILED = 'failed'
        PENDING = 'pending'
        STABLE = 'stable'
        SUSPENDED = 'suspended'
        UPDATING = 'updating'
        WAITING = 'waiting'


    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        ENDPOINT_GATEWAY = 'endpoint_gateway'



class EndpointGatewayCollection:
    """
    EndpointGatewayCollection.

    :attr List[EndpointGateway] endpoint_gateways: Collection of endpoint gateways.
    :attr EndpointGatewayCollectionFirst first: A link to the first page of
          resources.
    :attr int limit: The maximum number of resources that can be returned by the
          request.
    :attr EndpointGatewayCollectionNext next: (optional) A link to the next page of
          resources. This property is present for all pages
          except the last page.
    :attr int total_count: The total number of resources across all pages.
    """

    def __init__(
        self,
        endpoint_gateways: List['EndpointGateway'],
        first: 'EndpointGatewayCollectionFirst',
        limit: int,
        total_count: int,
        *,
        next: 'EndpointGatewayCollectionNext' = None,
    ) -> None:
        """
        Initialize a EndpointGatewayCollection object.

        :param List[EndpointGateway] endpoint_gateways: Collection of endpoint
               gateways.
        :param EndpointGatewayCollectionFirst first: A link to the first page of
               resources.
        :param int limit: The maximum number of resources that can be returned by
               the request.
        :param int total_count: The total number of resources across all pages.
        :param EndpointGatewayCollectionNext next: (optional) A link to the next
               page of resources. This property is present for all pages
               except the last page.
        """
        self.endpoint_gateways = endpoint_gateways
        self.first = first
        self.limit = limit
        self.next = next
        self.total_count = total_count

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'EndpointGatewayCollection':
        """Initialize a EndpointGatewayCollection object from a json dictionary."""
        args = {}
        if 'endpoint_gateways' in _dict:
            args['endpoint_gateways'] = [EndpointGateway.from_dict(v) for v in _dict.get('endpoint_gateways')]
        else:
            raise ValueError('Required property \'endpoint_gateways\' not present in EndpointGatewayCollection JSON')
        if 'first' in _dict:
            args['first'] = EndpointGatewayCollectionFirst.from_dict(_dict.get('first'))
        else:
            raise ValueError('Required property \'first\' not present in EndpointGatewayCollection JSON')
        if 'limit' in _dict:
            args['limit'] = _dict.get('limit')
        else:
            raise ValueError('Required property \'limit\' not present in EndpointGatewayCollection JSON')
        if 'next' in _dict:
            args['next'] = EndpointGatewayCollectionNext.from_dict(_dict.get('next'))
        if 'total_count' in _dict:
            args['total_count'] = _dict.get('total_count')
        else:
            raise ValueError('Required property \'total_count\' not present in EndpointGatewayCollection JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a EndpointGatewayCollection object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'endpoint_gateways') and self.endpoint_gateways is not None:
            endpoint_gateways_list = []
            for v in self.endpoint_gateways:
                if isinstance(v, dict):
                    endpoint_gateways_list.append(v)
                else:
                    endpoint_gateways_list.append(v.to_dict())
            _dict['endpoint_gateways'] = endpoint_gateways_list
        if hasattr(self, 'first') and self.first is not None:
            if isinstance(self.first, dict):
                _dict['first'] = self.first
            else:
                _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:
            if isinstance(self.next, dict):
                _dict['next'] = self.next
            else:
                _dict['next'] = self.next.to_dict()
        if hasattr(self, 'total_count') and self.total_count is not None:
            _dict['total_count'] = self.total_count
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this EndpointGatewayCollection object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'EndpointGatewayCollection') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'EndpointGatewayCollection') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class EndpointGatewayCollectionFirst:
    """
    A link to the first page of resources.

    :attr str href: The URL for a page of resources.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a EndpointGatewayCollectionFirst object.

        :param str href: The URL for a page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'EndpointGatewayCollectionFirst':
        """Initialize a EndpointGatewayCollectionFirst object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in EndpointGatewayCollectionFirst JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a EndpointGatewayCollectionFirst object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this EndpointGatewayCollectionFirst object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'EndpointGatewayCollectionFirst') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'EndpointGatewayCollectionFirst') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class EndpointGatewayCollectionNext:
    """
    A link to the next page of resources. This property is present for all pages except
    the last page.

    :attr str href: The URL for a page of resources.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a EndpointGatewayCollectionNext object.

        :param str href: The URL for a page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'EndpointGatewayCollectionNext':
        """Initialize a EndpointGatewayCollectionNext object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in EndpointGatewayCollectionNext JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a EndpointGatewayCollectionNext object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this EndpointGatewayCollectionNext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'EndpointGatewayCollectionNext') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'EndpointGatewayCollectionNext') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class EndpointGatewayPatch:
    """
    EndpointGatewayPatch.

    :attr bool allow_dns_resolution_binding: (optional) Indicates whether to allow
          DNS resolution for this endpoint gateway when the VPC this endpoint gateway
          resides in has a DNS resolution binding to a VPC with `dns.enable_hub` set to
          `true`.
          Must be `true` if the VPC this endpoint gateway resides in has `dns.enable_hub`
          set to
          `true`.
    :attr str name: (optional) The name for this endpoint gateway. The name must not
          be used by another endpoint gateway in the VPC.
    """

    def __init__(
        self,
        *,
        allow_dns_resolution_binding: bool = None,
        name: str = None,
    ) -> None:
        """
        Initialize a EndpointGatewayPatch object.

        :param bool allow_dns_resolution_binding: (optional) Indicates whether to
               allow DNS resolution for this endpoint gateway when the VPC this endpoint
               gateway resides in has a DNS resolution binding to a VPC with
               `dns.enable_hub` set to `true`.
               Must be `true` if the VPC this endpoint gateway resides in has
               `dns.enable_hub` set to
               `true`.
        :param str name: (optional) The name for this endpoint gateway. The name
               must not be used by another endpoint gateway in the VPC.
        """
        self.allow_dns_resolution_binding = allow_dns_resolution_binding
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'EndpointGatewayPatch':
        """Initialize a EndpointGatewayPatch object from a json dictionary."""
        args = {}
        if 'allow_dns_resolution_binding' in _dict:
            args['allow_dns_resolution_binding'] = _dict.get('allow_dns_resolution_binding')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a EndpointGatewayPatch object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'allow_dns_resolution_binding') and self.allow_dns_resolution_binding is not None:
            _dict['allow_dns_resolution_binding'] = self.allow_dns_resolution_binding
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this EndpointGatewayPatch object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'EndpointGatewayPatch') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'EndpointGatewayPatch') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class EndpointGatewayReferenceDeleted:
    """
    If present, this property indicates the referenced resource has been deleted, and
    provides some supplementary information.

    :attr str more_info: Link to documentation about deleted resources.
    """

    def __init__(
        self,
        more_info: str,
    ) -> None:
        """
        Initialize a EndpointGatewayReferenceDeleted object.

        :param str more_info: Link to documentation about deleted resources.
        """
        self.more_info = more_info

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'EndpointGatewayReferenceDeleted':
        """Initialize a EndpointGatewayReferenceDeleted object from a json dictionary."""
        args = {}
        if 'more_info' in _dict:
            args['more_info'] = _dict.get('more_info')
        else:
            raise ValueError('Required property \'more_info\' not present in EndpointGatewayReferenceDeleted JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a EndpointGatewayReferenceDeleted object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'more_info') and self.more_info is not None:
            _dict['more_info'] = self.more_info
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this EndpointGatewayReferenceDeleted object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'EndpointGatewayReferenceDeleted') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'EndpointGatewayReferenceDeleted') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class EndpointGatewayReferenceRemote:
    """
    EndpointGatewayReferenceRemote.

    :attr str crn: The CRN for this endpoint gateway.
    :attr str href: The URL for this endpoint gateway.
    :attr str id: The unique identifier for this endpoint gateway.
    :attr str name: The name for this endpoint gateway. The name is unique across
          all endpoint gateways in the VPC.
    :attr EndpointGatewayRemote remote: (optional) If present, this property
          indicates that the resource associated with this reference
          is remote and therefore may not be directly retrievable.
    :attr str resource_type: The resource type.
    """

    def __init__(
        self,
        crn: str,
        href: str,
        id: str,
        name: str,
        resource_type: str,
        *,
        remote: 'EndpointGatewayRemote' = None,
    ) -> None:
        """
        Initialize a EndpointGatewayReferenceRemote object.

        :param str crn: The CRN for this endpoint gateway.
        :param str href: The URL for this endpoint gateway.
        :param str id: The unique identifier for this endpoint gateway.
        :param str name: The name for this endpoint gateway. The name is unique
               across all endpoint gateways in the VPC.
        :param str resource_type: The resource type.
        :param EndpointGatewayRemote remote: (optional) If present, this property
               indicates that the resource associated with this reference
               is remote and therefore may not be directly retrievable.
        """
        self.crn = crn
        self.href = href
        self.id = id
        self.name = name
        self.remote = remote
        self.resource_type = resource_type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'EndpointGatewayReferenceRemote':
        """Initialize a EndpointGatewayReferenceRemote object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError('Required property \'crn\' not present in EndpointGatewayReferenceRemote JSON')
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in EndpointGatewayReferenceRemote JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in EndpointGatewayReferenceRemote JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in EndpointGatewayReferenceRemote JSON')
        if 'remote' in _dict:
            args['remote'] = EndpointGatewayRemote.from_dict(_dict.get('remote'))
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError('Required property \'resource_type\' not present in EndpointGatewayReferenceRemote JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a EndpointGatewayReferenceRemote object from 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, '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, '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 EndpointGatewayReferenceRemote object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'EndpointGatewayReferenceRemote') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'EndpointGatewayReferenceRemote') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        ENDPOINT_GATEWAY = 'endpoint_gateway'



class EndpointGatewayRemote:
    """
    If present, this property indicates that the resource associated with this reference
    is remote and therefore may not be directly retrievable.

    :attr AccountReference account: (optional) If present, this property indicates
          that the referenced resource is remote to this
          account, and identifies the owning account.
    :attr RegionReference region: (optional) If present, this property indicates
          that the referenced resource is remote to this
          region, and identifies the native region.
    """

    def __init__(
        self,
        *,
        account: 'AccountReference' = None,
        region: 'RegionReference' = None,
    ) -> None:
        """
        Initialize a EndpointGatewayRemote object.

        :param AccountReference account: (optional) If present, this property
               indicates that the referenced resource is remote to this
               account, and identifies the owning account.
        :param RegionReference region: (optional) If present, this property
               indicates that the referenced resource is remote to this
               region, and identifies the native region.
        """
        self.account = account
        self.region = region

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'EndpointGatewayRemote':
        """Initialize a EndpointGatewayRemote object from a json dictionary."""
        args = {}
        if 'account' in _dict:
            args['account'] = AccountReference.from_dict(_dict.get('account'))
        if 'region' in _dict:
            args['region'] = RegionReference.from_dict(_dict.get('region'))
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a EndpointGatewayRemote object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'account') and self.account is not None:
            if isinstance(self.account, dict):
                _dict['account'] = self.account
            else:
                _dict['account'] = self.account.to_dict()
        if hasattr(self, 'region') and self.region is not None:
            if isinstance(self.region, dict):
                _dict['region'] = self.region
            else:
                _dict['region'] = self.region.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 EndpointGatewayRemote object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'EndpointGatewayRemote') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'EndpointGatewayRemote') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class EndpointGatewayReservedIP:
    """
    A reserved IP to bind to the endpoint gateway. This can be specified using an existing
    reserved IP, or a prototype object for a new reserved IP. The reserved IP will be
    bound to the endpoint gateway to function as a virtual private endpoint for the
    service.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a EndpointGatewayReservedIP object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['EndpointGatewayReservedIPReservedIPIdentity', 'EndpointGatewayReservedIPReservedIPPrototypeTargetContext'])
        )
        raise Exception(msg)


class EndpointGatewayTarget:
    """
    The target for this endpoint gateway.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a EndpointGatewayTarget object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['EndpointGatewayTargetProviderCloudServiceReference', 'EndpointGatewayTargetProviderInfrastructureServiceReference'])
        )
        raise Exception(msg)


class EndpointGatewayTargetPrototype:
    """
    The target to use for this endpoint gateway. Must not already be the target of another
    endpoint gateway in the VPC.

    :attr str resource_type: The type of target for this endpoint gateway.
    """

    def __init__(
        self,
        resource_type: str,
    ) -> None:
        """
        Initialize a EndpointGatewayTargetPrototype object.

        :param str resource_type: The type of target for this endpoint gateway.
        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['EndpointGatewayTargetPrototypeProviderCloudServiceIdentity', 'EndpointGatewayTargetPrototypeProviderInfrastructureServiceIdentity'])
        )
        raise Exception(msg)

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'EndpointGatewayTargetPrototype':
        """Initialize a EndpointGatewayTargetPrototype object from a json dictionary."""
        disc_class = cls._get_class_by_discriminator(_dict)
        if disc_class != cls:
            return disc_class.from_dict(_dict)
        msg = "Cannot convert dictionary into an instance of base class 'EndpointGatewayTargetPrototype'. The discriminator value should map to a valid subclass: {1}".format(
            ", ".join(['EndpointGatewayTargetPrototypeProviderCloudServiceIdentity', 'EndpointGatewayTargetPrototypeProviderInfrastructureServiceIdentity'])
        )
        raise Exception(msg)

    @classmethod
    def _from_dict(cls, _dict: Dict):
        """Initialize a EndpointGatewayTargetPrototype object from a json dictionary."""
        return cls.from_dict(_dict)

    @classmethod
    def _get_class_by_discriminator(cls, _dict: Dict) -> object:
        mapping = {}
        mapping['provider_cloud_service'] = 'EndpointGatewayTargetPrototypeProviderCloudServiceIdentity'
        mapping['provider_infrastructure_service'] = 'EndpointGatewayTargetPrototypeProviderInfrastructureServiceIdentity'
        disc_value = _dict.get('resource_type')
        if disc_value is None:
            raise ValueError('Discriminator property \'resource_type\' not found in EndpointGatewayTargetPrototype JSON')
        class_name = mapping.get(disc_value, disc_value)
        try:
            disc_class = getattr(sys.modules[__name__], class_name)
        except AttributeError:
            disc_class = cls
        if isinstance(disc_class, object):
            return disc_class
        raise TypeError('%s is not a discriminator class' % class_name)

    class ResourceTypeEnum(str, Enum):
        """
        The type of target for this endpoint gateway.
        """

        PROVIDER_CLOUD_SERVICE = 'provider_cloud_service'
        PROVIDER_INFRASTRUCTURE_SERVICE = 'provider_infrastructure_service'



class FloatingIP:
    """
    FloatingIP.

    :attr str address: The globally unique IP address.
    :attr datetime created_at: The date and time that the floating IP was created.
    :attr str crn: The CRN for this floating IP.
    :attr str href: The URL for this floating IP.
    :attr str id: The unique identifier for this floating IP.
    :attr str name: The name for this floating IP. The name is unique across all
          floating IPs in the region.
    :attr ResourceGroupReference resource_group: The resource group for this
          floating IP.
    :attr str status: The status of the floating IP.
    :attr FloatingIPTarget target: (optional) The target of this floating IP.
    :attr ZoneReference zone: The zone this floating IP resides in.
    """

    def __init__(
        self,
        address: str,
        created_at: datetime,
        crn: str,
        href: str,
        id: str,
        name: str,
        resource_group: 'ResourceGroupReference',
        status: str,
        zone: 'ZoneReference',
        *,
        target: 'FloatingIPTarget' = None,
    ) -> None:
        """
        Initialize a FloatingIP object.

        :param str address: The globally unique IP address.
        :param datetime created_at: The date and time that the floating IP was
               created.
        :param str crn: The CRN for this floating IP.
        :param str href: The URL for this floating IP.
        :param str id: The unique identifier for this floating IP.
        :param str name: The name for this floating IP. The name is unique across
               all floating IPs in the region.
        :param ResourceGroupReference resource_group: The resource group for this
               floating IP.
        :param str status: The status of the floating IP.
        :param ZoneReference zone: The zone this floating IP resides in.
        :param FloatingIPTarget target: (optional) The target of this floating IP.
        """
        self.address = address
        self.created_at = created_at
        self.crn = crn
        self.href = href
        self.id = id
        self.name = name
        self.resource_group = resource_group
        self.status = status
        self.target = target
        self.zone = zone

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'FloatingIP':
        """Initialize a FloatingIP object from a json dictionary."""
        args = {}
        if 'address' in _dict:
            args['address'] = _dict.get('address')
        else:
            raise ValueError('Required property \'address\' not present in FloatingIP JSON')
        if 'created_at' in _dict:
            args['created_at'] = string_to_datetime(_dict.get('created_at'))
        else:
            raise ValueError('Required property \'created_at\' not present in FloatingIP JSON')
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError('Required property \'crn\' not present in FloatingIP JSON')
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in FloatingIP JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in FloatingIP JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in FloatingIP JSON')
        if 'resource_group' in _dict:
            args['resource_group'] = ResourceGroupReference.from_dict(_dict.get('resource_group'))
        else:
            raise ValueError('Required property \'resource_group\' not present in FloatingIP JSON')
        if 'status' in _dict:
            args['status'] = _dict.get('status')
        else:
            raise ValueError('Required property \'status\' not present in FloatingIP JSON')
        if 'target' in _dict:
            args['target'] = _dict.get('target')
        if 'zone' in _dict:
            args['zone'] = ZoneReference.from_dict(_dict.get('zone'))
        else:
            raise ValueError('Required property \'zone\' not present in FloatingIP JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a FloatingIP object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'address') and self.address is not None:
            _dict['address'] = self.address
        if hasattr(self, 'created_at') and self.created_at is not None:
            _dict['created_at'] = datetime_to_string(self.created_at)
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'resource_group') and self.resource_group is not None:
            if isinstance(self.resource_group, dict):
                _dict['resource_group'] = self.resource_group
            else:
                _dict['resource_group'] = self.resource_group.to_dict()
        if hasattr(self, 'status') and self.status is not None:
            _dict['status'] = self.status
        if hasattr(self, 'target') and self.target is not None:
            if isinstance(self.target, dict):
                _dict['target'] = self.target
            else:
                _dict['target'] = self.target.to_dict()
        if hasattr(self, 'zone') and self.zone is not None:
            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 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 FloatingIPCollection:
    """
    FloatingIPCollection.

    :attr FloatingIPCollectionFirst first: A link to the first page of resources.
    :attr List[FloatingIP] floating_ips: Collection of floating IPs.
    :attr int limit: The maximum number of resources that can be returned by the
          request.
    :attr FloatingIPCollectionNext next: (optional) A link to the next page of
          resources. This property is present for all pages
          except the last page.
    :attr int total_count: The total number of resources across all pages.
    """

    def __init__(
        self,
        first: 'FloatingIPCollectionFirst',
        floating_ips: List['FloatingIP'],
        limit: int,
        total_count: int,
        *,
        next: 'FloatingIPCollectionNext' = None,
    ) -> None:
        """
        Initialize a FloatingIPCollection object.

        :param FloatingIPCollectionFirst first: A link to the first page of
               resources.
        :param List[FloatingIP] floating_ips: Collection of floating IPs.
        :param int limit: The maximum number of resources that can be returned by
               the request.
        :param int total_count: The total number of resources across all pages.
        :param FloatingIPCollectionNext next: (optional) A link to the next page of
               resources. This property is present for all pages
               except the last page.
        """
        self.first = first
        self.floating_ips = floating_ips
        self.limit = limit
        self.next = next
        self.total_count = total_count

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'FloatingIPCollection':
        """Initialize a FloatingIPCollection object from a json dictionary."""
        args = {}
        if 'first' in _dict:
            args['first'] = FloatingIPCollectionFirst.from_dict(_dict.get('first'))
        else:
            raise ValueError('Required property \'first\' not present in FloatingIPCollection JSON')
        if 'floating_ips' in _dict:
            args['floating_ips'] = [FloatingIP.from_dict(v) for v in _dict.get('floating_ips')]
        else:
            raise ValueError('Required property \'floating_ips\' not present in FloatingIPCollection JSON')
        if 'limit' in _dict:
            args['limit'] = _dict.get('limit')
        else:
            raise ValueError('Required property \'limit\' not present in FloatingIPCollection JSON')
        if 'next' in _dict:
            args['next'] = FloatingIPCollectionNext.from_dict(_dict.get('next'))
        if 'total_count' in _dict:
            args['total_count'] = _dict.get('total_count')
        else:
            raise ValueError('Required property \'total_count\' not present in FloatingIPCollection JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a FloatingIPCollection object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'first') and self.first is not None:
            if isinstance(self.first, dict):
                _dict['first'] = self.first
            else:
                _dict['first'] = self.first.to_dict()
        if hasattr(self, 'floating_ips') and self.floating_ips is not None:
            floating_ips_list = []
            for v in self.floating_ips:
                if isinstance(v, dict):
                    floating_ips_list.append(v)
                else:
                    floating_ips_list.append(v.to_dict())
            _dict['floating_ips'] = floating_ips_list
        if hasattr(self, 'limit') and self.limit is not None:
            _dict['limit'] = self.limit
        if hasattr(self, 'next') and self.next is not None:
            if isinstance(self.next, dict):
                _dict['next'] = self.next
            else:
                _dict['next'] = self.next.to_dict()
        if hasattr(self, 'total_count') and self.total_count is not None:
            _dict['total_count'] = self.total_count
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this FloatingIPCollection object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'FloatingIPCollection') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'FloatingIPCollection') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class FloatingIPCollectionFirst:
    """
    A link to the first page of resources.

    :attr str href: The URL for a page of resources.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a FloatingIPCollectionFirst object.

        :param str href: The URL for a page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'FloatingIPCollectionFirst':
        """Initialize a FloatingIPCollectionFirst object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in FloatingIPCollectionFirst JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a FloatingIPCollectionFirst object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this FloatingIPCollectionFirst object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'FloatingIPCollectionFirst') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'FloatingIPCollectionFirst') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class FloatingIPCollectionNext:
    """
    A link to the next page of resources. This property is present for all pages except
    the last page.

    :attr str href: The URL for a page of resources.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a FloatingIPCollectionNext object.

        :param str href: The URL for a page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'FloatingIPCollectionNext':
        """Initialize a FloatingIPCollectionNext object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in FloatingIPCollectionNext JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a FloatingIPCollectionNext object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this FloatingIPCollectionNext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'FloatingIPCollectionNext') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'FloatingIPCollectionNext') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class FloatingIPPatch:
    """
    FloatingIPPatch.

    :attr str name: (optional) The name for this floating IP. The name must not be
          used by another floating IP in the region.
    :attr FloatingIPTargetPatch target: (optional) The target resource to bind this
          floating IP to, replacing any existing binding.
          The floating IP must not be required by another resource, such as a public
          gateway.
          The target resource must not already have a floating IP bound to it if the
          target
          resource is:
          - an instance network interface
          - a bare metal server network interface with `enable_infrastructure_nat` set to
          `true`.
    """

    def __init__(
        self,
        *,
        name: str = None,
        target: 'FloatingIPTargetPatch' = None,
    ) -> None:
        """
        Initialize a FloatingIPPatch object.

        :param str name: (optional) The name for this floating IP. The name must
               not be used by another floating IP in the region.
        :param FloatingIPTargetPatch target: (optional) The target resource to bind
               this floating IP to, replacing any existing binding.
               The floating IP must not be required by another resource, such as a public
               gateway.
               The target resource must not already have a floating IP bound to it if the
               target
               resource is:
               - an instance network interface
               - a bare metal server network interface with `enable_infrastructure_nat`
               set to `true`.
        """
        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 FloatingIPPrototype:
    """
    FloatingIPPrototype.

    :attr str name: (optional) The name for this floating IP. The name must not be
          used by another floating IP in the region. 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) will be
          used.
    """

    def __init__(
        self,
        *,
        name: str = None,
        resource_group: 'ResourceGroupIdentity' = None,
    ) -> None:
        """
        Initialize a FloatingIPPrototype object.

        :param str name: (optional) The name for this floating IP. The name must
               not be used by another floating IP in the region. 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) will be
               used.
        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['FloatingIPPrototypeFloatingIPByZone', 'FloatingIPPrototypeFloatingIPByTarget'])
        )
        raise Exception(msg)


class FloatingIPReference:
    """
    FloatingIPReference.

    :attr str address: The globally unique IP address.
    :attr str crn: The CRN for this floating IP.
    :attr FloatingIPReferenceDeleted deleted: (optional) If present, this property
          indicates the referenced resource has been deleted, and provides
          some supplementary information.
    :attr str href: The URL for this floating IP.
    :attr str id: The unique identifier for this floating IP.
    :attr str name: The name for this floating IP. The name is unique across all
          floating IPs in the region.
    """

    def __init__(
        self,
        address: str,
        crn: str,
        href: str,
        id: str,
        name: str,
        *,
        deleted: 'FloatingIPReferenceDeleted' = None,
    ) -> None:
        """
        Initialize a FloatingIPReference object.

        :param str address: The globally unique IP address.
        :param str crn: The CRN for this floating IP.
        :param str href: The URL for this floating IP.
        :param str id: The unique identifier for this floating IP.
        :param str name: The name for this floating IP. The name is unique across
               all floating IPs in the region.
        :param FloatingIPReferenceDeleted deleted: (optional) If present, this
               property indicates the referenced resource has been deleted, and provides
               some supplementary information.
        """
        self.address = address
        self.crn = crn
        self.deleted = deleted
        self.href = href
        self.id = id
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'FloatingIPReference':
        """Initialize a FloatingIPReference object from a json dictionary."""
        args = {}
        if 'address' in _dict:
            args['address'] = _dict.get('address')
        else:
            raise ValueError('Required property \'address\' not present in FloatingIPReference JSON')
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError('Required property \'crn\' not present in FloatingIPReference JSON')
        if 'deleted' in _dict:
            args['deleted'] = FloatingIPReferenceDeleted.from_dict(_dict.get('deleted'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in FloatingIPReference JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in FloatingIPReference JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in FloatingIPReference JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a FloatingIPReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'address') and self.address is not None:
            _dict['address'] = self.address
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'deleted') and self.deleted is not None:
            if isinstance(self.deleted, dict):
                _dict['deleted'] = self.deleted
            else:
                _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this FloatingIPReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'FloatingIPReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'FloatingIPReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class FloatingIPReferenceDeleted:
    """
    If present, this property indicates the referenced resource has been deleted, and
    provides some supplementary information.

    :attr str more_info: Link to documentation about deleted resources.
    """

    def __init__(
        self,
        more_info: str,
    ) -> None:
        """
        Initialize a FloatingIPReferenceDeleted object.

        :param str more_info: Link to documentation about deleted resources.
        """
        self.more_info = more_info

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'FloatingIPReferenceDeleted':
        """Initialize a FloatingIPReferenceDeleted object from a json dictionary."""
        args = {}
        if 'more_info' in _dict:
            args['more_info'] = _dict.get('more_info')
        else:
            raise ValueError('Required property \'more_info\' not present in FloatingIPReferenceDeleted JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a FloatingIPReferenceDeleted object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'more_info') and self.more_info is not None:
            _dict['more_info'] = self.more_info
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this FloatingIPReferenceDeleted object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'FloatingIPReferenceDeleted') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'FloatingIPReferenceDeleted') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class FloatingIPTarget:
    """
    The target of this floating IP.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a FloatingIPTarget object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['FloatingIPTargetNetworkInterfaceReference', 'FloatingIPTargetBareMetalServerNetworkInterfaceReference', 'FloatingIPTargetPublicGatewayReference'])
        )
        raise Exception(msg)


class FloatingIPTargetPatch:
    """
    The target resource to bind this floating IP to, replacing any existing binding. The
    floating IP must not be required by another resource, such as a public gateway.
    The target resource must not already have a floating IP bound to it if the target
    resource is:
    - an instance network interface
    - a bare metal server network interface with `enable_infrastructure_nat` set to
    `true`.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a FloatingIPTargetPatch object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['FloatingIPTargetPatchBareMetalServerNetworkInterfaceIdentity', 'FloatingIPTargetPatchNetworkInterfaceIdentity'])
        )
        raise Exception(msg)


class FloatingIPTargetPrototype:
    """
    The target resource to bind this floating IP to.
    The target resource must not already have a floating IP bound to it if the target
    resource is:
    - an instance network interface
    - a bare metal server network interface with `enable_infrastructure_nat` set to
    `true`.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a FloatingIPTargetPrototype object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['FloatingIPTargetPrototypeBareMetalServerNetworkInterfaceIdentity', 'FloatingIPTargetPrototypeNetworkInterfaceIdentity'])
        )
        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(v) for v 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:
            floating_ips_list = []
            for v in self.floating_ips:
                if isinstance(v, dict):
                    floating_ips_list.append(v)
                else:
                    floating_ips_list.append(v.to_dict())
            _dict['floating_ips'] = floating_ips_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 FloatingIPUnpaginatedCollection object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'FloatingIPUnpaginatedCollection') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'FloatingIPUnpaginatedCollection') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class FlowLogCollector:
    """
    FlowLogCollector.

    :attr bool active: Indicates whether this collector is active.
    :attr bool auto_delete: Indicates whether this flow log collector will be
          automatically deleted when `target` is deleted. At present, this is always
          `true`, but may be modifiable in the future.
    :attr datetime created_at: The date and time that the flow log collector was
          created.
    :attr str crn: The CRN for this flow log collector.
    :attr str href: The URL for this flow log collector.
    :attr str id: The unique identifier for this flow log collector.
    :attr str lifecycle_state: The lifecycle state of the flow log collector.
    :attr str name: The name for this flow log collector. The name is unique across
          all flow log collectors in the VPC.
    :attr ResourceGroupReference resource_group: The resource group for this flow
          log collector.
    :attr LegacyCloudObjectStorageBucketReference storage_bucket: The Cloud Object
          Storage bucket where the collected flows are logged. For more
          information, see [Viewing flow log
          objects](https://cloud.ibm.com/docs/vpc?topic=vpc-fl-analyze).
    :attr FlowLogCollectorTarget target: The target this collector is collecting
          flow logs for.
          - If the target is an instance network interface, flow logs will be collected
            for that instance network interface.
          - If the target is a virtual server instance, flow logs will be collected
            for all network interfaces on that instance.
          - If the target is a subnet, flow logs will be collected
            for all instance network interfaces attached to that subnet.
          - If the target is a VPC, flow logs will be collected for instance network
          interfaces
            attached to all subnets within that VPC.
          If the target is an instance, subnet, or VPC, flow logs will not be collected
          for any instance network interfaces within the target that are themselves the
          target of
          a more specific flow log collector.
    :attr VPCReference vpc: The VPC this flow log collector resides in.
    """

    def __init__(
        self,
        active: bool,
        auto_delete: bool,
        created_at: datetime,
        crn: str,
        href: str,
        id: str,
        lifecycle_state: str,
        name: str,
        resource_group: 'ResourceGroupReference',
        storage_bucket: 'LegacyCloudObjectStorageBucketReference',
        target: 'FlowLogCollectorTarget',
        vpc: 'VPCReference',
    ) -> None:
        """
        Initialize a FlowLogCollector object.

        :param bool active: Indicates whether this collector is active.
        :param bool auto_delete: Indicates whether this flow log collector will be
               automatically deleted when `target` is deleted. At present, this is always
               `true`, but may be modifiable in the future.
        :param datetime created_at: The date and time that the flow log collector
               was created.
        :param str crn: The CRN for this flow log collector.
        :param str href: The URL for this flow log collector.
        :param str id: The unique identifier for this flow log collector.
        :param str lifecycle_state: The lifecycle state of the flow log collector.
        :param str name: The name for this flow log collector. The name is unique
               across all flow log collectors in the VPC.
        :param ResourceGroupReference resource_group: The resource group for this
               flow log collector.
        :param LegacyCloudObjectStorageBucketReference storage_bucket: The Cloud
               Object Storage bucket where the collected flows are logged. For more
               information, see [Viewing flow log
               objects](https://cloud.ibm.com/docs/vpc?topic=vpc-fl-analyze).
        :param FlowLogCollectorTarget target: The target this collector is
               collecting flow logs for.
               - If the target is an instance network interface, flow logs will be
               collected
                 for that instance network interface.
               - If the target is a virtual server instance, flow logs will be collected
                 for all network interfaces on that instance.
               - If the target is a subnet, flow logs will be collected
                 for all instance network interfaces attached to that subnet.
               - If the target is a VPC, flow logs will be collected for instance network
               interfaces
                 attached to all subnets within that VPC.
               If the target is an instance, subnet, or VPC, flow logs will not be
               collected
               for any instance network interfaces within the target that are themselves
               the target of
               a more specific flow log collector.
        :param VPCReference vpc: The VPC this flow log collector resides in.
        """
        self.active = active
        self.auto_delete = auto_delete
        self.created_at = created_at
        self.crn = crn
        self.href = href
        self.id = id
        self.lifecycle_state = lifecycle_state
        self.name = name
        self.resource_group = resource_group
        self.storage_bucket = storage_bucket
        self.target = target
        self.vpc = vpc

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'FlowLogCollector':
        """Initialize a FlowLogCollector object from a json dictionary."""
        args = {}
        if 'active' in _dict:
            args['active'] = _dict.get('active')
        else:
            raise ValueError('Required property \'active\' not present in FlowLogCollector JSON')
        if 'auto_delete' in _dict:
            args['auto_delete'] = _dict.get('auto_delete')
        else:
            raise ValueError('Required property \'auto_delete\' not present in FlowLogCollector JSON')
        if 'created_at' in _dict:
            args['created_at'] = string_to_datetime(_dict.get('created_at'))
        else:
            raise ValueError('Required property \'created_at\' not present in FlowLogCollector JSON')
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError('Required property \'crn\' not present in FlowLogCollector JSON')
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in FlowLogCollector JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in FlowLogCollector JSON')
        if 'lifecycle_state' in _dict:
            args['lifecycle_state'] = _dict.get('lifecycle_state')
        else:
            raise ValueError('Required property \'lifecycle_state\' not present in FlowLogCollector JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in FlowLogCollector JSON')
        if 'resource_group' in _dict:
            args['resource_group'] = ResourceGroupReference.from_dict(_dict.get('resource_group'))
        else:
            raise ValueError('Required property \'resource_group\' not present in FlowLogCollector JSON')
        if 'storage_bucket' in _dict:
            args['storage_bucket'] = LegacyCloudObjectStorageBucketReference.from_dict(_dict.get('storage_bucket'))
        else:
            raise ValueError('Required property \'storage_bucket\' not present in FlowLogCollector JSON')
        if 'target' in _dict:
            args['target'] = _dict.get('target')
        else:
            raise ValueError('Required property \'target\' not present in FlowLogCollector JSON')
        if 'vpc' in _dict:
            args['vpc'] = VPCReference.from_dict(_dict.get('vpc'))
        else:
            raise ValueError('Required property \'vpc\' not present in FlowLogCollector JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a FlowLogCollector object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'active') and self.active is not None:
            _dict['active'] = self.active
        if hasattr(self, 'auto_delete') and self.auto_delete is not None:
            _dict['auto_delete'] = self.auto_delete
        if hasattr(self, 'created_at') and self.created_at is not None:
            _dict['created_at'] = datetime_to_string(self.created_at)
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'lifecycle_state') and self.lifecycle_state is not None:
            _dict['lifecycle_state'] = self.lifecycle_state
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'resource_group') and self.resource_group is not None:
            if isinstance(self.resource_group, dict):
                _dict['resource_group'] = self.resource_group
            else:
                _dict['resource_group'] = self.resource_group.to_dict()
        if hasattr(self, 'storage_bucket') and self.storage_bucket is not None:
            if isinstance(self.storage_bucket, dict):
                _dict['storage_bucket'] = self.storage_bucket
            else:
                _dict['storage_bucket'] = self.storage_bucket.to_dict()
        if hasattr(self, 'target') and self.target is not None:
            if isinstance(self.target, dict):
                _dict['target'] = self.target
            else:
                _dict['target'] = self.target.to_dict()
        if hasattr(self, 'vpc') and self.vpc is not None:
            if isinstance(self.vpc, dict):
                _dict['vpc'] = self.vpc
            else:
                _dict['vpc'] = self.vpc.to_dict()
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this FlowLogCollector object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'FlowLogCollector') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'FlowLogCollector') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class LifecycleStateEnum(str, Enum):
        """
        The lifecycle state of the flow log collector.
        """

        DELETING = 'deleting'
        FAILED = 'failed'
        PENDING = 'pending'
        STABLE = 'stable'
        SUSPENDED = 'suspended'
        UPDATING = 'updating'
        WAITING = 'waiting'



class FlowLogCollectorCollection:
    """
    FlowLogCollectorCollection.

    :attr FlowLogCollectorCollectionFirst first: A link to the first page of
          resources.
    :attr List[FlowLogCollector] flow_log_collectors: Collection of flow log
          collectors.
    :attr int limit: The maximum number of resources that can be returned by the
          request.
    :attr FlowLogCollectorCollectionNext next: (optional) A link to the next page of
          resources. This property is present for all pages
          except the last page.
    :attr int total_count: The total number of resources across all pages.
    """

    def __init__(
        self,
        first: 'FlowLogCollectorCollectionFirst',
        flow_log_collectors: List['FlowLogCollector'],
        limit: int,
        total_count: int,
        *,
        next: 'FlowLogCollectorCollectionNext' = None,
    ) -> None:
        """
        Initialize a FlowLogCollectorCollection object.

        :param FlowLogCollectorCollectionFirst first: A link to the first page of
               resources.
        :param List[FlowLogCollector] flow_log_collectors: Collection of flow log
               collectors.
        :param int limit: The maximum number of resources that can be returned by
               the request.
        :param int total_count: The total number of resources across all pages.
        :param FlowLogCollectorCollectionNext next: (optional) A link to the next
               page of resources. This property is present for all pages
               except the last page.
        """
        self.first = first
        self.flow_log_collectors = flow_log_collectors
        self.limit = limit
        self.next = next
        self.total_count = total_count

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'FlowLogCollectorCollection':
        """Initialize a FlowLogCollectorCollection object from a json dictionary."""
        args = {}
        if 'first' in _dict:
            args['first'] = FlowLogCollectorCollectionFirst.from_dict(_dict.get('first'))
        else:
            raise ValueError('Required property \'first\' not present in FlowLogCollectorCollection JSON')
        if 'flow_log_collectors' in _dict:
            args['flow_log_collectors'] = [FlowLogCollector.from_dict(v) for v in _dict.get('flow_log_collectors')]
        else:
            raise ValueError('Required property \'flow_log_collectors\' not present in FlowLogCollectorCollection JSON')
        if 'limit' in _dict:
            args['limit'] = _dict.get('limit')
        else:
            raise ValueError('Required property \'limit\' not present in FlowLogCollectorCollection JSON')
        if 'next' in _dict:
            args['next'] = FlowLogCollectorCollectionNext.from_dict(_dict.get('next'))
        if 'total_count' in _dict:
            args['total_count'] = _dict.get('total_count')
        else:
            raise ValueError('Required property \'total_count\' not present in FlowLogCollectorCollection JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a FlowLogCollectorCollection object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'first') and self.first is not None:
            if isinstance(self.first, dict):
                _dict['first'] = self.first
            else:
                _dict['first'] = self.first.to_dict()
        if hasattr(self, 'flow_log_collectors') and self.flow_log_collectors is not None:
            flow_log_collectors_list = []
            for v in self.flow_log_collectors:
                if isinstance(v, dict):
                    flow_log_collectors_list.append(v)
                else:
                    flow_log_collectors_list.append(v.to_dict())
            _dict['flow_log_collectors'] = flow_log_collectors_list
        if hasattr(self, 'limit') and self.limit is not None:
            _dict['limit'] = self.limit
        if hasattr(self, 'next') and self.next is not None:
            if isinstance(self.next, dict):
                _dict['next'] = self.next
            else:
                _dict['next'] = self.next.to_dict()
        if hasattr(self, 'total_count') and self.total_count is not None:
            _dict['total_count'] = self.total_count
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this FlowLogCollectorCollection object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'FlowLogCollectorCollection') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'FlowLogCollectorCollection') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class FlowLogCollectorCollectionFirst:
    """
    A link to the first page of resources.

    :attr str href: The URL for a page of resources.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a FlowLogCollectorCollectionFirst object.

        :param str href: The URL for a page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'FlowLogCollectorCollectionFirst':
        """Initialize a FlowLogCollectorCollectionFirst object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in FlowLogCollectorCollectionFirst JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a FlowLogCollectorCollectionFirst object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this FlowLogCollectorCollectionFirst object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'FlowLogCollectorCollectionFirst') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'FlowLogCollectorCollectionFirst') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class FlowLogCollectorCollectionNext:
    """
    A link to the next page of resources. This property is present for all pages except
    the last page.

    :attr str href: The URL for a page of resources.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a FlowLogCollectorCollectionNext object.

        :param str href: The URL for a page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'FlowLogCollectorCollectionNext':
        """Initialize a FlowLogCollectorCollectionNext object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in FlowLogCollectorCollectionNext JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a FlowLogCollectorCollectionNext object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this FlowLogCollectorCollectionNext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'FlowLogCollectorCollectionNext') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'FlowLogCollectorCollectionNext') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class FlowLogCollectorPatch:
    """
    FlowLogCollectorPatch.

    :attr bool active: (optional) Indicates whether this collector is active.
          Updating to false deactivates the collector and updating to true activates the
          collector.
    :attr str name: (optional) The name for this flow log collector. The name must
          not be used by another flow log collector in the VPC.
    """

    def __init__(
        self,
        *,
        active: bool = None,
        name: str = None,
    ) -> None:
        """
        Initialize a FlowLogCollectorPatch object.

        :param bool active: (optional) Indicates whether this collector is active.
               Updating to false deactivates the collector and updating to true activates
               the collector.
        :param str name: (optional) The name for this flow log collector. The name
               must not be used by another flow log collector in the VPC.
        """
        self.active = active
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'FlowLogCollectorPatch':
        """Initialize a FlowLogCollectorPatch object from a json dictionary."""
        args = {}
        if 'active' in _dict:
            args['active'] = _dict.get('active')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a FlowLogCollectorPatch object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'active') and self.active is not None:
            _dict['active'] = self.active
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this FlowLogCollectorPatch object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'FlowLogCollectorPatch') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'FlowLogCollectorPatch') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class FlowLogCollectorTarget:
    """
    The target this collector is collecting flow logs for.
    - If the target is an instance network interface, flow logs will be collected
      for that instance network interface.
    - If the target is a virtual server instance, flow logs will be collected
      for all network interfaces on that instance.
    - If the target is a subnet, flow logs will be collected
      for all instance network interfaces attached to that subnet.
    - If the target is a VPC, flow logs will be collected for instance network interfaces
      attached to all subnets within that VPC. If the target is an instance, subnet, or
    VPC, flow logs will not be collected for any instance network interfaces within the
    target that are themselves the target of a more specific flow log collector.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a FlowLogCollectorTarget object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['FlowLogCollectorTargetNetworkInterfaceReferenceTargetContext', 'FlowLogCollectorTargetInstanceReference', 'FlowLogCollectorTargetSubnetReference', 'FlowLogCollectorTargetVPCReference'])
        )
        raise Exception(msg)


class FlowLogCollectorTargetPrototype:
    """
    The target this collector will collect flow logs for. If the target is an instance,
    subnet, or VPC, flow logs will not be collected for any instance network interfaces
    within the target that are themselves the target of a more specific flow log
    collector.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a FlowLogCollectorTargetPrototype object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['FlowLogCollectorTargetPrototypeNetworkInterfaceIdentity', 'FlowLogCollectorTargetPrototypeInstanceIdentity', 'FlowLogCollectorTargetPrototypeSubnetIdentity', 'FlowLogCollectorTargetPrototypeVPCIdentity'])
        )
        raise Exception(msg)


class GenericResourceReferenceDeleted:
    """
    If present, this property indicates the referenced resource has been deleted, and
    provides some supplementary information.

    :attr str more_info: Link to documentation about deleted resources.
    """

    def __init__(
        self,
        more_info: str,
    ) -> None:
        """
        Initialize a GenericResourceReferenceDeleted object.

        :param str more_info: Link to documentation about deleted resources.
        """
        self.more_info = more_info

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'GenericResourceReferenceDeleted':
        """Initialize a GenericResourceReferenceDeleted object from a json dictionary."""
        args = {}
        if 'more_info' in _dict:
            args['more_info'] = _dict.get('more_info')
        else:
            raise ValueError('Required property \'more_info\' not present in GenericResourceReferenceDeleted JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a GenericResourceReferenceDeleted object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'more_info') and self.more_info is not None:
            _dict['more_info'] = self.more_info
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this GenericResourceReferenceDeleted object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'GenericResourceReferenceDeleted') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'GenericResourceReferenceDeleted') -> 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
          The `md5` and `sha1` algorithms have been deprecated.
    :attr List[VPNGatewayConnectionReference] connections: The 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
          Groups `2` and `5` have been deprecated.
    :attr str encryption_algorithm: The encryption algorithm
          The `triple_des` algorithm has been deprecated.
    :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 name for this IKE policy. The name is unique across all IKE
          policies in the region.
    :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
               The `md5` and `sha1` algorithms have been deprecated.
        :param List[VPNGatewayConnectionReference] connections: The 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
               Groups `2` and `5` have been deprecated.
        :param str encryption_algorithm: The encryption algorithm
               The `triple_des` algorithm has been deprecated.
        :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 name for this IKE policy. The name is unique across
               all IKE policies in the region.
        :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(v) for v 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:
            connections_list = []
            for v in self.connections:
                if isinstance(v, dict):
                    connections_list.append(v)
                else:
                    connections_list.append(v.to_dict())
            _dict['connections'] = connections_list
        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:
            if isinstance(self.resource_group, dict):
                _dict['resource_group'] = self.resource_group
            else:
                _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
        The `md5` and `sha1` algorithms have been deprecated.
        """

        MD5 = 'md5'
        SHA1 = 'sha1'
        SHA256 = 'sha256'
        SHA384 = 'sha384'
        SHA512 = 'sha512'


    class EncryptionAlgorithmEnum(str, Enum):
        """
        The encryption algorithm
        The `triple_des` algorithm has been deprecated.
        """

        AES128 = 'aes128'
        AES192 = 'aes192'
        AES256 = 'aes256'
        TRIPLE_DES = 'triple_des'


    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(v) for v 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:
            if isinstance(self.first, dict):
                _dict['first'] = self.first
            else:
                _dict['first'] = self.first.to_dict()
        if hasattr(self, 'ike_policies') and self.ike_policies is not None:
            ike_policies_list = []
            for v in self.ike_policies:
                if isinstance(v, dict):
                    ike_policies_list.append(v)
                else:
                    ike_policies_list.append(v.to_dict())
            _dict['ike_policies'] = ike_policies_list
        if hasattr(self, 'limit') and self.limit is not None:
            _dict['limit'] = self.limit
        if hasattr(self, 'next') and self.next is not None:
            if isinstance(self.next, dict):
                _dict['next'] = self.next
            else:
                _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 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 name for this IKE policy. The name must not be
          used by another IKE policy in the region.
    """

    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 name for this IKE policy. The name must not
               be used by another IKE policy in the region.
        """
        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.
        """

        SHA256 = 'sha256'
        SHA384 = 'sha384'
        SHA512 = 'sha512'


    class EncryptionAlgorithmEnum(str, Enum):
        """
        The encryption algorithm.
        """

        AES128 = 'aes128'
        AES192 = 'aes192'
        AES256 = 'aes256'



class IKEPolicyReference:
    """
    IKEPolicyReference.

    :attr IKEPolicyReferenceDeleted deleted: (optional) If present, this property
          indicates the referenced resource has been deleted, and provides
          some supplementary information.
    :attr str href: The IKE policy's canonical URL.
    :attr str id: The unique identifier for this IKE policy.
    :attr str name: The name for this IKE policy. The name is unique across all IKE
          policies in the region.
    :attr str resource_type: The resource type.
    """

    def __init__(
        self,
        href: str,
        id: str,
        name: str,
        resource_type: str,
        *,
        deleted: 'IKEPolicyReferenceDeleted' = None,
    ) -> None:
        """
        Initialize a IKEPolicyReference object.

        :param str href: The IKE policy's canonical URL.
        :param str id: The unique identifier for this IKE policy.
        :param str name: The name for this IKE policy. The name is unique across
               all IKE policies in the region.
        :param str resource_type: The resource type.
        :param IKEPolicyReferenceDeleted deleted: (optional) If present, this
               property indicates the referenced resource has been deleted, and provides
               some supplementary information.
        """
        self.deleted = deleted
        self.href = href
        self.id = id
        self.name = name
        self.resource_type = resource_type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'IKEPolicyReference':
        """Initialize a IKEPolicyReference object from a json dictionary."""
        args = {}
        if 'deleted' in _dict:
            args['deleted'] = IKEPolicyReferenceDeleted.from_dict(_dict.get('deleted'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in IKEPolicyReference JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in IKEPolicyReference JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in IKEPolicyReference JSON')
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError('Required property \'resource_type\' not present in IKEPolicyReference JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a IKEPolicyReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'deleted') and self.deleted is not None:
            if isinstance(self.deleted, dict):
                _dict['deleted'] = self.deleted
            else:
                _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'resource_type') and self.resource_type is not None:
            _dict['resource_type'] = self.resource_type
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this IKEPolicyReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'IKEPolicyReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'IKEPolicyReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        IKE_POLICY = 'ike_policy'



class IKEPolicyReferenceDeleted:
    """
    If present, this property indicates the referenced resource has been deleted, and
    provides some supplementary information.

    :attr str more_info: Link to documentation about deleted resources.
    """

    def __init__(
        self,
        more_info: str,
    ) -> None:
        """
        Initialize a IKEPolicyReferenceDeleted object.

        :param str more_info: Link to documentation about deleted resources.
        """
        self.more_info = more_info

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'IKEPolicyReferenceDeleted':
        """Initialize a IKEPolicyReferenceDeleted object from a json dictionary."""
        args = {}
        if 'more_info' in _dict:
            args['more_info'] = _dict.get('more_info')
        else:
            raise ValueError('Required property \'more_info\' not present in IKEPolicyReferenceDeleted JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a IKEPolicyReferenceDeleted object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'more_info') and self.more_info is not None:
            _dict['more_info'] = self.more_info
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this IKEPolicyReferenceDeleted object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'IKEPolicyReferenceDeleted') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'IKEPolicyReferenceDeleted') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class IP:
    """
    IP.

    :attr str address: The IP address.
          This property may add support for IPv6 addresses in the future. When processing
          a value in this property, verify that the address is in an expected format. If
          it is not, log an error. Optionally halt processing and surface the error, or
          bypass the resource on which the unexpected IP address format was encountered.
    """

    def __init__(
        self,
        address: str,
    ) -> None:
        """
        Initialize a IP object.

        :param str address: The IP address.
               This property may add support for IPv6 addresses in the future. When
               processing a value in this property, verify that the address is in an
               expected format. If it is not, log an error. Optionally halt processing and
               surface the error, or bypass the resource on which the unexpected IP
               address format was encountered.
        """
        self.address = address

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'IP':
        """Initialize a IP object from a json dictionary."""
        args = {}
        if 'address' in _dict:
            args['address'] = _dict.get('address')
        else:
            raise ValueError('Required property \'address\' not present in IP JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a IP object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'address') and self.address is not None:
            _dict['address'] = self.address
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this IP object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'IP') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'IP') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class IPsecPolicy:
    """
    IPsecPolicy.

    :attr str authentication_algorithm: The authentication algorithm
          The `md5` and `sha1` algorithms have been deprecated
          Must be `disabled` if and only if the `encryption_algorithm` is
          `aes128gcm16`, `aes192gcm16`, or `aes256gcm16`.
    :attr List[VPNGatewayConnectionReference] connections: The 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
          The `triple_des` algorithm has been deprecated
          The `authentication_algorithm` must be `disabled` if and only if
          `encryption_algorithm` is `aes128gcm16`, `aes192gcm16`, or
          `aes256gcm16`.
    :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 name for this IPsec policy. The name is unique across all
          IPsec policies in the region.
    :attr str pfs: Perfect Forward Secrecy
          Groups `group_2` and `group_5` have been deprecated.
    :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
               The `md5` and `sha1` algorithms have been deprecated
               Must be `disabled` if and only if the `encryption_algorithm` is
               `aes128gcm16`, `aes192gcm16`, or `aes256gcm16`.
        :param List[VPNGatewayConnectionReference] connections: The 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
               The `triple_des` algorithm has been deprecated
               The `authentication_algorithm` must be `disabled` if and only if
               `encryption_algorithm` is `aes128gcm16`, `aes192gcm16`, or
               `aes256gcm16`.
        :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 name for this IPsec policy. The name is unique across
               all IPsec policies in the region.
        :param str pfs: Perfect Forward Secrecy
               Groups `group_2` and `group_5` have been deprecated.
        :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(v) for v 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:
            connections_list = []
            for v in self.connections:
                if isinstance(v, dict):
                    connections_list.append(v)
                else:
                    connections_list.append(v.to_dict())
            _dict['connections'] = connections_list
        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:
            if isinstance(self.resource_group, dict):
                _dict['resource_group'] = self.resource_group
            else:
                _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
        The `md5` and `sha1` algorithms have been deprecated
        Must be `disabled` if and only if the `encryption_algorithm` is
        `aes128gcm16`, `aes192gcm16`, or `aes256gcm16`.
        """

        DISABLED = 'disabled'
        MD5 = 'md5'
        SHA1 = 'sha1'
        SHA256 = 'sha256'
        SHA384 = 'sha384'
        SHA512 = 'sha512'


    class EncapsulationModeEnum(str, Enum):
        """
        The encapsulation mode used. Only `tunnel` is supported.
        """

        TUNNEL = 'tunnel'


    class EncryptionAlgorithmEnum(str, Enum):
        """
        The encryption algorithm
        The `triple_des` algorithm has been deprecated
        The `authentication_algorithm` must be `disabled` if and only if
        `encryption_algorithm` is `aes128gcm16`, `aes192gcm16`, or
        `aes256gcm16`.
        """

        AES128 = 'aes128'
        AES128GCM16 = 'aes128gcm16'
        AES192 = 'aes192'
        AES192GCM16 = 'aes192gcm16'
        AES256 = 'aes256'
        AES256GCM16 = 'aes256gcm16'
        TRIPLE_DES = 'triple_des'


    class PfsEnum(str, Enum):
        """
        Perfect Forward Secrecy
        Groups `group_2` and `group_5` have been deprecated.
        """

        DISABLED = 'disabled'
        GROUP_14 = 'group_14'
        GROUP_15 = 'group_15'
        GROUP_16 = 'group_16'
        GROUP_17 = 'group_17'
        GROUP_18 = 'group_18'
        GROUP_19 = 'group_19'
        GROUP_2 = 'group_2'
        GROUP_20 = 'group_20'
        GROUP_21 = 'group_21'
        GROUP_22 = 'group_22'
        GROUP_23 = 'group_23'
        GROUP_24 = 'group_24'
        GROUP_31 = 'group_31'
        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(v) for v 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:
            if isinstance(self.first, dict):
                _dict['first'] = self.first
            else:
                _dict['first'] = self.first.to_dict()
        if hasattr(self, 'ipsec_policies') and self.ipsec_policies is not None:
            ipsec_policies_list = []
            for v in self.ipsec_policies:
                if isinstance(v, dict):
                    ipsec_policies_list.append(v)
                else:
                    ipsec_policies_list.append(v.to_dict())
            _dict['ipsec_policies'] = ipsec_policies_list
        if hasattr(self, 'limit') and self.limit is not None:
            _dict['limit'] = self.limit
        if hasattr(self, 'next') and self.next is not None:
            if isinstance(self.next, dict):
                _dict['next'] = self.next
            else:
                _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 IPsecPolicyPatch:
    """
    IPsecPolicyPatch.

    :attr str authentication_algorithm: (optional) The authentication algorithm
          Must be `disabled` if and only if the `encryption_algorithm` is
          `aes128gcm16`, `aes192gcm16`, or `aes256gcm16`.
    :attr str encryption_algorithm: (optional) The encryption algorithm
          The `authentication_algorithm` must be `disabled` if and only if
          `encryption_algorithm` is `aes128gcm16`, `aes192gcm16`, or
          `aes256gcm16`.
    :attr int key_lifetime: (optional) The key lifetime in seconds.
    :attr str name: (optional) The name for this IPsec policy. The name must not be
          used by another IPsec policy in the region.
    :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
               Must be `disabled` if and only if the `encryption_algorithm` is
               `aes128gcm16`, `aes192gcm16`, or `aes256gcm16`.
        :param str encryption_algorithm: (optional) The encryption algorithm
               The `authentication_algorithm` must be `disabled` if and only if
               `encryption_algorithm` is `aes128gcm16`, `aes192gcm16`, or
               `aes256gcm16`.
        :param int key_lifetime: (optional) The key lifetime in seconds.
        :param str name: (optional) The name for this IPsec policy. The name must
               not be used by another IPsec policy in the region.
        :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
        Must be `disabled` if and only if the `encryption_algorithm` is
        `aes128gcm16`, `aes192gcm16`, or `aes256gcm16`.
        """

        DISABLED = 'disabled'
        SHA256 = 'sha256'
        SHA384 = 'sha384'
        SHA512 = 'sha512'


    class EncryptionAlgorithmEnum(str, Enum):
        """
        The encryption algorithm
        The `authentication_algorithm` must be `disabled` if and only if
        `encryption_algorithm` is `aes128gcm16`, `aes192gcm16`, or
        `aes256gcm16`.
        """

        AES128 = 'aes128'
        AES128GCM16 = 'aes128gcm16'
        AES192 = 'aes192'
        AES192GCM16 = 'aes192gcm16'
        AES256 = 'aes256'
        AES256GCM16 = 'aes256gcm16'


    class PfsEnum(str, Enum):
        """
        Perfect Forward Secrecy.
        """

        DISABLED = 'disabled'
        GROUP_14 = 'group_14'
        GROUP_15 = 'group_15'
        GROUP_16 = 'group_16'
        GROUP_17 = 'group_17'
        GROUP_18 = 'group_18'
        GROUP_19 = 'group_19'
        GROUP_20 = 'group_20'
        GROUP_21 = 'group_21'
        GROUP_22 = 'group_22'
        GROUP_23 = 'group_23'
        GROUP_24 = 'group_24'
        GROUP_31 = 'group_31'



class IPsecPolicyReference:
    """
    IPsecPolicyReference.

    :attr IPsecPolicyReferenceDeleted deleted: (optional) If present, this property
          indicates the referenced resource has been deleted, and provides
          some supplementary information.
    :attr str href: The IPsec policy's canonical URL.
    :attr str id: The unique identifier for this IPsec policy.
    :attr str name: The name for this IPsec policy. The name is unique across all
          IPsec policies in the region.
    :attr str resource_type: The resource type.
    """

    def __init__(
        self,
        href: str,
        id: str,
        name: str,
        resource_type: str,
        *,
        deleted: 'IPsecPolicyReferenceDeleted' = None,
    ) -> None:
        """
        Initialize a IPsecPolicyReference object.

        :param str href: The IPsec policy's canonical URL.
        :param str id: The unique identifier for this IPsec policy.
        :param str name: The name for this IPsec policy. The name is unique across
               all IPsec policies in the region.
        :param str resource_type: The resource type.
        :param IPsecPolicyReferenceDeleted deleted: (optional) If present, this
               property indicates the referenced resource has been deleted, and provides
               some supplementary information.
        """
        self.deleted = deleted
        self.href = href
        self.id = id
        self.name = name
        self.resource_type = resource_type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'IPsecPolicyReference':
        """Initialize a IPsecPolicyReference object from a json dictionary."""
        args = {}
        if 'deleted' in _dict:
            args['deleted'] = IPsecPolicyReferenceDeleted.from_dict(_dict.get('deleted'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in IPsecPolicyReference JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in IPsecPolicyReference JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in IPsecPolicyReference JSON')
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError('Required property \'resource_type\' not present in IPsecPolicyReference JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a IPsecPolicyReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'deleted') and self.deleted is not None:
            if isinstance(self.deleted, dict):
                _dict['deleted'] = self.deleted
            else:
                _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'resource_type') and self.resource_type is not None:
            _dict['resource_type'] = self.resource_type
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this IPsecPolicyReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'IPsecPolicyReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'IPsecPolicyReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        IPSEC_POLICY = 'ipsec_policy'



class IPsecPolicyReferenceDeleted:
    """
    If present, this property indicates the referenced resource has been deleted, and
    provides some supplementary information.

    :attr str more_info: Link to documentation about deleted resources.
    """

    def __init__(
        self,
        more_info: str,
    ) -> None:
        """
        Initialize a IPsecPolicyReferenceDeleted object.

        :param str more_info: Link to documentation about deleted resources.
        """
        self.more_info = more_info

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'IPsecPolicyReferenceDeleted':
        """Initialize a IPsecPolicyReferenceDeleted object from a json dictionary."""
        args = {}
        if 'more_info' in _dict:
            args['more_info'] = _dict.get('more_info')
        else:
            raise ValueError('Required property \'more_info\' not present in IPsecPolicyReferenceDeleted JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a IPsecPolicyReferenceDeleted object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'more_info') and self.more_info is not None:
            _dict['more_info'] = self.more_info
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this IPsecPolicyReferenceDeleted object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'IPsecPolicyReferenceDeleted') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'IPsecPolicyReferenceDeleted') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class Image:
    """
    Image.

    :attr ImageCatalogOffering catalog_offering:
    :attr datetime created_at: The date and time that the image was created.
    :attr str crn: The CRN for this image.
    :attr datetime deprecation_at: (optional) The deprecation date and time (UTC)
          for this image.
          If absent, no deprecation date and time has been set.
    :attr str encryption: The type of encryption used on the image.
    :attr EncryptionKeyReference encryption_key: (optional) The key that will be
          used to encrypt volumes created from this image (unless an
          alternate `encryption_key` is specified at volume creation).
          This property will be present for images with an `encryption` type of
          `user_managed`.
    :attr ImageFile file: Details for the stored image file.
    :attr str href: The URL for this image.
    :attr str id: The unique identifier for this image.
    :attr int minimum_provisioned_size: (optional) The minimum size (in gigabytes)
          of a volume onto which this image may be provisioned.
          This property may be absent if the image has a `status` of `pending` or
          `failed`.
    :attr str name: The name for this image. The name is unique across all images in
          the region.
    :attr datetime obsolescence_at: (optional) The obsolescence date and time (UTC)
          for this image.
          If absent, no obsolescence date and time has been set.
    :attr OperatingSystem operating_system: (optional) The operating system included
          in this image.
    :attr ResourceGroupReference resource_group: The resource group for this image.
    :attr str resource_type: The resource type.
    :attr VolumeReference source_volume: (optional) The volume used to create this
          image (this may be
          [deleted](https://cloud.ibm.com/apidocs/vpc#deleted-resources)).
          If absent, this image was not created from a volume.
    :attr str status: The status of this image
          - available: image can be used (provisionable)
          - deleting: image is being deleted, and can no longer be used to provision new
            resources
          - deprecated: image is administratively slated to become `obsolete`
          - failed: image is corrupt or did not pass validation
          - obsolete: image administratively set to not be used for new resources
          - pending: image is being imported and is not yet `available`
          - unusable: image cannot be used (see `status_reasons[]` for possible
          remediation)
          The enumerated values for this property are expected to expand in the future.
          When processing this property, check for and log unknown values. Optionally halt
          processing and surface the error, or bypass the image on which the unexpected
          property value was encountered.
    :attr List[ImageStatusReason] status_reasons: The reasons for the current status
          (if any):
          - `encrypted_data_key_invalid`: image cannot be decrypted with the specified
            `encryption_key`
          - `encryption_key_deleted`: image unusable because its `encryption_key` was
          deleted
          - `encryption_key_disabled`: image unusable until its `encryption_key` is
          re-enabled
          - `image_data_corrupted`: image data is corrupt, or is not in the specified
          format
          - `image_provisioned_size_unsupported`: image requires a boot volume size
          greater
            than the maximum supported value
          - `image_request_in_progress`: image operation is in progress (such as an import
          from
             Cloud Object Storage)
          - `image_request_queued`: image request has been accepted but the requested
            operation has not started
          The enumerated reason code values for this property will expand in the future.
          When processing this property, check for and log unknown values. Optionally halt
          processing and surface the error, or bypass the resource on which the unexpected
          reason code was encountered.
    :attr str visibility: The visibility of this image.
          - `private`: Visible only to this account
          - `public`: Visible to all accounts.
    """

    def __init__(
        self,
        catalog_offering: 'ImageCatalogOffering',
        created_at: datetime,
        crn: str,
        encryption: str,
        file: 'ImageFile',
        href: str,
        id: str,
        name: str,
        resource_group: 'ResourceGroupReference',
        resource_type: str,
        status: str,
        status_reasons: List['ImageStatusReason'],
        visibility: str,
        *,
        deprecation_at: datetime = None,
        encryption_key: 'EncryptionKeyReference' = None,
        minimum_provisioned_size: int = None,
        obsolescence_at: datetime = None,
        operating_system: 'OperatingSystem' = None,
        source_volume: 'VolumeReference' = None,
    ) -> None:
        """
        Initialize a Image object.

        :param ImageCatalogOffering catalog_offering:
        :param datetime created_at: The date and time that the image was created.
        :param str crn: The CRN for this image.
        :param str encryption: The type of encryption used on the image.
        :param ImageFile file: Details for the stored image file.
        :param str href: The URL for this image.
        :param str id: The unique identifier for this image.
        :param str name: The name for this image. The name is unique across all
               images in the region.
        :param ResourceGroupReference resource_group: The resource group for this
               image.
        :param str resource_type: The resource type.
        :param str status: The status of this image
               - available: image can be used (provisionable)
               - deleting: image is being deleted, and can no longer be used to provision
               new
                 resources
               - deprecated: image is administratively slated to become `obsolete`
               - failed: image is corrupt or did not pass validation
               - obsolete: image administratively set to not be used for new resources
               - pending: image is being imported and is not yet `available`
               - unusable: image cannot be used (see `status_reasons[]` for possible
               remediation)
               The enumerated values for this property are expected to expand in the
               future. When processing this property, check for and log unknown values.
               Optionally halt processing and surface the error, or bypass the image on
               which the unexpected property value was encountered.
        :param List[ImageStatusReason] status_reasons: The reasons for the current
               status (if any):
               - `encrypted_data_key_invalid`: image cannot be decrypted with the
               specified
                 `encryption_key`
               - `encryption_key_deleted`: image unusable because its `encryption_key` was
               deleted
               - `encryption_key_disabled`: image unusable until its `encryption_key` is
               re-enabled
               - `image_data_corrupted`: image data is corrupt, or is not in the specified
               format
               - `image_provisioned_size_unsupported`: image requires a boot volume size
               greater
                 than the maximum supported value
               - `image_request_in_progress`: image operation is in progress (such as an
               import from
                  Cloud Object Storage)
               - `image_request_queued`: image request has been accepted but the requested
                 operation has not started
               The enumerated reason code values for this property will expand in the
               future. When processing this property, check for and log unknown values.
               Optionally halt processing and surface the error, or bypass the resource on
               which the unexpected reason code was encountered.
        :param str visibility: The visibility of this image.
               - `private`: Visible only to this account
               - `public`: Visible to all accounts.
        :param datetime deprecation_at: (optional) The deprecation date and time
               (UTC) for this image.
               If absent, no deprecation date and time has been set.
        :param EncryptionKeyReference encryption_key: (optional) The key that will
               be used to encrypt volumes created from this image (unless an
               alternate `encryption_key` is specified at volume creation).
               This property will be present for images with an `encryption` type of
               `user_managed`.
        :param int minimum_provisioned_size: (optional) The minimum size (in
               gigabytes) of a volume onto which this image may be provisioned.
               This property may be absent if the image has a `status` of `pending` or
               `failed`.
        :param datetime obsolescence_at: (optional) The obsolescence date and time
               (UTC) for this image.
               If absent, no obsolescence date and time has been set.
        :param OperatingSystem operating_system: (optional) The operating system
               included in this image.
        :param VolumeReference source_volume: (optional) The volume used to create
               this image (this may be
               [deleted](https://cloud.ibm.com/apidocs/vpc#deleted-resources)).
               If absent, this image was not created from a volume.
        """
        self.catalog_offering = catalog_offering
        self.created_at = created_at
        self.crn = crn
        self.deprecation_at = deprecation_at
        self.encryption = encryption
        self.encryption_key = encryption_key
        self.file = file
        self.href = href
        self.id = id
        self.minimum_provisioned_size = minimum_provisioned_size
        self.name = name
        self.obsolescence_at = obsolescence_at
        self.operating_system = operating_system
        self.resource_group = resource_group
        self.resource_type = resource_type
        self.source_volume = source_volume
        self.status = status
        self.status_reasons = status_reasons
        self.visibility = visibility

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'Image':
        """Initialize a Image object from a json dictionary."""
        args = {}
        if 'catalog_offering' in _dict:
            args['catalog_offering'] = ImageCatalogOffering.from_dict(_dict.get('catalog_offering'))
        else:
            raise ValueError('Required property \'catalog_offering\' not present in Image JSON')
        if 'created_at' in _dict:
            args['created_at'] = string_to_datetime(_dict.get('created_at'))
        else:
            raise ValueError('Required property \'created_at\' not present in Image JSON')
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError('Required property \'crn\' not present in Image JSON')
        if 'deprecation_at' in _dict:
            args['deprecation_at'] = string_to_datetime(_dict.get('deprecation_at'))
        if 'encryption' in _dict:
            args['encryption'] = _dict.get('encryption')
        else:
            raise ValueError('Required property \'encryption\' not present in Image JSON')
        if 'encryption_key' in _dict:
            args['encryption_key'] = EncryptionKeyReference.from_dict(_dict.get('encryption_key'))
        if 'file' in _dict:
            args['file'] = ImageFile.from_dict(_dict.get('file'))
        else:
            raise ValueError('Required property \'file\' not present in Image JSON')
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in Image JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in Image JSON')
        if 'minimum_provisioned_size' in _dict:
            args['minimum_provisioned_size'] = _dict.get('minimum_provisioned_size')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in Image JSON')
        if 'obsolescence_at' in _dict:
            args['obsolescence_at'] = string_to_datetime(_dict.get('obsolescence_at'))
        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 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError('Required property \'resource_type\' not present in Image JSON')
        if 'source_volume' in _dict:
            args['source_volume'] = VolumeReference.from_dict(_dict.get('source_volume'))
        if 'status' in _dict:
            args['status'] = _dict.get('status')
        else:
            raise ValueError('Required property \'status\' not present in Image JSON')
        if 'status_reasons' in _dict:
            args['status_reasons'] = [ImageStatusReason.from_dict(v) for v in _dict.get('status_reasons')]
        else:
            raise ValueError('Required property \'status_reasons\' not present in Image JSON')
        if 'visibility' in _dict:
            args['visibility'] = _dict.get('visibility')
        else:
            raise ValueError('Required property \'visibility\' not present in Image JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a Image object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'catalog_offering') and self.catalog_offering is not None:
            if isinstance(self.catalog_offering, dict):
                _dict['catalog_offering'] = self.catalog_offering
            else:
                _dict['catalog_offering'] = self.catalog_offering.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, 'deprecation_at') and self.deprecation_at is not None:
            _dict['deprecation_at'] = datetime_to_string(self.deprecation_at)
        if hasattr(self, 'encryption') and self.encryption is not None:
            _dict['encryption'] = self.encryption
        if hasattr(self, 'encryption_key') and self.encryption_key is not None:
            if isinstance(self.encryption_key, dict):
                _dict['encryption_key'] = self.encryption_key
            else:
                _dict['encryption_key'] = self.encryption_key.to_dict()
        if hasattr(self, 'file') and self.file is not None:
            if isinstance(self.file, dict):
                _dict['file'] = self.file
            else:
                _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, 'obsolescence_at') and self.obsolescence_at is not None:
            _dict['obsolescence_at'] = datetime_to_string(self.obsolescence_at)
        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()
        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, 'resource_type') and self.resource_type is not None:
            _dict['resource_type'] = self.resource_type
        if hasattr(self, 'source_volume') and self.source_volume is not None:
            if isinstance(self.source_volume, dict):
                _dict['source_volume'] = self.source_volume
            else:
                _dict['source_volume'] = self.source_volume.to_dict()
        if hasattr(self, 'status') and self.status is not None:
            _dict['status'] = self.status
        if hasattr(self, 'status_reasons') and self.status_reasons is not None:
            status_reasons_list = []
            for v in self.status_reasons:
                if isinstance(v, dict):
                    status_reasons_list.append(v)
                else:
                    status_reasons_list.append(v.to_dict())
            _dict['status_reasons'] = status_reasons_list
        if hasattr(self, 'visibility') and self.visibility is not None:
            _dict['visibility'] = self.visibility
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this Image object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'Image') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'Image') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class EncryptionEnum(str, Enum):
        """
        The type of encryption used on the image.
        """

        NONE = 'none'
        USER_MANAGED = 'user_managed'


    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        IMAGE = 'image'


    class StatusEnum(str, Enum):
        """
        The status of this image
        - available: image can be used (provisionable)
        - deleting: image is being deleted, and can no longer be used to provision new
          resources
        - deprecated: image is administratively slated to become `obsolete`
        - failed: image is corrupt or did not pass validation
        - obsolete: image administratively set to not be used for new resources
        - pending: image is being imported and is not yet `available`
        - unusable: image cannot be used (see `status_reasons[]` for possible remediation)
        The enumerated values for this property are expected to expand in the future. When
        processing this property, check for and log unknown values. Optionally halt
        processing and surface the error, or bypass the image on which the unexpected
        property value was encountered.
        """

        AVAILABLE = 'available'
        DELETING = 'deleting'
        DEPRECATED = 'deprecated'
        FAILED = 'failed'
        OBSOLETE = 'obsolete'
        PENDING = 'pending'
        UNUSABLE = 'unusable'


    class VisibilityEnum(str, Enum):
        """
        The visibility of this image.
        - `private`: Visible only to this account
        - `public`: Visible to all accounts.
        """

        PRIVATE = 'private'
        PUBLIC = 'public'



class ImageCatalogOffering:
    """
    ImageCatalogOffering.

    :attr bool managed: Indicates whether this image is managed as part of a
          [catalog](https://cloud.ibm.com/docs/account?topic=account-restrict-by-user)
          offering. If an image is managed, accounts in the same
          [enterprise](https://cloud.ibm.com/docs/account?topic=account-what-is-enterprise)
          with access to that catalog can specify the image's catalog offering version CRN
          to provision virtual server instances using the image.
    :attr CatalogOfferingVersionReference version: (optional) The
          [catalog](https://cloud.ibm.com/docs/account?topic=account-restrict-by-user)
          offering version associated with this image.
          If absent, this image is not associated with a cloud catalog offering.
    """

    def __init__(
        self,
        managed: bool,
        *,
        version: 'CatalogOfferingVersionReference' = None,
    ) -> None:
        """
        Initialize a ImageCatalogOffering object.

        :param bool managed: Indicates whether this image is managed as part of a
               [catalog](https://cloud.ibm.com/docs/account?topic=account-restrict-by-user)
               offering. If an image is managed, accounts in the same
               [enterprise](https://cloud.ibm.com/docs/account?topic=account-what-is-enterprise)
               with access to that catalog can specify the image's catalog offering
               version CRN to provision virtual server instances using the image.
        :param CatalogOfferingVersionReference version: (optional) The
               [catalog](https://cloud.ibm.com/docs/account?topic=account-restrict-by-user)
               offering version associated with this image.
               If absent, this image is not associated with a cloud catalog offering.
        """
        self.managed = managed
        self.version = version

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ImageCatalogOffering':
        """Initialize a ImageCatalogOffering object from a json dictionary."""
        args = {}
        if 'managed' in _dict:
            args['managed'] = _dict.get('managed')
        else:
            raise ValueError('Required property \'managed\' not present in ImageCatalogOffering JSON')
        if 'version' in _dict:
            args['version'] = CatalogOfferingVersionReference.from_dict(_dict.get('version'))
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ImageCatalogOffering object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'managed') and self.managed is not None:
            _dict['managed'] = self.managed
        if hasattr(self, 'version') and self.version is not None:
            if isinstance(self.version, dict):
                _dict['version'] = self.version
            else:
                _dict['version'] = self.version.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 ImageCatalogOffering object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ImageCatalogOffering') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ImageCatalogOffering') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


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.
    :attr int total_count: The total number of resources across all pages.
    """

    def __init__(
        self,
        first: 'ImageCollectionFirst',
        images: List['Image'],
        limit: int,
        total_count: 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 int total_count: The total number of resources across all pages.
        :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
        self.total_count = total_count

    @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(v) for v 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'))
        if 'total_count' in _dict:
            args['total_count'] = _dict.get('total_count')
        else:
            raise ValueError('Required property \'total_count\' not present in ImageCollection JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ImageCollection object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'first') and self.first is not None:
            if isinstance(self.first, dict):
                _dict['first'] = self.first
            else:
                _dict['first'] = self.first.to_dict()
        if hasattr(self, 'images') and self.images is not None:
            images_list = []
            for v in self.images:
                if isinstance(v, dict):
                    images_list.append(v)
                else:
                    images_list.append(v.to_dict())
            _dict['images'] = images_list
        if hasattr(self, 'limit') and self.limit is not None:
            _dict['limit'] = self.limit
        if hasattr(self, 'next') and self.next is not None:
            if isinstance(self.next, dict):
                _dict['next'] = self.next
            else:
                _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 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 ImageExportJob:
    """
    ImageExportJob.

    :attr datetime completed_at: (optional) The date and time that the image export
          job was completed.
          If absent, the export job has not yet completed.
    :attr datetime created_at: The date and time that the image export job was
          created.
    :attr bytes encrypted_data_key: (optional) A base64-encoded, encrypted
          representation of the key that was used to encrypt the data for the exported
          image. This key can be unwrapped with the image's `encryption_key` root key
          using either Key Protect or Hyper Protect Crypto Services.
          If absent, the export job is for an unencrypted image.
    :attr str format: The format of the exported image.
    :attr str href: The URL for this image export job.
    :attr str id: The unique identifier for this image export job.
    :attr str name: The name for this image export job. The name must not be used by
          another export job for the image. Changing the name will not affect the exported
          image name,
          `storage_object.name`, or `storage_href` values.
    :attr str resource_type: The type of resource referenced.
    :attr datetime started_at: (optional) The date and time that the image export
          job started running.
          If absent, the export job has not yet started.
    :attr str status: The status of this image export job:
          - `deleting`: Export job is being deleted
          - `failed`: Export job could not be completed successfully
          - `queued`: Export job is queued
          - `running`: Export job is in progress
          - `succeeded`: Export job was completed successfully
          The exported image object is automatically deleted for `failed` jobs.
    :attr List[ImageExportJobStatusReason] status_reasons: The reasons for the
          current status (if any).
          The enumerated reason code values for this property will expand in the future.
          When processing this property, check for and log unknown values. Optionally halt
          processing and surface the error, or bypass the resource on which the unexpected
          reason code was encountered.
    :attr CloudObjectStorageBucketReference storage_bucket: The Cloud Object Storage
          bucket of the exported image object.
    :attr str storage_href: The Cloud Object Storage location of the exported image
          object. The object at this location will not exist until the job completes
          successfully. The exported image object is not managed by the IBM VPC service,
          and may be removed or replaced with a different object by any user or service
          with IAM authorization to the storage bucket.
    :attr CloudObjectStorageObjectReference storage_object: The Cloud Object Storage
          object for the exported image. This object will not exist until
          the job completes successfully. The exported image object is not managed by the
          IBM VPC
          service, and may be removed or replaced with a different object by any user or
          service
          with IAM authorization to the storage bucket.
    """

    def __init__(
        self,
        created_at: datetime,
        format: str,
        href: str,
        id: str,
        name: str,
        resource_type: str,
        status: str,
        status_reasons: List['ImageExportJobStatusReason'],
        storage_bucket: 'CloudObjectStorageBucketReference',
        storage_href: str,
        storage_object: 'CloudObjectStorageObjectReference',
        *,
        completed_at: datetime = None,
        encrypted_data_key: bytes = None,
        started_at: datetime = None,
    ) -> None:
        """
        Initialize a ImageExportJob object.

        :param datetime created_at: The date and time that the image export job was
               created.
        :param str format: The format of the exported image.
        :param str href: The URL for this image export job.
        :param str id: The unique identifier for this image export job.
        :param str name: The name for this image export job. The name must not be
               used by another export job for the image. Changing the name will not affect
               the exported image name,
               `storage_object.name`, or `storage_href` values.
        :param str resource_type: The type of resource referenced.
        :param str status: The status of this image export job:
               - `deleting`: Export job is being deleted
               - `failed`: Export job could not be completed successfully
               - `queued`: Export job is queued
               - `running`: Export job is in progress
               - `succeeded`: Export job was completed successfully
               The exported image object is automatically deleted for `failed` jobs.
        :param List[ImageExportJobStatusReason] status_reasons: The reasons for the
               current status (if any).
               The enumerated reason code values for this property will expand in the
               future. When processing this property, check for and log unknown values.
               Optionally halt processing and surface the error, or bypass the resource on
               which the unexpected reason code was encountered.
        :param CloudObjectStorageBucketReference storage_bucket: The Cloud Object
               Storage bucket of the exported image object.
        :param str storage_href: The Cloud Object Storage location of the exported
               image object. The object at this location will not exist until the job
               completes successfully. The exported image object is not managed by the IBM
               VPC service, and may be removed or replaced with a different object by any
               user or service with IAM authorization to the storage bucket.
        :param CloudObjectStorageObjectReference storage_object: The Cloud Object
               Storage object for the exported image. This object will not exist until
               the job completes successfully. The exported image object is not managed by
               the IBM VPC
               service, and may be removed or replaced with a different object by any user
               or service
               with IAM authorization to the storage bucket.
        :param datetime completed_at: (optional) The date and time that the image
               export job was completed.
               If absent, the export job has not yet completed.
        :param bytes encrypted_data_key: (optional) A base64-encoded, encrypted
               representation of the key that was used to encrypt the data for the
               exported image. This key can be unwrapped with the image's `encryption_key`
               root key using either Key Protect or Hyper Protect Crypto Services.
               If absent, the export job is for an unencrypted image.
        :param datetime started_at: (optional) The date and time that the image
               export job started running.
               If absent, the export job has not yet started.
        """
        self.completed_at = completed_at
        self.created_at = created_at
        self.encrypted_data_key = encrypted_data_key
        self.format = format
        self.href = href
        self.id = id
        self.name = name
        self.resource_type = resource_type
        self.started_at = started_at
        self.status = status
        self.status_reasons = status_reasons
        self.storage_bucket = storage_bucket
        self.storage_href = storage_href
        self.storage_object = storage_object

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ImageExportJob':
        """Initialize a ImageExportJob 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 ImageExportJob JSON')
        if 'encrypted_data_key' in _dict:
            args['encrypted_data_key'] = base64.b64decode(_dict.get('encrypted_data_key'))
        if 'format' in _dict:
            args['format'] = _dict.get('format')
        else:
            raise ValueError('Required property \'format\' not present in ImageExportJob JSON')
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in ImageExportJob JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in ImageExportJob JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in ImageExportJob JSON')
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError('Required property \'resource_type\' not present in ImageExportJob 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 ImageExportJob JSON')
        if 'status_reasons' in _dict:
            args['status_reasons'] = [ImageExportJobStatusReason.from_dict(v) for v in _dict.get('status_reasons')]
        else:
            raise ValueError('Required property \'status_reasons\' not present in ImageExportJob JSON')
        if 'storage_bucket' in _dict:
            args['storage_bucket'] = CloudObjectStorageBucketReference.from_dict(_dict.get('storage_bucket'))
        else:
            raise ValueError('Required property \'storage_bucket\' not present in ImageExportJob JSON')
        if 'storage_href' in _dict:
            args['storage_href'] = _dict.get('storage_href')
        else:
            raise ValueError('Required property \'storage_href\' not present in ImageExportJob JSON')
        if 'storage_object' in _dict:
            args['storage_object'] = CloudObjectStorageObjectReference.from_dict(_dict.get('storage_object'))
        else:
            raise ValueError('Required property \'storage_object\' not present in ImageExportJob JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ImageExportJob object from 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, 'encrypted_data_key') and self.encrypted_data_key is not None:
            _dict['encrypted_data_key'] = str(base64.b64encode(self.encrypted_data_key), 'utf-8')
        if hasattr(self, 'format') and self.format is not None:
            _dict['format'] = self.format
        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, '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, 'status_reasons') and self.status_reasons is not None:
            status_reasons_list = []
            for v in self.status_reasons:
                if isinstance(v, dict):
                    status_reasons_list.append(v)
                else:
                    status_reasons_list.append(v.to_dict())
            _dict['status_reasons'] = status_reasons_list
        if hasattr(self, 'storage_bucket') and self.storage_bucket is not None:
            if isinstance(self.storage_bucket, dict):
                _dict['storage_bucket'] = self.storage_bucket
            else:
                _dict['storage_bucket'] = self.storage_bucket.to_dict()
        if hasattr(self, 'storage_href') and self.storage_href is not None:
            _dict['storage_href'] = self.storage_href
        if hasattr(self, 'storage_object') and self.storage_object is not None:
            if isinstance(self.storage_object, dict):
                _dict['storage_object'] = self.storage_object
            else:
                _dict['storage_object'] = self.storage_object.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 ImageExportJob object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ImageExportJob') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ImageExportJob') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class FormatEnum(str, Enum):
        """
        The format of the exported image.
        """

        QCOW2 = 'qcow2'
        VHD = 'vhd'


    class ResourceTypeEnum(str, Enum):
        """
        The type of resource referenced.
        """

        IMAGE_EXPORT_JOB = 'image_export_job'


    class StatusEnum(str, Enum):
        """
        The status of this image export job:
        - `deleting`: Export job is being deleted
        - `failed`: Export job could not be completed successfully
        - `queued`: Export job is queued
        - `running`: Export job is in progress
        - `succeeded`: Export job was completed successfully
        The exported image object is automatically deleted for `failed` jobs.
        """

        DELETING = 'deleting'
        FAILED = 'failed'
        QUEUED = 'queued'
        RUNNING = 'running'
        SUCCEEDED = 'succeeded'



class ImageExportJobPatch:
    """
    ImageExportJobPatch.

    :attr str name: (optional) The name for this image export job. The name must not
          be used by another export job for the image. Changing the name will not affect
          the exported image name,
          `storage_object.name`, or `storage_href` values.
    """

    def __init__(
        self,
        *,
        name: str = None,
    ) -> None:
        """
        Initialize a ImageExportJobPatch object.

        :param str name: (optional) The name for this image export job. The name
               must not be used by another export job for the image. Changing the name
               will not affect the exported image name,
               `storage_object.name`, or `storage_href` values.
        """
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ImageExportJobPatch':
        """Initialize a ImageExportJobPatch 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 ImageExportJobPatch object from 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 ImageExportJobPatch object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ImageExportJobPatch') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ImageExportJobPatch') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class ImageExportJobStatusReason:
    """
    ImageExportJobStatusReason.

    :attr str code: A snake case string succinctly identifying the status reason.
    :attr str message: An explanation of the status reason.
    :attr str more_info: (optional) Link to documentation about this status reason.
    """

    def __init__(
        self,
        code: str,
        message: str,
        *,
        more_info: str = None,
    ) -> None:
        """
        Initialize a ImageExportJobStatusReason object.

        :param str code: A snake case string succinctly identifying the status
               reason.
        :param str message: An explanation of the status reason.
        :param str more_info: (optional) Link to documentation about this status
               reason.
        """
        self.code = code
        self.message = message
        self.more_info = more_info

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ImageExportJobStatusReason':
        """Initialize a ImageExportJobStatusReason object from a json dictionary."""
        args = {}
        if 'code' in _dict:
            args['code'] = _dict.get('code')
        else:
            raise ValueError('Required property \'code\' not present in ImageExportJobStatusReason JSON')
        if 'message' in _dict:
            args['message'] = _dict.get('message')
        else:
            raise ValueError('Required property \'message\' not present in ImageExportJobStatusReason JSON')
        if 'more_info' in _dict:
            args['more_info'] = _dict.get('more_info')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ImageExportJobStatusReason object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'code') and self.code is not None:
            _dict['code'] = self.code
        if hasattr(self, 'message') and self.message is not None:
            _dict['message'] = self.message
        if hasattr(self, 'more_info') and self.more_info is not None:
            _dict['more_info'] = self.more_info
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this ImageExportJobStatusReason object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ImageExportJobStatusReason') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ImageExportJobStatusReason') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class CodeEnum(str, Enum):
        """
        A snake case string succinctly identifying the status reason.
        """

        CANNOT_ACCESS_STORAGE_BUCKET = 'cannot_access_storage_bucket'
        INTERNAL_ERROR = 'internal_error'



class ImageExportJobUnpaginatedCollection:
    """
    ImageExportJobUnpaginatedCollection.

    :attr List[ImageExportJob] export_jobs: Collection of image export jobs.
    """

    def __init__(
        self,
        export_jobs: List['ImageExportJob'],
    ) -> None:
        """
        Initialize a ImageExportJobUnpaginatedCollection object.

        :param List[ImageExportJob] export_jobs: Collection of image export jobs.
        """
        self.export_jobs = export_jobs

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ImageExportJobUnpaginatedCollection':
        """Initialize a ImageExportJobUnpaginatedCollection object from a json dictionary."""
        args = {}
        if 'export_jobs' in _dict:
            args['export_jobs'] = [ImageExportJob.from_dict(v) for v in _dict.get('export_jobs')]
        else:
            raise ValueError('Required property \'export_jobs\' not present in ImageExportJobUnpaginatedCollection JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ImageExportJobUnpaginatedCollection object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'export_jobs') and self.export_jobs is not None:
            export_jobs_list = []
            for v in self.export_jobs:
                if isinstance(v, dict):
                    export_jobs_list.append(v)
                else:
                    export_jobs_list.append(v.to_dict())
            _dict['export_jobs'] = export_jobs_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 ImageExportJobUnpaginatedCollection object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ImageExportJobUnpaginatedCollection') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ImageExportJobUnpaginatedCollection') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class ImageFile:
    """
    ImageFile.

    :attr ImageFileChecksums checksums: (optional) Checksums for this image file.
          This property may be absent if the associated image has a `status` of `pending`
          or
          `failed`.
    :attr int size: (optional) The size of the stored image file rounded up to the
          next gigabyte.
          This property may be absent if the associated image has a `status` of `pending`
          or
          `failed`.
    """

    def __init__(
        self,
        *,
        checksums: 'ImageFileChecksums' = None,
        size: int = None,
    ) -> None:
        """
        Initialize a ImageFile object.

        :param ImageFileChecksums checksums: (optional) Checksums for this image
               file.
               This property may be absent if the associated image has a `status` of
               `pending` or
               `failed`.
        :param int size: (optional) The size of the stored image file rounded up to
               the next gigabyte.
               This property may be absent if the associated image has a `status` of
               `pending` or
               `failed`.
        """
        self.checksums = checksums
        self.size = size

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ImageFile':
        """Initialize a ImageFile object from a json dictionary."""
        args = {}
        if 'checksums' in _dict:
            args['checksums'] = ImageFileChecksums.from_dict(_dict.get('checksums'))
        if 'size' in _dict:
            args['size'] = _dict.get('size')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ImageFile object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'checksums') and self.checksums is not None:
            if isinstance(self.checksums, dict):
                _dict['checksums'] = self.checksums
            else:
                _dict['checksums'] = self.checksums.to_dict()
        if hasattr(self, 'size') and self.size is not None:
            _dict['size'] = self.size
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this ImageFile object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ImageFile') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ImageFile') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class ImageFileChecksums:
    """
    ImageFileChecksums.

    :attr str sha256: (optional) The SHA256 fingerprint of the image file.
    """

    def __init__(
        self,
        *,
        sha256: str = None,
    ) -> None:
        """
        Initialize a ImageFileChecksums object.

        :param str sha256: (optional) The SHA256 fingerprint of the image file.
        """
        self.sha256 = sha256

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ImageFileChecksums':
        """Initialize a ImageFileChecksums object from a json dictionary."""
        args = {}
        if 'sha256' in _dict:
            args['sha256'] = _dict.get('sha256')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ImageFileChecksums object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'sha256') and self.sha256 is not None:
            _dict['sha256'] = self.sha256
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this ImageFileChecksums object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ImageFileChecksums') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ImageFileChecksums') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class ImageFilePrototype:
    """
    ImageFilePrototype.

    :attr str href: The Cloud Object Storage location of the image file.
          The image file format is specified by the file's extension, which must be either
          `qcow2` or `vhd`.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a ImageFilePrototype object.

        :param str href: The Cloud Object Storage location of the image file.
               The image file format is specified by the file's extension, which must be
               either
               `qcow2` or `vhd`.
        """
        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 datetime deprecation_at: (optional) The deprecation date and time to set
          for this image.
          This cannot be set if the image has a `status` of `failed` or `deleting`, or if
          `catalog_offering.managed` is `true`.
          The date and time must not be in the past, and must be earlier than
          `obsolescence_at`
          (if `obsolescence_at` is set). Additionally, if the image status is currently
          `deprecated`, the value cannot be changed (but may be removed).
          Specify `null` to remove an existing deprecation date and time. If the image
          status is currently `deprecated`, it will become `available`.
          If the deprecation date and time is reached while the image has a status of
          `pending`, the image's status will transition to `deprecated` upon its
          successful creation (or
          `obsolete` if the obsolescence date and time was also reached).
    :attr str name: (optional) The name for this image. The name must not be used by
          another image in the region. Names starting with `ibm-` are reserved for
          system-provided images, and are not allowed.
    :attr datetime obsolescence_at: (optional) The obsolescence date and time to set
          for this image.
          This cannot be set if the image has a `status` of `failed` or `deleting`, or if
          `catalog_offering.managed` is `true`.
          The date and time must not be in the past, and must be later than
          `deprecation_at` (if
          `deprecation_at` is set). Additionally, if the image status is currently
          `obsolete`, the value cannot be changed (but may be removed).
          Specify `null` to remove an existing obsolescence date and time. If the image
          status is currently `obsolete`, it will become `deprecated` if `deprecation_at`
          is in the past. Otherwise, it will become `available`.
          If the obsolescence date and time is reached while the image has a status of
          `pending`, the image's status will transition to `obsolete` upon its successful
          creation.
    """

    def __init__(
        self,
        *,
        deprecation_at: datetime = None,
        name: str = None,
        obsolescence_at: datetime = None,
    ) -> None:
        """
        Initialize a ImagePatch object.

        :param datetime deprecation_at: (optional) The deprecation date and time to
               set for this image.
               This cannot be set if the image has a `status` of `failed` or `deleting`,
               or if
               `catalog_offering.managed` is `true`.
               The date and time must not be in the past, and must be earlier than
               `obsolescence_at`
               (if `obsolescence_at` is set). Additionally, if the image status is
               currently
               `deprecated`, the value cannot be changed (but may be removed).
               Specify `null` to remove an existing deprecation date and time. If the
               image status is currently `deprecated`, it will become `available`.
               If the deprecation date and time is reached while the image has a status of
               `pending`, the image's status will transition to `deprecated` upon its
               successful creation (or
               `obsolete` if the obsolescence date and time was also reached).
        :param str name: (optional) The name for this image. The name must not be
               used by another image in the region. Names starting with `ibm-` are
               reserved for system-provided images, and are not allowed.
        :param datetime obsolescence_at: (optional) The obsolescence date and time
               to set for this image.
               This cannot be set if the image has a `status` of `failed` or `deleting`,
               or if
               `catalog_offering.managed` is `true`.
               The date and time must not be in the past, and must be later than
               `deprecation_at` (if
               `deprecation_at` is set). Additionally, if the image status is currently
               `obsolete`, the value cannot be changed (but may be removed).
               Specify `null` to remove an existing obsolescence date and time. If the
               image status is currently `obsolete`, it will become `deprecated` if
               `deprecation_at` is in the past. Otherwise, it will become `available`.
               If the obsolescence date and time is reached while the image has a status
               of `pending`, the image's status will transition to `obsolete` upon its
               successful creation.
        """
        self.deprecation_at = deprecation_at
        self.name = name
        self.obsolescence_at = obsolescence_at

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ImagePatch':
        """Initialize a ImagePatch object from a json dictionary."""
        args = {}
        if 'deprecation_at' in _dict:
            args['deprecation_at'] = string_to_datetime(_dict.get('deprecation_at'))
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        if 'obsolescence_at' in _dict:
            args['obsolescence_at'] = string_to_datetime(_dict.get('obsolescence_at'))
        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, 'deprecation_at') and self.deprecation_at is not None:
            _dict['deprecation_at'] = datetime_to_string(self.deprecation_at)
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'obsolescence_at') and self.obsolescence_at is not None:
            _dict['obsolescence_at'] = datetime_to_string(self.obsolescence_at)
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this 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 datetime deprecation_at: (optional) The deprecation date and time to set
          for this image.
          The date and time must not be in the past, and must be earlier than
          `obsolescence_at`
          (if `obsolescence_at` is set).
          If unspecified, no deprecation date and time will be set.
          If the deprecation date and time is reached while the image has a status of
          `pending`, the image's status will transition to `deprecated` upon its
          successful creation (or
          `obsolete` if the obsolescence date and time was also reached).
    :attr str name: (optional) The name for this image. The name must not be used by
          another image in the region. Names starting with `ibm-` are reserved for
          system-provided images, and are not allowed. If unspecified, the name will be a
          hyphenated list of randomly-selected words.
    :attr datetime obsolescence_at: (optional) The obsolescence date and time to set
          for this image.
          The date and time must not be in the past, and must be later than
          `deprecation_at` (if
          `deprecation_at` is set).
          If unspecified, no obsolescence date and time will be set.
          If the obsolescence date and time is reached while the image has a status of
          `pending`, the image's status will transition to `obsolete` upon its successful
          creation.
    :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) will be
          used.
    """

    def __init__(
        self,
        *,
        deprecation_at: datetime = None,
        name: str = None,
        obsolescence_at: datetime = None,
        resource_group: 'ResourceGroupIdentity' = None,
    ) -> None:
        """
        Initialize a ImagePrototype object.

        :param datetime deprecation_at: (optional) The deprecation date and time to
               set for this image.
               The date and time must not be in the past, and must be earlier than
               `obsolescence_at`
               (if `obsolescence_at` is set).
               If unspecified, no deprecation date and time will be set.
               If the deprecation date and time is reached while the image has a status of
               `pending`, the image's status will transition to `deprecated` upon its
               successful creation (or
               `obsolete` if the obsolescence date and time was also reached).
        :param str name: (optional) The name for this image. The name must not be
               used by another image in the region. Names starting with `ibm-` are
               reserved for system-provided images, and are not allowed. If unspecified,
               the name will be a hyphenated list of randomly-selected words.
        :param datetime obsolescence_at: (optional) The obsolescence date and time
               to set for this image.
               The date and time must not be in the past, and must be later than
               `deprecation_at` (if
               `deprecation_at` is set).
               If unspecified, no obsolescence date and time will be set.
               If the obsolescence date and time is reached while the image has a status
               of
               `pending`, the image's status will transition to `obsolete` upon its
               successful creation.
        :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) will be
               used.
        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['ImagePrototypeImageByFile', 'ImagePrototypeImageBySourceVolume'])
        )
        raise Exception(msg)


class ImageReference:
    """
    ImageReference.

    :attr str crn: The CRN for this image.
    :attr ImageReferenceDeleted deleted: (optional) If present, this property
          indicates the referenced resource has been deleted, and provides
          some supplementary information.
    :attr str href: The URL for this image.
    :attr str id: The unique identifier for this image.
    :attr str name: The name for this image. The name is unique across all images in
          the region.
    :attr ImageRemote remote: (optional) If present, this property indicates that
          the resource associated with this reference
          is remote and therefore may not be directly retrievable.
    :attr str resource_type: The resource type.
    """

    def __init__(
        self,
        crn: str,
        href: str,
        id: str,
        name: str,
        resource_type: str,
        *,
        deleted: 'ImageReferenceDeleted' = None,
        remote: 'ImageRemote' = None,
    ) -> None:
        """
        Initialize a ImageReference object.

        :param str crn: The CRN for this image.
        :param str href: The URL for this image.
        :param str id: The unique identifier for this image.
        :param str name: The name for this image. The name is unique across all
               images in the region.
        :param str resource_type: The resource type.
        :param ImageReferenceDeleted deleted: (optional) If present, this property
               indicates the referenced resource has been deleted, and provides
               some supplementary information.
        :param ImageRemote remote: (optional) If present, this property indicates
               that the resource associated with this reference
               is remote and therefore may not be directly retrievable.
        """
        self.crn = crn
        self.deleted = deleted
        self.href = href
        self.id = id
        self.name = name
        self.remote = remote
        self.resource_type = resource_type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ImageReference':
        """Initialize a ImageReference object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError('Required property \'crn\' not present in ImageReference JSON')
        if 'deleted' in _dict:
            args['deleted'] = ImageReferenceDeleted.from_dict(_dict.get('deleted'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in ImageReference JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in ImageReference JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in ImageReference JSON')
        if 'remote' in _dict:
            args['remote'] = ImageRemote.from_dict(_dict.get('remote'))
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError('Required property \'resource_type\' not present in ImageReference JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ImageReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'deleted') and self.deleted is not None:
            if isinstance(self.deleted, dict):
                _dict['deleted'] = self.deleted
            else:
                _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, '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, '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 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 ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        IMAGE = 'image'



class ImageReferenceDeleted:
    """
    If present, this property indicates the referenced resource has been deleted, and
    provides some supplementary information.

    :attr str more_info: Link to documentation about deleted resources.
    """

    def __init__(
        self,
        more_info: str,
    ) -> None:
        """
        Initialize a ImageReferenceDeleted object.

        :param str more_info: Link to documentation about deleted resources.
        """
        self.more_info = more_info

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ImageReferenceDeleted':
        """Initialize a ImageReferenceDeleted object from a json dictionary."""
        args = {}
        if 'more_info' in _dict:
            args['more_info'] = _dict.get('more_info')
        else:
            raise ValueError('Required property \'more_info\' not present in ImageReferenceDeleted JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ImageReferenceDeleted object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'more_info') and self.more_info is not None:
            _dict['more_info'] = self.more_info
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this ImageReferenceDeleted object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ImageReferenceDeleted') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ImageReferenceDeleted') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class ImageRemote:
    """
    If present, this property indicates that the resource associated with this reference
    is remote and therefore may not be directly retrievable.

    :attr AccountReference account: (optional) If present, this property indicates
          that the referenced resource is remote to this
          account, and identifies the owning account.
    :attr RegionReference region: (optional) If present, this property indicates
          that the referenced resource is remote to this
          region, and identifies the native region.
    """

    def __init__(
        self,
        *,
        account: 'AccountReference' = None,
        region: 'RegionReference' = None,
    ) -> None:
        """
        Initialize a ImageRemote object.

        :param AccountReference account: (optional) If present, this property
               indicates that the referenced resource is remote to this
               account, and identifies the owning account.
        :param RegionReference region: (optional) If present, this property
               indicates that the referenced resource is remote to this
               region, and identifies the native region.
        """
        self.account = account
        self.region = region

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ImageRemote':
        """Initialize a ImageRemote object from a json dictionary."""
        args = {}
        if 'account' in _dict:
            args['account'] = AccountReference.from_dict(_dict.get('account'))
        if 'region' in _dict:
            args['region'] = RegionReference.from_dict(_dict.get('region'))
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ImageRemote object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'account') and self.account is not None:
            if isinstance(self.account, dict):
                _dict['account'] = self.account
            else:
                _dict['account'] = self.account.to_dict()
        if hasattr(self, 'region') and self.region is not None:
            if isinstance(self.region, dict):
                _dict['region'] = self.region
            else:
                _dict['region'] = self.region.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 ImageRemote object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ImageRemote') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ImageRemote') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class ImageStatusReason:
    """
    ImageStatusReason.

    :attr str code: A snake case string succinctly identifying the status reason.
    :attr str message: An explanation of the status reason.
    :attr str more_info: (optional) Link to documentation about this status reason.
    """

    def __init__(
        self,
        code: str,
        message: str,
        *,
        more_info: str = None,
    ) -> None:
        """
        Initialize a ImageStatusReason object.

        :param str code: A snake case string succinctly identifying the status
               reason.
        :param str message: An explanation of the status reason.
        :param str more_info: (optional) Link to documentation about this status
               reason.
        """
        self.code = code
        self.message = message
        self.more_info = more_info

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ImageStatusReason':
        """Initialize a ImageStatusReason object from a json dictionary."""
        args = {}
        if 'code' in _dict:
            args['code'] = _dict.get('code')
        else:
            raise ValueError('Required property \'code\' not present in ImageStatusReason JSON')
        if 'message' in _dict:
            args['message'] = _dict.get('message')
        else:
            raise ValueError('Required property \'message\' not present in ImageStatusReason JSON')
        if 'more_info' in _dict:
            args['more_info'] = _dict.get('more_info')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ImageStatusReason object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'code') and self.code is not None:
            _dict['code'] = self.code
        if hasattr(self, 'message') and self.message is not None:
            _dict['message'] = self.message
        if hasattr(self, 'more_info') and self.more_info is not None:
            _dict['more_info'] = self.more_info
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this ImageStatusReason object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ImageStatusReason') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ImageStatusReason') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class CodeEnum(str, Enum):
        """
        A snake case string succinctly identifying the status reason.
        """

        ENCRYPTED_DATA_KEY_INVALID = 'encrypted_data_key_invalid'
        ENCRYPTION_KEY_DELETED = 'encryption_key_deleted'
        ENCRYPTION_KEY_DISABLED = 'encryption_key_disabled'
        IMAGE_DATA_CORRUPTED = 'image_data_corrupted'
        IMAGE_PROVISIONED_SIZE_UNSUPPORTED = 'image_provisioned_size_unsupported'
        IMAGE_REQUEST_IN_PROGRESS = 'image_request_in_progress'
        IMAGE_REQUEST_QUEUED = 'image_request_queued'



class Instance:
    """
    Instance.

    :attr InstanceAvailabilityPolicy availability_policy: The availability policy
          for this virtual server instance.
    :attr int bandwidth: The total bandwidth (in megabits per second) shared across
          the instance network interfaces and storage volumes of virtual server instance.
    :attr VolumeAttachmentReferenceInstanceContext boot_volume_attachment: Boot
          volume attachment.
    :attr InstanceCatalogOffering catalog_offering: (optional) If present, this
          virtual server instance was provisioned from a
          [catalog](https://cloud.ibm.com/docs/account?topic=account-restrict-by-user).
    :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 DedicatedHostReference dedicated_host: (optional) If present, the
          dedicated host this virtual server instance has been placed on.
    :attr List[InstanceDisk] disks: The instance disks for this virtual server
          instance.
    :attr InstanceGPU gpu: (optional) The virtual server instance GPU configuration.
    :attr str href: The URL for this virtual server instance.
    :attr str id: The unique identifier for this virtual server instance.
    :attr ImageReference image: (optional) The image the virtual server instance was
          provisioned from.
    :attr List[InstanceLifecycleReason] lifecycle_reasons: The reasons for the
          current `lifecycle_state` (if any).
          The enumerated reason code values for this property will expand in the future.
          When processing this property, check for and log unknown values. Optionally halt
          processing and surface the error, or bypass the resource on which the unexpected
          reason code was encountered.
    :attr str lifecycle_state: The lifecycle state of the virtual server instance.
    :attr int memory: The amount of memory, truncated to whole gibibytes.
    :attr InstanceMetadataService metadata_service: The metadata service
          configuration.
    :attr str name: The name for this virtual server instance. The name is unique
          across all virtual server instances in the region.
    :attr List[NetworkInterfaceInstanceContextReference] network_interfaces: The
          network interfaces for this instance, including the primary network interface.
    :attr int numa_count: (optional) The number of NUMA nodes this virtual server
          instance is provisioned on.
          This property will be absent if the instance's `status` is not `running`.
    :attr InstancePlacementTarget placement_target: (optional) The placement
          restrictions for the virtual server instance.
    :attr NetworkInterfaceInstanceContextReference primary_network_interface: The
          primary network interface for this virtual server instance.
    :attr InstanceProfileReference profile: The
          [profile](https://cloud.ibm.com/docs/vpc?topic=vpc-profiles) for this virtual
          server instance.
    :attr ResourceGroupReference resource_group: The resource group for this
          instance.
    :attr str resource_type: The resource type.
    :attr bool startable: Indicates whether the state of the virtual server instance
          permits a start request.
    :attr str status: The status of the virtual server instance.
          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 instance on which the unexpected
          property value was encountered.
    :attr List[InstanceStatusReason] status_reasons: The reasons for the current
          status (if any).
          The enumerated reason code values for this property will expand in the future.
          When processing this property, check for and log unknown values. Optionally halt
          processing and surface the error, or bypass the resource on which the unexpected
          reason code was encountered.
    :attr int total_network_bandwidth: The amount of bandwidth (in megabits per
          second) allocated exclusively to instance network interfaces.
    :attr int total_volume_bandwidth: The amount of bandwidth (in megabits per
          second) allocated exclusively to instance storage volumes. An increase in this
          value will result in a corresponding decrease to
          `total_network_bandwidth`.
    :attr InstanceVCPU vcpu: The virtual server instance VCPU configuration.
    :attr List[VolumeAttachmentReferenceInstanceContext] volume_attachments: The
          volume attachments for this virtual server instance, including the boot volume
          attachment.
    :attr VPCReference vpc: The VPC this virtual server instance resides in.
    :attr ZoneReference zone: The zone this virtual server instance resides in.
    """

    def __init__(
        self,
        availability_policy: 'InstanceAvailabilityPolicy',
        bandwidth: int,
        boot_volume_attachment: 'VolumeAttachmentReferenceInstanceContext',
        created_at: datetime,
        crn: str,
        disks: List['InstanceDisk'],
        href: str,
        id: str,
        lifecycle_reasons: List['InstanceLifecycleReason'],
        lifecycle_state: str,
        memory: int,
        metadata_service: 'InstanceMetadataService',
        name: str,
        network_interfaces: List['NetworkInterfaceInstanceContextReference'],
        primary_network_interface: 'NetworkInterfaceInstanceContextReference',
        profile: 'InstanceProfileReference',
        resource_group: 'ResourceGroupReference',
        resource_type: str,
        startable: bool,
        status: str,
        status_reasons: List['InstanceStatusReason'],
        total_network_bandwidth: int,
        total_volume_bandwidth: int,
        vcpu: 'InstanceVCPU',
        volume_attachments: List['VolumeAttachmentReferenceInstanceContext'],
        vpc: 'VPCReference',
        zone: 'ZoneReference',
        *,
        catalog_offering: 'InstanceCatalogOffering' = None,
        dedicated_host: 'DedicatedHostReference' = None,
        gpu: 'InstanceGPU' = None,
        image: 'ImageReference' = None,
        numa_count: int = None,
        placement_target: 'InstancePlacementTarget' = None,
    ) -> None:
        """
        Initialize a Instance object.

        :param InstanceAvailabilityPolicy availability_policy: The availability
               policy for this virtual server instance.
        :param int bandwidth: The total bandwidth (in megabits per second) shared
               across the instance network interfaces and storage volumes of virtual
               server instance.
        :param VolumeAttachmentReferenceInstanceContext boot_volume_attachment:
               Boot volume attachment.
        :param datetime created_at: The date and time that the virtual server
               instance was created.
        :param str crn: The CRN for this virtual server instance.
        :param List[InstanceDisk] disks: The instance disks 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 List[InstanceLifecycleReason] lifecycle_reasons: The reasons for the
               current `lifecycle_state` (if any).
               The enumerated reason code values for this property will expand in the
               future. When processing this property, check for and log unknown values.
               Optionally halt processing and surface the error, or bypass the resource on
               which the unexpected reason code was encountered.
        :param str lifecycle_state: The lifecycle state of the virtual server
               instance.
        :param int memory: The amount of memory, truncated to whole gibibytes.
        :param InstanceMetadataService metadata_service: The metadata service
               configuration.
        :param str name: The name for this virtual server instance. The name is
               unique across all virtual server instances in the region.
        :param List[NetworkInterfaceInstanceContextReference] network_interfaces:
               The network interfaces for this instance, including the primary network
               interface.
        :param NetworkInterfaceInstanceContextReference primary_network_interface:
               The primary network interface for this virtual server instance.
        :param InstanceProfileReference profile: The
               [profile](https://cloud.ibm.com/docs/vpc?topic=vpc-profiles) for this
               virtual
               server instance.
        :param ResourceGroupReference resource_group: The resource group for this
               instance.
        :param str resource_type: The resource type.
        :param bool startable: Indicates whether the state of the virtual server
               instance permits a start request.
        :param str status: The status of the virtual server instance.
               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 instance on which the
               unexpected property value was encountered.
        :param List[InstanceStatusReason] status_reasons: The reasons for the
               current status (if any).
               The enumerated reason code values for this property will expand in the
               future. When processing this property, check for and log unknown values.
               Optionally halt processing and surface the error, or bypass the resource on
               which the unexpected reason code was encountered.
        :param int total_network_bandwidth: The amount of bandwidth (in megabits
               per second) allocated exclusively to instance network interfaces.
        :param int total_volume_bandwidth: The amount of bandwidth (in megabits per
               second) allocated exclusively to instance storage volumes. An increase in
               this value will result in a corresponding decrease to
               `total_network_bandwidth`.
        :param InstanceVCPU vcpu: The virtual server instance VCPU configuration.
        :param List[VolumeAttachmentReferenceInstanceContext] volume_attachments:
               The volume attachments for this virtual server instance, including the boot
               volume attachment.
        :param VPCReference vpc: The VPC this virtual server instance resides in.
        :param ZoneReference zone: The zone this virtual server instance resides
               in.
        :param InstanceCatalogOffering catalog_offering: (optional) If present,
               this virtual server instance was provisioned from a
               [catalog](https://cloud.ibm.com/docs/account?topic=account-restrict-by-user).
        :param DedicatedHostReference dedicated_host: (optional) If present, the
               dedicated host this virtual server instance has been placed on.
        :param InstanceGPU gpu: (optional) The virtual server instance GPU
               configuration.
        :param ImageReference image: (optional) The image the virtual server
               instance was provisioned from.
        :param int numa_count: (optional) The number of NUMA nodes this virtual
               server instance is provisioned on.
               This property will be absent if the instance's `status` is not `running`.
        :param InstancePlacementTarget placement_target: (optional) The placement
               restrictions for the virtual server instance.
        """
        self.availability_policy = availability_policy
        self.bandwidth = bandwidth
        self.boot_volume_attachment = boot_volume_attachment
        self.catalog_offering = catalog_offering
        self.created_at = created_at
        self.crn = crn
        self.dedicated_host = dedicated_host
        self.disks = disks
        self.gpu = gpu
        self.href = href
        self.id = id
        self.image = image
        self.lifecycle_reasons = lifecycle_reasons
        self.lifecycle_state = lifecycle_state
        self.memory = memory
        self.metadata_service = metadata_service
        self.name = name
        self.network_interfaces = network_interfaces
        self.numa_count = numa_count
        self.placement_target = placement_target
        self.primary_network_interface = primary_network_interface
        self.profile = profile
        self.resource_group = resource_group
        self.resource_type = resource_type
        self.startable = startable
        self.status = status
        self.status_reasons = status_reasons
        self.total_network_bandwidth = total_network_bandwidth
        self.total_volume_bandwidth = total_volume_bandwidth
        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 'availability_policy' in _dict:
            args['availability_policy'] = InstanceAvailabilityPolicy.from_dict(_dict.get('availability_policy'))
        else:
            raise ValueError('Required property \'availability_policy\' not present in Instance JSON')
        if 'bandwidth' in _dict:
            args['bandwidth'] = _dict.get('bandwidth')
        else:
            raise ValueError('Required property \'bandwidth\' not present in Instance JSON')
        if 'boot_volume_attachment' in _dict:
            args['boot_volume_attachment'] = VolumeAttachmentReferenceInstanceContext.from_dict(_dict.get('boot_volume_attachment'))
        else:
            raise ValueError('Required property \'boot_volume_attachment\' not present in Instance JSON')
        if 'catalog_offering' in _dict:
            args['catalog_offering'] = InstanceCatalogOffering.from_dict(_dict.get('catalog_offering'))
        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 'dedicated_host' in _dict:
            args['dedicated_host'] = DedicatedHostReference.from_dict(_dict.get('dedicated_host'))
        if 'disks' in _dict:
            args['disks'] = [InstanceDisk.from_dict(v) for v in _dict.get('disks')]
        else:
            raise ValueError('Required property \'disks\' not present in Instance JSON')
        if 'gpu' in _dict:
            args['gpu'] = InstanceGPU.from_dict(_dict.get('gpu'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in Instance JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in Instance JSON')
        if 'image' in _dict:
            args['image'] = ImageReference.from_dict(_dict.get('image'))
        if 'lifecycle_reasons' in _dict:
            args['lifecycle_reasons'] = [InstanceLifecycleReason.from_dict(v) for v in _dict.get('lifecycle_reasons')]
        else:
            raise ValueError('Required property \'lifecycle_reasons\' not present in Instance JSON')
        if 'lifecycle_state' in _dict:
            args['lifecycle_state'] = _dict.get('lifecycle_state')
        else:
            raise ValueError('Required property \'lifecycle_state\' not present in Instance JSON')
        if 'memory' in _dict:
            args['memory'] = _dict.get('memory')
        else:
            raise ValueError('Required property \'memory\' not present in Instance JSON')
        if 'metadata_service' in _dict:
            args['metadata_service'] = InstanceMetadataService.from_dict(_dict.get('metadata_service'))
        else:
            raise ValueError('Required property \'metadata_service\' 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(v) for v in _dict.get('network_interfaces')]
        else:
            raise ValueError('Required property \'network_interfaces\' not present in Instance JSON')
        if 'numa_count' in _dict:
            args['numa_count'] = _dict.get('numa_count')
        if 'placement_target' in _dict:
            args['placement_target'] = _dict.get('placement_target')
        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 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError('Required property \'resource_type\' not present in Instance JSON')
        if 'startable' in _dict:
            args['startable'] = _dict.get('startable')
        else:
            raise ValueError('Required property \'startable\' not present in Instance JSON')
        if 'status' in _dict:
            args['status'] = _dict.get('status')
        else:
            raise ValueError('Required property \'status\' not present in Instance JSON')
        if 'status_reasons' in _dict:
            args['status_reasons'] = [InstanceStatusReason.from_dict(v) for v in _dict.get('status_reasons')]
        else:
            raise ValueError('Required property \'status_reasons\' not present in Instance JSON')
        if 'total_network_bandwidth' in _dict:
            args['total_network_bandwidth'] = _dict.get('total_network_bandwidth')
        else:
            raise ValueError('Required property \'total_network_bandwidth\' not present in Instance JSON')
        if 'total_volume_bandwidth' in _dict:
            args['total_volume_bandwidth'] = _dict.get('total_volume_bandwidth')
        else:
            raise ValueError('Required property \'total_volume_bandwidth\' 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(v) for v 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, 'availability_policy') and self.availability_policy is not None:
            if isinstance(self.availability_policy, dict):
                _dict['availability_policy'] = self.availability_policy
            else:
                _dict['availability_policy'] = self.availability_policy.to_dict()
        if hasattr(self, 'bandwidth') and self.bandwidth is not None:
            _dict['bandwidth'] = self.bandwidth
        if hasattr(self, 'boot_volume_attachment') and self.boot_volume_attachment is not None:
            if isinstance(self.boot_volume_attachment, dict):
                _dict['boot_volume_attachment'] = self.boot_volume_attachment
            else:
                _dict['boot_volume_attachment'] = self.boot_volume_attachment.to_dict()
        if hasattr(self, 'catalog_offering') and self.catalog_offering is not None:
            if isinstance(self.catalog_offering, dict):
                _dict['catalog_offering'] = self.catalog_offering
            else:
                _dict['catalog_offering'] = self.catalog_offering.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, 'dedicated_host') and self.dedicated_host is not None:
            if isinstance(self.dedicated_host, dict):
                _dict['dedicated_host'] = self.dedicated_host
            else:
                _dict['dedicated_host'] = self.dedicated_host.to_dict()
        if hasattr(self, 'disks') and self.disks is not None:
            disks_list = []
            for v in self.disks:
                if isinstance(v, dict):
                    disks_list.append(v)
                else:
                    disks_list.append(v.to_dict())
            _dict['disks'] = disks_list
        if hasattr(self, 'gpu') and self.gpu is not None:
            if isinstance(self.gpu, dict):
                _dict['gpu'] = self.gpu
            else:
                _dict['gpu'] = self.gpu.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'image') and self.image is not None:
            if isinstance(self.image, dict):
                _dict['image'] = self.image
            else:
                _dict['image'] = self.image.to_dict()
        if hasattr(self, 'lifecycle_reasons') and self.lifecycle_reasons is not None:
            lifecycle_reasons_list = []
            for v in self.lifecycle_reasons:
                if isinstance(v, dict):
                    lifecycle_reasons_list.append(v)
                else:
                    lifecycle_reasons_list.append(v.to_dict())
            _dict['lifecycle_reasons'] = lifecycle_reasons_list
        if hasattr(self, 'lifecycle_state') and self.lifecycle_state is not None:
            _dict['lifecycle_state'] = self.lifecycle_state
        if hasattr(self, 'memory') and self.memory is not None:
            _dict['memory'] = self.memory
        if hasattr(self, 'metadata_service') and self.metadata_service is not None:
            if isinstance(self.metadata_service, dict):
                _dict['metadata_service'] = self.metadata_service
            else:
                _dict['metadata_service'] = self.metadata_service.to_dict()
        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:
            network_interfaces_list = []
            for v in self.network_interfaces:
                if isinstance(v, dict):
                    network_interfaces_list.append(v)
                else:
                    network_interfaces_list.append(v.to_dict())
            _dict['network_interfaces'] = network_interfaces_list
        if hasattr(self, 'numa_count') and self.numa_count is not None:
            _dict['numa_count'] = self.numa_count
        if hasattr(self, 'placement_target') and self.placement_target is not None:
            if isinstance(self.placement_target, dict):
                _dict['placement_target'] = self.placement_target
            else:
                _dict['placement_target'] = self.placement_target.to_dict()
        if hasattr(self, 'primary_network_interface') and self.primary_network_interface is not None:
            if isinstance(self.primary_network_interface, dict):
                _dict['primary_network_interface'] = self.primary_network_interface
            else:
                _dict['primary_network_interface'] = self.primary_network_interface.to_dict()
        if hasattr(self, 'profile') and self.profile is not None:
            if isinstance(self.profile, dict):
                _dict['profile'] = self.profile
            else:
                _dict['profile'] = self.profile.to_dict()
        if hasattr(self, 'resource_group') and self.resource_group is not None:
            if isinstance(self.resource_group, dict):
                _dict['resource_group'] = self.resource_group
            else:
                _dict['resource_group'] = self.resource_group.to_dict()
        if hasattr(self, 'resource_type') and self.resource_type is not None:
            _dict['resource_type'] = self.resource_type
        if hasattr(self, 'startable') and self.startable is not None:
            _dict['startable'] = self.startable
        if hasattr(self, 'status') and self.status is not None:
            _dict['status'] = self.status
        if hasattr(self, 'status_reasons') and self.status_reasons is not None:
            status_reasons_list = []
            for v in self.status_reasons:
                if isinstance(v, dict):
                    status_reasons_list.append(v)
                else:
                    status_reasons_list.append(v.to_dict())
            _dict['status_reasons'] = status_reasons_list
        if hasattr(self, 'total_network_bandwidth') and self.total_network_bandwidth is not None:
            _dict['total_network_bandwidth'] = self.total_network_bandwidth
        if hasattr(self, 'total_volume_bandwidth') and self.total_volume_bandwidth is not None:
            _dict['total_volume_bandwidth'] = self.total_volume_bandwidth
        if hasattr(self, 'vcpu') and self.vcpu is not None:
            if isinstance(self.vcpu, dict):
                _dict['vcpu'] = self.vcpu
            else:
                _dict['vcpu'] = self.vcpu.to_dict()
        if hasattr(self, 'volume_attachments') and self.volume_attachments is not None:
            volume_attachments_list = []
            for v in self.volume_attachments:
                if isinstance(v, dict):
                    volume_attachments_list.append(v)
                else:
                    volume_attachments_list.append(v.to_dict())
            _dict['volume_attachments'] = volume_attachments_list
        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, '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 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 LifecycleStateEnum(str, Enum):
        """
        The lifecycle state of the virtual server instance.
        """

        DELETING = 'deleting'
        FAILED = 'failed'
        PENDING = 'pending'
        STABLE = 'stable'
        SUSPENDED = 'suspended'
        UPDATING = 'updating'
        WAITING = 'waiting'


    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        INSTANCE = 'instance'


    class StatusEnum(str, Enum):
        """
        The status of the virtual server instance.
        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 instance on which the unexpected property value
        was encountered.
        """

        DELETING = 'deleting'
        FAILED = 'failed'
        PENDING = 'pending'
        RESTARTING = 'restarting'
        RUNNING = 'running'
        STARTING = 'starting'
        STOPPED = 'stopped'
        STOPPING = 'stopping'



class InstanceAction:
    """
    InstanceAction.

    :attr datetime completed_at: (optional) Deprecated: The date and time that the
          action was completed.
    :attr datetime created_at: The date and time that the action was created.
    :attr bool force: (optional) If set to true, the action will be forced
          immediately, and all queued actions deleted. Ignored for the start action.
    :attr str href: Deprecated: The URL for this instance action.
    :attr str id: Deprecated: The identifier for this instance action.
    :attr datetime started_at: (optional) Deprecated: The date and time that the
          action was started.
    :attr str status: Deprecated: The current status of this action.
    :attr str type: The type of action.
    """

    def __init__(
        self,
        created_at: datetime,
        href: str,
        id: str,
        status: str,
        type: str,
        *,
        completed_at: datetime = None,
        force: bool = None,
        started_at: datetime = None,
    ) -> None:
        """
        Initialize a InstanceAction object.

        :param datetime created_at: The date and time that the action was created.
        :param str href: Deprecated: The URL for this instance action.
        :param str id: Deprecated: The identifier for this instance action.
        :param str status: Deprecated: The current status of this action.
        :param str type: The type of action.
        :param datetime completed_at: (optional) Deprecated: The date and time that
               the action was completed.
        :param bool force: (optional) If set to true, the action will be forced
               immediately, and all queued actions deleted. Ignored for the start action.
        :param datetime started_at: (optional) Deprecated: The date and time that
               the action was started.
        """
        self.completed_at = completed_at
        self.created_at = created_at
        self.force = force
        self.href = href
        self.id = id
        self.started_at = started_at
        self.status = status
        self.type = type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceAction':
        """Initialize a InstanceAction object from a json dictionary."""
        args = {}
        if 'completed_at' in _dict:
            args['completed_at'] = string_to_datetime(_dict.get('completed_at'))
        if 'created_at' in _dict:
            args['created_at'] = string_to_datetime(_dict.get('created_at'))
        else:
            raise ValueError('Required property \'created_at\' not present in InstanceAction JSON')
        if 'force' in _dict:
            args['force'] = _dict.get('force')
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in InstanceAction JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in InstanceAction JSON')
        if 'started_at' in _dict:
            args['started_at'] = string_to_datetime(_dict.get('started_at'))
        if 'status' in _dict:
            args['status'] = _dict.get('status')
        else:
            raise ValueError('Required property \'status\' not present in InstanceAction JSON')
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in InstanceAction JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceAction object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'completed_at') and self.completed_at is not None:
            _dict['completed_at'] = datetime_to_string(self.completed_at)
        if hasattr(self, 'created_at') and self.created_at is not None:
            _dict['created_at'] = datetime_to_string(self.created_at)
        if hasattr(self, 'force') and self.force is not None:
            _dict['force'] = self.force
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'started_at') and self.started_at is not None:
            _dict['started_at'] = datetime_to_string(self.started_at)
        if hasattr(self, 'status') and self.status is not None:
            _dict['status'] = self.status
        if hasattr(self, 'type') and self.type is not None:
            _dict['type'] = self.type
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceAction object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceAction') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceAction') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class StatusEnum(str, Enum):
        """
        The current status of this action.
        """

        COMPLETED = 'completed'
        FAILED = 'failed'
        PENDING = 'pending'
        RUNNING = 'running'


    class TypeEnum(str, Enum):
        """
        The type of action.
        """

        REBOOT = 'reboot'
        START = 'start'
        STOP = 'stop'



class InstanceAvailabilityPolicy:
    """
    InstanceAvailabilityPolicy.

    :attr str host_failure: The action to perform if the compute host experiences a
          failure.
          - `restart`: Automatically restart the virtual server instance after host
          failure
          - `stop`: Leave the virtual server instance stopped after host failure
          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 instance on which the unexpected
          property value was encountered.
    """

    def __init__(
        self,
        host_failure: str,
    ) -> None:
        """
        Initialize a InstanceAvailabilityPolicy object.

        :param str host_failure: The action to perform if the compute host
               experiences a failure.
               - `restart`: Automatically restart the virtual server instance after host
               failure
               - `stop`: Leave the virtual server instance stopped after host failure
               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 instance on
               which the unexpected property value was encountered.
        """
        self.host_failure = host_failure

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceAvailabilityPolicy':
        """Initialize a InstanceAvailabilityPolicy object from a json dictionary."""
        args = {}
        if 'host_failure' in _dict:
            args['host_failure'] = _dict.get('host_failure')
        else:
            raise ValueError('Required property \'host_failure\' not present in InstanceAvailabilityPolicy JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceAvailabilityPolicy object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'host_failure') and self.host_failure is not None:
            _dict['host_failure'] = self.host_failure
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceAvailabilityPolicy object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceAvailabilityPolicy') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceAvailabilityPolicy') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class HostFailureEnum(str, Enum):
        """
        The action to perform if the compute host experiences a failure.
        - `restart`: Automatically restart the virtual server instance after host failure
        - `stop`: Leave the virtual server instance stopped after host failure
        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 instance on which the unexpected
        property value was encountered.
        """

        RESTART = 'restart'
        STOP = 'stop'



class InstanceAvailabilityPolicyPatch:
    """
    InstanceAvailabilityPolicyPatch.

    :attr str host_failure: (optional) The action to perform if the compute host
          experiences a failure.
          - `restart`: Automatically restart the virtual server instance after host
          failure
          - `stop`: Leave the virtual server instance stopped after host failure.
    """

    def __init__(
        self,
        *,
        host_failure: str = None,
    ) -> None:
        """
        Initialize a InstanceAvailabilityPolicyPatch object.

        :param str host_failure: (optional) The action to perform if the compute
               host experiences a failure.
               - `restart`: Automatically restart the virtual server instance after host
               failure
               - `stop`: Leave the virtual server instance stopped after host failure.
        """
        self.host_failure = host_failure

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceAvailabilityPolicyPatch':
        """Initialize a InstanceAvailabilityPolicyPatch object from a json dictionary."""
        args = {}
        if 'host_failure' in _dict:
            args['host_failure'] = _dict.get('host_failure')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceAvailabilityPolicyPatch object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'host_failure') and self.host_failure is not None:
            _dict['host_failure'] = self.host_failure
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceAvailabilityPolicyPatch object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceAvailabilityPolicyPatch') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceAvailabilityPolicyPatch') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class HostFailureEnum(str, Enum):
        """
        The action to perform if the compute host experiences a failure.
        - `restart`: Automatically restart the virtual server instance after host failure
        - `stop`: Leave the virtual server instance stopped after host failure.
        """

        RESTART = 'restart'
        STOP = 'stop'



class InstanceAvailabilityPolicyPrototype:
    """
    InstanceAvailabilityPolicyPrototype.

    :attr str host_failure: (optional) The action to perform if the compute host
          experiences a failure.
          - `restart`: Automatically restart the virtual server instance after host
          failure
          - `stop`: Leave the virtual server instance stopped after host failure.
    """

    def __init__(
        self,
        *,
        host_failure: str = None,
    ) -> None:
        """
        Initialize a InstanceAvailabilityPolicyPrototype object.

        :param str host_failure: (optional) The action to perform if the compute
               host experiences a failure.
               - `restart`: Automatically restart the virtual server instance after host
               failure
               - `stop`: Leave the virtual server instance stopped after host failure.
        """
        self.host_failure = host_failure

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceAvailabilityPolicyPrototype':
        """Initialize a InstanceAvailabilityPolicyPrototype object from a json dictionary."""
        args = {}
        if 'host_failure' in _dict:
            args['host_failure'] = _dict.get('host_failure')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceAvailabilityPolicyPrototype object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'host_failure') and self.host_failure is not None:
            _dict['host_failure'] = self.host_failure
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceAvailabilityPolicyPrototype object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceAvailabilityPolicyPrototype') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceAvailabilityPolicyPrototype') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class HostFailureEnum(str, Enum):
        """
        The action to perform if the compute host experiences a failure.
        - `restart`: Automatically restart the virtual server instance after host failure
        - `stop`: Leave the virtual server instance stopped after host failure.
        """

        RESTART = 'restart'
        STOP = 'stop'



class InstanceCatalogOffering:
    """
    InstanceCatalogOffering.

    :attr CatalogOfferingVersionReference version: The catalog offering version this
          virtual server instance was provisioned from.
          The catalog offering version is not managed by the IBM VPC service, and may no
          longer
          exist, or may refer to a different image CRN than the `image.crn` for this
          virtual
          server instance. However, all images associated with a catalog offering version
          will
          have the same checksum, and therefore will have the same data.
    """

    def __init__(
        self,
        version: 'CatalogOfferingVersionReference',
    ) -> None:
        """
        Initialize a InstanceCatalogOffering object.

        :param CatalogOfferingVersionReference version: The catalog offering
               version this virtual server instance was provisioned from.
               The catalog offering version is not managed by the IBM VPC service, and may
               no longer
               exist, or may refer to a different image CRN than the `image.crn` for this
               virtual
               server instance. However, all images associated with a catalog offering
               version will
               have the same checksum, and therefore will have the same data.
        """
        self.version = version

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceCatalogOffering':
        """Initialize a InstanceCatalogOffering object from a json dictionary."""
        args = {}
        if 'version' in _dict:
            args['version'] = CatalogOfferingVersionReference.from_dict(_dict.get('version'))
        else:
            raise ValueError('Required property \'version\' not present in InstanceCatalogOffering JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceCatalogOffering object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'version') and self.version is not None:
            if isinstance(self.version, dict):
                _dict['version'] = self.version
            else:
                _dict['version'] = self.version.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 InstanceCatalogOffering object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceCatalogOffering') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceCatalogOffering') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceCatalogOfferingPrototype:
    """
    The [catalog](https://cloud.ibm.com/docs/account?topic=account-restrict-by-user)
    offering or offering version to use when provisioning this virtual server instance.
    If an offering is specified, the latest version of that offering will be used.
    The specified offering or offering version may be in a different account in the same
    [enterprise](https://cloud.ibm.com/docs/account?topic=account-what-is-enterprise),
    subject to IAM policies.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a InstanceCatalogOfferingPrototype object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['InstanceCatalogOfferingPrototypeCatalogOfferingByOffering', 'InstanceCatalogOfferingPrototypeCatalogOfferingByVersion'])
        )
        raise Exception(msg)


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(v) for v 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:
            if isinstance(self.first, dict):
                _dict['first'] = self.first
            else:
                _dict['first'] = self.first.to_dict()
        if hasattr(self, 'instances') and self.instances is not None:
            instances_list = []
            for v in self.instances:
                if isinstance(v, dict):
                    instances_list.append(v)
                else:
                    instances_list.append(v.to_dict())
            _dict['instances'] = instances_list
        if hasattr(self, 'limit') and self.limit is not None:
            _dict['limit'] = self.limit
        if hasattr(self, 'next') and self.next is not None:
            if isinstance(self.next, dict):
                _dict['next'] = self.next
            else:
                _dict['next'] = self.next.to_dict()
        if hasattr(self, 'total_count') and self.total_count is not None:
            _dict['total_count'] = self.total_count
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceCollection object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceCollection') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceCollection') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceCollectionFirst:
    """
    A link to the first page of resources.

    :attr str href: The URL for a page of resources.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a InstanceCollectionFirst object.

        :param str href: The URL for a page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceCollectionFirst':
        """Initialize a InstanceCollectionFirst object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in InstanceCollectionFirst JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceCollectionFirst object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceCollectionFirst object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceCollectionFirst') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceCollectionFirst') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceCollectionNext:
    """
    A link to the next page of resources. This property is present for all pages except
    the last page.

    :attr str href: The URL for a page of resources.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a InstanceCollectionNext object.

        :param str href: The URL for a page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceCollectionNext':
        """Initialize a InstanceCollectionNext object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in InstanceCollectionNext JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceCollectionNext object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceCollectionNext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceCollectionNext') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceCollectionNext') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceConsoleAccessToken:
    """
    The instance console access token information.

    :attr str access_token: A URL safe single-use token used to access the console
          WebSocket.
    :attr str console_type: The instance console type for which this token may be
          used.
    :attr datetime created_at: The date and time that the access token was created.
    :attr datetime expires_at: The date and time that the access token will expire.
    :attr bool force: Indicates whether to disconnect an existing serial console
          session as the serial console cannot be shared.  This has no effect on VNC
          consoles.
    :attr str href: The URL to access this instance console.
    """

    def __init__(
        self,
        access_token: str,
        console_type: str,
        created_at: datetime,
        expires_at: datetime,
        force: bool,
        href: str,
    ) -> None:
        """
        Initialize a InstanceConsoleAccessToken object.

        :param str access_token: A URL safe single-use token used to access the
               console WebSocket.
        :param str console_type: The instance console type for which this token may
               be used.
        :param datetime created_at: The date and time that the access token was
               created.
        :param datetime expires_at: The date and time that the access token will
               expire.
        :param bool force: Indicates whether to disconnect an existing serial
               console session as the serial console cannot be shared.  This has no effect
               on VNC consoles.
        :param str href: The URL to access this instance console.
        """
        self.access_token = access_token
        self.console_type = console_type
        self.created_at = created_at
        self.expires_at = expires_at
        self.force = force
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceConsoleAccessToken':
        """Initialize a InstanceConsoleAccessToken object from a json dictionary."""
        args = {}
        if 'access_token' in _dict:
            args['access_token'] = _dict.get('access_token')
        else:
            raise ValueError('Required property \'access_token\' not present in InstanceConsoleAccessToken JSON')
        if 'console_type' in _dict:
            args['console_type'] = _dict.get('console_type')
        else:
            raise ValueError('Required property \'console_type\' not present in InstanceConsoleAccessToken JSON')
        if 'created_at' in _dict:
            args['created_at'] = string_to_datetime(_dict.get('created_at'))
        else:
            raise ValueError('Required property \'created_at\' not present in InstanceConsoleAccessToken JSON')
        if 'expires_at' in _dict:
            args['expires_at'] = string_to_datetime(_dict.get('expires_at'))
        else:
            raise ValueError('Required property \'expires_at\' not present in InstanceConsoleAccessToken JSON')
        if 'force' in _dict:
            args['force'] = _dict.get('force')
        else:
            raise ValueError('Required property \'force\' not present in InstanceConsoleAccessToken JSON')
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in InstanceConsoleAccessToken JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceConsoleAccessToken object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'access_token') and self.access_token is not None:
            _dict['access_token'] = self.access_token
        if hasattr(self, 'console_type') and self.console_type is not None:
            _dict['console_type'] = self.console_type
        if hasattr(self, 'created_at') and self.created_at is not None:
            _dict['created_at'] = datetime_to_string(self.created_at)
        if hasattr(self, 'expires_at') and self.expires_at is not None:
            _dict['expires_at'] = datetime_to_string(self.expires_at)
        if hasattr(self, 'force') and self.force is not None:
            _dict['force'] = self.force
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceConsoleAccessToken object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceConsoleAccessToken') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceConsoleAccessToken') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ConsoleTypeEnum(str, Enum):
        """
        The instance console type for which this token may be used.
        """

        SERIAL = 'serial'
        VNC = 'vnc'



class InstanceDefaultTrustedProfilePrototype:
    """
    InstanceDefaultTrustedProfilePrototype.

    :attr bool auto_link: (optional) If set to `true`, the system will create a link
          to the specified `target` trusted profile during instance creation. Regardless
          of whether a link is created by the system or manually using the IAM Identity
          service, it will be automatically deleted when the instance is deleted.
    :attr TrustedProfileIdentity target: The default IAM trusted profile to use for
          this virtual server instance.
    """

    def __init__(
        self,
        target: 'TrustedProfileIdentity',
        *,
        auto_link: bool = None,
    ) -> None:
        """
        Initialize a InstanceDefaultTrustedProfilePrototype object.

        :param TrustedProfileIdentity target: The default IAM trusted profile to
               use for this virtual server instance.
        :param bool auto_link: (optional) If set to `true`, the system will create
               a link to the specified `target` trusted profile during instance creation.
               Regardless of whether a link is created by the system or manually using the
               IAM Identity service, it will be automatically deleted when the instance is
               deleted.
        """
        self.auto_link = auto_link
        self.target = target

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceDefaultTrustedProfilePrototype':
        """Initialize a InstanceDefaultTrustedProfilePrototype object from a json dictionary."""
        args = {}
        if 'auto_link' in _dict:
            args['auto_link'] = _dict.get('auto_link')
        if 'target' in _dict:
            args['target'] = _dict.get('target')
        else:
            raise ValueError('Required property \'target\' not present in InstanceDefaultTrustedProfilePrototype JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceDefaultTrustedProfilePrototype object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'auto_link') and self.auto_link is not None:
            _dict['auto_link'] = self.auto_link
        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 InstanceDefaultTrustedProfilePrototype object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceDefaultTrustedProfilePrototype') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceDefaultTrustedProfilePrototype') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceDisk:
    """
    InstanceDisk.

    :attr datetime created_at: The date and time that the disk was created.
    :attr str href: The URL for this instance disk.
    :attr str id: The unique identifier for this instance disk.
    :attr str interface_type: The disk interface used for attaching the disk.
          The enumerated values for this property are expected to expand in the future.
          When processing this property, check for and log unknown values. Optionally halt
          processing and surface the error, or bypass the resource on which the unexpected
          property value was encountered.
    :attr str name: The name for this instance disk. The name is unique across all
          disks on the instance.
    :attr str resource_type: The resource type.
    :attr int size: The size of the disk in GB (gigabytes).
    """

    def __init__(
        self,
        created_at: datetime,
        href: str,
        id: str,
        interface_type: str,
        name: str,
        resource_type: str,
        size: int,
    ) -> None:
        """
        Initialize a InstanceDisk object.

        :param datetime created_at: The date and time that the disk was created.
        :param str href: The URL for this instance disk.
        :param str id: The unique identifier for this instance disk.
        :param str interface_type: The disk interface used for attaching the disk.
               The enumerated values for this property are expected to expand in the
               future. When processing this property, check for and log unknown values.
               Optionally halt processing and surface the error, or bypass the resource on
               which the unexpected property value was encountered.
        :param str name: The name for this instance disk. The name is unique across
               all disks on the instance.
        :param str resource_type: The resource type.
        :param int size: The size of the disk in GB (gigabytes).
        """
        self.created_at = created_at
        self.href = href
        self.id = id
        self.interface_type = interface_type
        self.name = name
        self.resource_type = resource_type
        self.size = size

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceDisk':
        """Initialize a InstanceDisk object from a json dictionary."""
        args = {}
        if 'created_at' in _dict:
            args['created_at'] = string_to_datetime(_dict.get('created_at'))
        else:
            raise ValueError('Required property \'created_at\' not present in InstanceDisk JSON')
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in InstanceDisk JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in InstanceDisk JSON')
        if 'interface_type' in _dict:
            args['interface_type'] = _dict.get('interface_type')
        else:
            raise ValueError('Required property \'interface_type\' not present in InstanceDisk JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in InstanceDisk JSON')
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError('Required property \'resource_type\' not present in InstanceDisk JSON')
        if 'size' in _dict:
            args['size'] = _dict.get('size')
        else:
            raise ValueError('Required property \'size\' not present in InstanceDisk JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceDisk object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'created_at') and self.created_at is not None:
            _dict['created_at'] = datetime_to_string(self.created_at)
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'interface_type') and self.interface_type is not None:
            _dict['interface_type'] = self.interface_type
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'resource_type') and self.resource_type is not None:
            _dict['resource_type'] = self.resource_type
        if hasattr(self, 'size') and self.size is not None:
            _dict['size'] = self.size
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceDisk object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceDisk') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceDisk') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class InterfaceTypeEnum(str, Enum):
        """
        The disk interface used for attaching the disk.
        The enumerated values for this property are expected to expand in the future. When
        processing this property, check for and log unknown values. Optionally halt
        processing and surface the error, or bypass the resource on which the unexpected
        property value was encountered.
        """

        NVME = 'nvme'
        VIRTIO_BLK = 'virtio_blk'


    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        INSTANCE_DISK = 'instance_disk'



class InstanceDiskCollection:
    """
    InstanceDiskCollection.

    :attr List[InstanceDisk] disks: Collection of the instance's disks.
    """

    def __init__(
        self,
        disks: List['InstanceDisk'],
    ) -> None:
        """
        Initialize a InstanceDiskCollection object.

        :param List[InstanceDisk] disks: Collection of the instance's disks.
        """
        self.disks = disks

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceDiskCollection':
        """Initialize a InstanceDiskCollection object from a json dictionary."""
        args = {}
        if 'disks' in _dict:
            args['disks'] = [InstanceDisk.from_dict(v) for v in _dict.get('disks')]
        else:
            raise ValueError('Required property \'disks\' not present in InstanceDiskCollection JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceDiskCollection object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'disks') and self.disks is not None:
            disks_list = []
            for v in self.disks:
                if isinstance(v, dict):
                    disks_list.append(v)
                else:
                    disks_list.append(v.to_dict())
            _dict['disks'] = disks_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 InstanceDiskCollection object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceDiskCollection') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceDiskCollection') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceDiskPatch:
    """
    InstanceDiskPatch.

    :attr str name: (optional) The name for this instance disk. The name must not be
          used by another disk on the instance.
    """

    def __init__(
        self,
        *,
        name: str = None,
    ) -> None:
        """
        Initialize a InstanceDiskPatch object.

        :param str name: (optional) The name for this instance disk. The name must
               not be used by another disk on the instance.
        """
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceDiskPatch':
        """Initialize a InstanceDiskPatch object from a json dictionary."""
        args = {}
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceDiskPatch object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceDiskPatch object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceDiskPatch') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceDiskPatch') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceDiskReference:
    """
    InstanceDiskReference.

    :attr InstanceDiskReferenceDeleted deleted: (optional) If present, this property
          indicates the referenced resource has been deleted, and provides
          some supplementary information.
    :attr str href: The URL for this instance disk.
    :attr str id: The unique identifier for this instance disk.
    :attr str name: The name for this instance disk. The name is unique across all
          disks on the instance.
    :attr str resource_type: The resource type.
    """

    def __init__(
        self,
        href: str,
        id: str,
        name: str,
        resource_type: str,
        *,
        deleted: 'InstanceDiskReferenceDeleted' = None,
    ) -> None:
        """
        Initialize a InstanceDiskReference object.

        :param str href: The URL for this instance disk.
        :param str id: The unique identifier for this instance disk.
        :param str name: The name for this instance disk. The name is unique across
               all disks on the instance.
        :param str resource_type: The resource type.
        :param InstanceDiskReferenceDeleted deleted: (optional) If present, this
               property indicates the referenced resource has been deleted, and provides
               some supplementary information.
        """
        self.deleted = deleted
        self.href = href
        self.id = id
        self.name = name
        self.resource_type = resource_type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceDiskReference':
        """Initialize a InstanceDiskReference object from a json dictionary."""
        args = {}
        if 'deleted' in _dict:
            args['deleted'] = InstanceDiskReferenceDeleted.from_dict(_dict.get('deleted'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in InstanceDiskReference JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in InstanceDiskReference JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in InstanceDiskReference JSON')
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError('Required property \'resource_type\' not present in InstanceDiskReference JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceDiskReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'deleted') and self.deleted is not None:
            if isinstance(self.deleted, dict):
                _dict['deleted'] = self.deleted
            else:
                _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'resource_type') and self.resource_type is not None:
            _dict['resource_type'] = self.resource_type
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceDiskReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceDiskReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceDiskReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        INSTANCE_DISK = 'instance_disk'



class InstanceDiskReferenceDeleted:
    """
    If present, this property indicates the referenced resource has been deleted, and
    provides some supplementary information.

    :attr str more_info: Link to documentation about deleted resources.
    """

    def __init__(
        self,
        more_info: str,
    ) -> None:
        """
        Initialize a InstanceDiskReferenceDeleted object.

        :param str more_info: Link to documentation about deleted resources.
        """
        self.more_info = more_info

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceDiskReferenceDeleted':
        """Initialize a InstanceDiskReferenceDeleted object from a json dictionary."""
        args = {}
        if 'more_info' in _dict:
            args['more_info'] = _dict.get('more_info')
        else:
            raise ValueError('Required property \'more_info\' not present in InstanceDiskReferenceDeleted JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceDiskReferenceDeleted object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'more_info') and self.more_info is not None:
            _dict['more_info'] = self.more_info
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceDiskReferenceDeleted object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceDiskReferenceDeleted') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceDiskReferenceDeleted') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceGPU:
    """
    The virtual server instance GPU configuration.

    :attr int count: The number of GPUs assigned to the instance.
    :attr str manufacturer: The GPU manufacturer.
    :attr int memory: The overall amount of GPU memory in GiB (gibibytes).
    :attr str model: The GPU model.
    """

    def __init__(
        self,
        count: int,
        manufacturer: str,
        memory: int,
        model: str,
    ) -> None:
        """
        Initialize a InstanceGPU object.

        :param int count: The number of GPUs assigned to the instance.
        :param str manufacturer: The GPU manufacturer.
        :param int memory: The overall amount of GPU memory in GiB (gibibytes).
        :param str model: The GPU model.
        """
        self.count = count
        self.manufacturer = manufacturer
        self.memory = memory
        self.model = model

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceGPU':
        """Initialize a InstanceGPU object from a json dictionary."""
        args = {}
        if 'count' in _dict:
            args['count'] = _dict.get('count')
        else:
            raise ValueError('Required property \'count\' not present in InstanceGPU JSON')
        if 'manufacturer' in _dict:
            args['manufacturer'] = _dict.get('manufacturer')
        else:
            raise ValueError('Required property \'manufacturer\' not present in InstanceGPU JSON')
        if 'memory' in _dict:
            args['memory'] = _dict.get('memory')
        else:
            raise ValueError('Required property \'memory\' not present in InstanceGPU JSON')
        if 'model' in _dict:
            args['model'] = _dict.get('model')
        else:
            raise ValueError('Required property \'model\' not present in InstanceGPU JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceGPU object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'count') and self.count is not None:
            _dict['count'] = self.count
        if hasattr(self, 'manufacturer') and self.manufacturer is not None:
            _dict['manufacturer'] = self.manufacturer
        if hasattr(self, 'memory') and self.memory is not None:
            _dict['memory'] = self.memory
        if hasattr(self, 'model') and self.model is not None:
            _dict['model'] = self.model
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceGPU object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceGPU') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceGPU') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceGroup:
    """
    InstanceGroup.

    :attr int application_port: (optional) The port used for new load balancer pool
          members created by this instance group.
          This property will be present if and only if `load_balancer_pool` is present.
    :attr datetime created_at: The date and time that the instance group was
          created.
    :attr str crn: The CRN for this instance group.
    :attr str href: The URL for this instance group.
    :attr str id: The unique identifier for this instance group.
    :attr InstanceTemplateReference instance_template: The template used to create
          new instances for this group.
    :attr LoadBalancerPoolReference load_balancer_pool: (optional) If present, the
          load balancer pool this instance group manages. A pool member will
          be created for each instance created by this group.
    :attr List[InstanceGroupManagerReference] managers: The managers for the
          instance group.
    :attr int membership_count: The number of instances in the instance group.
    :attr str name: The name for this instance group. The name is unique across all
          instance groups in the region.
    :attr ResourceGroupReference resource_group:
    :attr str status: The status of the instance group
          - `deleting`: Group is being deleted
          - `healthy`: Group has `membership_count` instances
          - `scaling`: Instances in the group are being created or deleted to reach
                       `membership_count`
          - `unhealthy`: Group is unable to reach `membership_count` instances.
    :attr List[SubnetReference] subnets: The subnets to use when creating new
          instances.
    :attr datetime updated_at: The date and time that the instance group was
          updated.
    :attr VPCReference vpc: The VPC the instance group resides in.
    """

    def __init__(
        self,
        created_at: datetime,
        crn: str,
        href: str,
        id: str,
        instance_template: 'InstanceTemplateReference',
        managers: List['InstanceGroupManagerReference'],
        membership_count: int,
        name: str,
        resource_group: 'ResourceGroupReference',
        status: str,
        subnets: List['SubnetReference'],
        updated_at: datetime,
        vpc: 'VPCReference',
        *,
        application_port: int = None,
        load_balancer_pool: 'LoadBalancerPoolReference' = None,
    ) -> None:
        """
        Initialize a InstanceGroup object.

        :param datetime created_at: The date and time that the instance group was
               created.
        :param str crn: The CRN for this instance group.
        :param str href: The URL for this instance group.
        :param str id: The unique identifier for this instance group.
        :param InstanceTemplateReference instance_template: The template used to
               create new instances for this group.
        :param List[InstanceGroupManagerReference] managers: The managers for the
               instance group.
        :param int membership_count: The number of instances in the instance group.
        :param str name: The name for this instance group. The name is unique
               across all instance groups in the region.
        :param ResourceGroupReference resource_group:
        :param str status: The status of the instance group
               - `deleting`: Group is being deleted
               - `healthy`: Group has `membership_count` instances
               - `scaling`: Instances in the group are being created or deleted to reach
                            `membership_count`
               - `unhealthy`: Group is unable to reach `membership_count` instances.
        :param List[SubnetReference] subnets: The subnets to use when creating new
               instances.
        :param datetime updated_at: The date and time that the instance group was
               updated.
        :param VPCReference vpc: The VPC the instance group resides in.
        :param int application_port: (optional) The port used for new load balancer
               pool members created by this instance group.
               This property will be present if and only if `load_balancer_pool` is
               present.
        :param LoadBalancerPoolReference load_balancer_pool: (optional) If present,
               the load balancer pool this instance group manages. A pool member will
               be created for each instance created by this group.
        """
        self.application_port = application_port
        self.created_at = created_at
        self.crn = crn
        self.href = href
        self.id = id
        self.instance_template = instance_template
        self.load_balancer_pool = load_balancer_pool
        self.managers = managers
        self.membership_count = membership_count
        self.name = name
        self.resource_group = resource_group
        self.status = status
        self.subnets = subnets
        self.updated_at = updated_at
        self.vpc = vpc

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceGroup':
        """Initialize a InstanceGroup object from a json dictionary."""
        args = {}
        if 'application_port' in _dict:
            args['application_port'] = _dict.get('application_port')
        if 'created_at' in _dict:
            args['created_at'] = string_to_datetime(_dict.get('created_at'))
        else:
            raise ValueError('Required property \'created_at\' not present in InstanceGroup JSON')
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError('Required property \'crn\' not present in InstanceGroup JSON')
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in InstanceGroup JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in InstanceGroup JSON')
        if 'instance_template' in _dict:
            args['instance_template'] = InstanceTemplateReference.from_dict(_dict.get('instance_template'))
        else:
            raise ValueError('Required property \'instance_template\' not present in InstanceGroup JSON')
        if 'load_balancer_pool' in _dict:
            args['load_balancer_pool'] = LoadBalancerPoolReference.from_dict(_dict.get('load_balancer_pool'))
        if 'managers' in _dict:
            args['managers'] = [InstanceGroupManagerReference.from_dict(v) for v in _dict.get('managers')]
        else:
            raise ValueError('Required property \'managers\' not present in InstanceGroup JSON')
        if 'membership_count' in _dict:
            args['membership_count'] = _dict.get('membership_count')
        else:
            raise ValueError('Required property \'membership_count\' not present in InstanceGroup JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in InstanceGroup JSON')
        if 'resource_group' in _dict:
            args['resource_group'] = ResourceGroupReference.from_dict(_dict.get('resource_group'))
        else:
            raise ValueError('Required property \'resource_group\' not present in InstanceGroup JSON')
        if 'status' in _dict:
            args['status'] = _dict.get('status')
        else:
            raise ValueError('Required property \'status\' not present in InstanceGroup JSON')
        if 'subnets' in _dict:
            args['subnets'] = [SubnetReference.from_dict(v) for v in _dict.get('subnets')]
        else:
            raise ValueError('Required property \'subnets\' not present in InstanceGroup JSON')
        if 'updated_at' in _dict:
            args['updated_at'] = string_to_datetime(_dict.get('updated_at'))
        else:
            raise ValueError('Required property \'updated_at\' not present in InstanceGroup JSON')
        if 'vpc' in _dict:
            args['vpc'] = VPCReference.from_dict(_dict.get('vpc'))
        else:
            raise ValueError('Required property \'vpc\' not present in InstanceGroup JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceGroup object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'application_port') and self.application_port is not None:
            _dict['application_port'] = self.application_port
        if hasattr(self, 'created_at') and self.created_at is not None:
            _dict['created_at'] = datetime_to_string(self.created_at)
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'instance_template') and self.instance_template is not None:
            if isinstance(self.instance_template, dict):
                _dict['instance_template'] = self.instance_template
            else:
                _dict['instance_template'] = self.instance_template.to_dict()
        if hasattr(self, 'load_balancer_pool') and self.load_balancer_pool is not None:
            if isinstance(self.load_balancer_pool, dict):
                _dict['load_balancer_pool'] = self.load_balancer_pool
            else:
                _dict['load_balancer_pool'] = self.load_balancer_pool.to_dict()
        if hasattr(self, 'managers') and self.managers is not None:
            managers_list = []
            for v in self.managers:
                if isinstance(v, dict):
                    managers_list.append(v)
                else:
                    managers_list.append(v.to_dict())
            _dict['managers'] = managers_list
        if hasattr(self, 'membership_count') and self.membership_count is not None:
            _dict['membership_count'] = self.membership_count
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'resource_group') and self.resource_group is not None:
            if isinstance(self.resource_group, dict):
                _dict['resource_group'] = self.resource_group
            else:
                _dict['resource_group'] = self.resource_group.to_dict()
        if hasattr(self, 'status') and self.status is not None:
            _dict['status'] = self.status
        if hasattr(self, 'subnets') and self.subnets is not None:
            subnets_list = []
            for v in self.subnets:
                if isinstance(v, dict):
                    subnets_list.append(v)
                else:
                    subnets_list.append(v.to_dict())
            _dict['subnets'] = subnets_list
        if hasattr(self, 'updated_at') and self.updated_at is not None:
            _dict['updated_at'] = datetime_to_string(self.updated_at)
        if hasattr(self, 'vpc') and self.vpc is not None:
            if isinstance(self.vpc, dict):
                _dict['vpc'] = self.vpc
            else:
                _dict['vpc'] = self.vpc.to_dict()
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceGroup object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceGroup') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceGroup') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class StatusEnum(str, Enum):
        """
        The status of the instance group
        - `deleting`: Group is being deleted
        - `healthy`: Group has `membership_count` instances
        - `scaling`: Instances in the group are being created or deleted to reach
                     `membership_count`
        - `unhealthy`: Group is unable to reach `membership_count` instances.
        """

        DELETING = 'deleting'
        HEALTHY = 'healthy'
        SCALING = 'scaling'
        UNHEALTHY = 'unhealthy'



class InstanceGroupCollection:
    """
    InstanceGroupCollection.

    :attr InstanceGroupCollectionFirst first: A link to the first page of resources.
    :attr List[InstanceGroup] instance_groups: Collection of instance groups.
    :attr int limit: The maximum number of resources that can be returned by the
          request.
    :attr InstanceGroupCollectionNext next: (optional) A link to the next page of
          resources. This property is present for all pages
          except the last page.
    :attr int total_count: The total number of resources across all pages.
    """

    def __init__(
        self,
        first: 'InstanceGroupCollectionFirst',
        instance_groups: List['InstanceGroup'],
        limit: int,
        total_count: int,
        *,
        next: 'InstanceGroupCollectionNext' = None,
    ) -> None:
        """
        Initialize a InstanceGroupCollection object.

        :param InstanceGroupCollectionFirst first: A link to the first page of
               resources.
        :param List[InstanceGroup] instance_groups: Collection of instance groups.
        :param int limit: The maximum number of resources that can be returned by
               the request.
        :param int total_count: The total number of resources across all pages.
        :param InstanceGroupCollectionNext next: (optional) A link to the next page
               of resources. This property is present for all pages
               except the last page.
        """
        self.first = first
        self.instance_groups = instance_groups
        self.limit = limit
        self.next = next
        self.total_count = total_count

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceGroupCollection':
        """Initialize a InstanceGroupCollection object from a json dictionary."""
        args = {}
        if 'first' in _dict:
            args['first'] = InstanceGroupCollectionFirst.from_dict(_dict.get('first'))
        else:
            raise ValueError('Required property \'first\' not present in InstanceGroupCollection JSON')
        if 'instance_groups' in _dict:
            args['instance_groups'] = [InstanceGroup.from_dict(v) for v in _dict.get('instance_groups')]
        else:
            raise ValueError('Required property \'instance_groups\' not present in InstanceGroupCollection JSON')
        if 'limit' in _dict:
            args['limit'] = _dict.get('limit')
        else:
            raise ValueError('Required property \'limit\' not present in InstanceGroupCollection JSON')
        if 'next' in _dict:
            args['next'] = InstanceGroupCollectionNext.from_dict(_dict.get('next'))
        if 'total_count' in _dict:
            args['total_count'] = _dict.get('total_count')
        else:
            raise ValueError('Required property \'total_count\' not present in InstanceGroupCollection JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceGroupCollection object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'first') and self.first is not None:
            if isinstance(self.first, dict):
                _dict['first'] = self.first
            else:
                _dict['first'] = self.first.to_dict()
        if hasattr(self, 'instance_groups') and self.instance_groups is not None:
            instance_groups_list = []
            for v in self.instance_groups:
                if isinstance(v, dict):
                    instance_groups_list.append(v)
                else:
                    instance_groups_list.append(v.to_dict())
            _dict['instance_groups'] = instance_groups_list
        if hasattr(self, 'limit') and self.limit is not None:
            _dict['limit'] = self.limit
        if hasattr(self, 'next') and self.next is not None:
            if isinstance(self.next, dict):
                _dict['next'] = self.next
            else:
                _dict['next'] = self.next.to_dict()
        if hasattr(self, 'total_count') and self.total_count is not None:
            _dict['total_count'] = self.total_count
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceGroupCollection object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceGroupCollection') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceGroupCollection') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceGroupCollectionFirst:
    """
    A link to the first page of resources.

    :attr str href: The URL for a page of resources.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a InstanceGroupCollectionFirst object.

        :param str href: The URL for a page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceGroupCollectionFirst':
        """Initialize a InstanceGroupCollectionFirst object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in InstanceGroupCollectionFirst JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceGroupCollectionFirst object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceGroupCollectionFirst object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceGroupCollectionFirst') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceGroupCollectionFirst') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceGroupCollectionNext:
    """
    A link to the next page of resources. This property is present for all pages except
    the last page.

    :attr str href: The URL for a page of resources.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a InstanceGroupCollectionNext object.

        :param str href: The URL for a page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceGroupCollectionNext':
        """Initialize a InstanceGroupCollectionNext object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in InstanceGroupCollectionNext JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceGroupCollectionNext object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceGroupCollectionNext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceGroupCollectionNext') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceGroupCollectionNext') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceGroupManager:
    """
    InstanceGroupManager.

    :attr datetime created_at: The date and time that the instance group manager was
          created.
    :attr str href: The URL for this instance group manager.
    :attr str id: The unique identifier for this instance group manager.
    :attr bool management_enabled: Indicates whether this manager will control the
          instance group.
    :attr str name: The name for this instance group manager. The name is unique
          across all managers for the instance group.
    :attr datetime updated_at: The date and time that the instance group manager was
          updated.
    """

    def __init__(
        self,
        created_at: datetime,
        href: str,
        id: str,
        management_enabled: bool,
        name: str,
        updated_at: datetime,
    ) -> None:
        """
        Initialize a InstanceGroupManager object.

        :param datetime created_at: The date and time that the instance group
               manager was created.
        :param str href: The URL for this instance group manager.
        :param str id: The unique identifier for this instance group manager.
        :param bool management_enabled: Indicates whether this manager will control
               the instance group.
        :param str name: The name for this instance group manager. The name is
               unique across all managers for the instance group.
        :param datetime updated_at: The date and time that the instance group
               manager was updated.
        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['InstanceGroupManagerAutoScale', 'InstanceGroupManagerScheduled'])
        )
        raise Exception(msg)


class InstanceGroupManagerAction:
    """
    InstanceGroupManagerAction.

    :attr bool auto_delete: Indicates whether this scheduled action will be
          automatically deleted after it has completed and `auto_delete_timeout` hours
          have passed. At present, this is always
          `true`, but may be modifiable in the future.
    :attr int auto_delete_timeout: If `auto_delete` is `true`, and this scheduled
          action has finished, the hours after which it will be automatically deleted. If
          the value is `0`, the action will be deleted once it has finished. This value
          may be modifiable in the future.
    :attr datetime created_at: The date and time that the instance group manager
          action was created.
    :attr str href: The URL for this instance group manager action.
    :attr str id: The unique identifier for this instance group manager action.
    :attr str name: The name for this instance group manager action. The name is
          unique across all actions for the instance group manager.
    :attr str resource_type: The resource type.
    :attr str status: The status of the instance group action
          - `active`: Action is ready to be run
          - `completed`: Action was completed successfully
          - `failed`: Action could not be completed successfully
          - `incompatible`: Action parameters are not compatible with the group or manager
          - `omitted`: Action was not applied because this action's manager was disabled.
    :attr datetime updated_at: The date and time that the instance group manager
          action was updated.
    """

    def __init__(
        self,
        auto_delete: bool,
        auto_delete_timeout: int,
        created_at: datetime,
        href: str,
        id: str,
        name: str,
        resource_type: str,
        status: str,
        updated_at: datetime,
    ) -> None:
        """
        Initialize a InstanceGroupManagerAction object.

        :param bool auto_delete: Indicates whether this scheduled action will be
               automatically deleted after it has completed and `auto_delete_timeout`
               hours have passed. At present, this is always
               `true`, but may be modifiable in the future.
        :param int auto_delete_timeout: If `auto_delete` is `true`, and this
               scheduled action has finished, the hours after which it will be
               automatically deleted. If the value is `0`, the action will be deleted once
               it has finished. This value may be modifiable in the future.
        :param datetime created_at: The date and time that the instance group
               manager action was created.
        :param str href: The URL for this instance group manager action.
        :param str id: The unique identifier for this instance group manager
               action.
        :param str name: The name for this instance group manager action. The name
               is unique across all actions for the instance group manager.
        :param str resource_type: The resource type.
        :param str status: The status of the instance group action
               - `active`: Action is ready to be run
               - `completed`: Action was completed successfully
               - `failed`: Action could not be completed successfully
               - `incompatible`: Action parameters are not compatible with the group or
               manager
               - `omitted`: Action was not applied because this action's manager was
               disabled.
        :param datetime updated_at: The date and time that the instance group
               manager action was updated.
        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['InstanceGroupManagerActionScheduledAction'])
        )
        raise Exception(msg)

    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        INSTANCE_GROUP_MANAGER_ACTION = 'instance_group_manager_action'


    class StatusEnum(str, Enum):
        """
        The status of the instance group action
        - `active`: Action is ready to be run
        - `completed`: Action was completed successfully
        - `failed`: Action could not be completed successfully
        - `incompatible`: Action parameters are not compatible with the group or manager
        - `omitted`: Action was not applied because this action's manager was disabled.
        """

        ACTIVE = 'active'
        COMPLETED = 'completed'
        FAILED = 'failed'
        INCOMPATIBLE = 'incompatible'
        OMITTED = 'omitted'



class InstanceGroupManagerActionGroupPatch:
    """
    InstanceGroupManagerActionGroupPatch.

    :attr int membership_count: (optional) The desired number of instance group
          members at the scheduled time.
    """

    def __init__(
        self,
        *,
        membership_count: int = None,
    ) -> None:
        """
        Initialize a InstanceGroupManagerActionGroupPatch object.

        :param int membership_count: (optional) The desired number of instance
               group members at the scheduled time.
        """
        self.membership_count = membership_count

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceGroupManagerActionGroupPatch':
        """Initialize a InstanceGroupManagerActionGroupPatch object from a json dictionary."""
        args = {}
        if 'membership_count' in _dict:
            args['membership_count'] = _dict.get('membership_count')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceGroupManagerActionGroupPatch object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'membership_count') and self.membership_count is not None:
            _dict['membership_count'] = self.membership_count
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceGroupManagerActionGroupPatch object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceGroupManagerActionGroupPatch') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceGroupManagerActionGroupPatch') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceGroupManagerActionManagerPatch:
    """
    InstanceGroupManagerActionManagerPatch.

    :attr int max_membership_count: (optional) The desired maximum number of
          instance group members at the scheduled time.
    :attr int min_membership_count: (optional) The desired minimum number of
          instance group members at the scheduled time.
    """

    def __init__(
        self,
        *,
        max_membership_count: int = None,
        min_membership_count: int = None,
    ) -> None:
        """
        Initialize a InstanceGroupManagerActionManagerPatch object.

        :param int max_membership_count: (optional) The desired maximum number of
               instance group members at the scheduled time.
        :param int min_membership_count: (optional) The desired minimum number of
               instance group members at the scheduled time.
        """
        self.max_membership_count = max_membership_count
        self.min_membership_count = min_membership_count

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceGroupManagerActionManagerPatch':
        """Initialize a InstanceGroupManagerActionManagerPatch object from a json dictionary."""
        args = {}
        if 'max_membership_count' in _dict:
            args['max_membership_count'] = _dict.get('max_membership_count')
        if 'min_membership_count' in _dict:
            args['min_membership_count'] = _dict.get('min_membership_count')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceGroupManagerActionManagerPatch object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'max_membership_count') and self.max_membership_count is not None:
            _dict['max_membership_count'] = self.max_membership_count
        if hasattr(self, 'min_membership_count') and self.min_membership_count is not None:
            _dict['min_membership_count'] = self.min_membership_count
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceGroupManagerActionManagerPatch object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceGroupManagerActionManagerPatch') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceGroupManagerActionManagerPatch') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceGroupManagerActionPatch:
    """
    InstanceGroupManagerActionPatch.

    :attr str cron_spec: (optional) The cron specification for a recurring scheduled
          action. Actions can be applied a maximum of one time within a 5 min period.
    :attr InstanceGroupManagerActionGroupPatch group: (optional)
    :attr InstanceGroupManagerActionManagerPatch manager: (optional)
    :attr str name: (optional) The name for this instance group manager action. The
          name must not be used by another action for the instance group manager.
    :attr datetime run_at: (optional) The date and time the scheduled action will
          run.
    """

    def __init__(
        self,
        *,
        cron_spec: str = None,
        group: 'InstanceGroupManagerActionGroupPatch' = None,
        manager: 'InstanceGroupManagerActionManagerPatch' = None,
        name: str = None,
        run_at: datetime = None,
    ) -> None:
        """
        Initialize a InstanceGroupManagerActionPatch object.

        :param str cron_spec: (optional) The cron specification for a recurring
               scheduled action. Actions can be applied a maximum of one time within a 5
               min period.
        :param InstanceGroupManagerActionGroupPatch group: (optional)
        :param InstanceGroupManagerActionManagerPatch manager: (optional)
        :param str name: (optional) The name for this instance group manager
               action. The name must not be used by another action for the instance group
               manager.
        :param datetime run_at: (optional) The date and time the scheduled action
               will run.
        """
        self.cron_spec = cron_spec
        self.group = group
        self.manager = manager
        self.name = name
        self.run_at = run_at

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceGroupManagerActionPatch':
        """Initialize a InstanceGroupManagerActionPatch object from a json dictionary."""
        args = {}
        if 'cron_spec' in _dict:
            args['cron_spec'] = _dict.get('cron_spec')
        if 'group' in _dict:
            args['group'] = InstanceGroupManagerActionGroupPatch.from_dict(_dict.get('group'))
        if 'manager' in _dict:
            args['manager'] = InstanceGroupManagerActionManagerPatch.from_dict(_dict.get('manager'))
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        if 'run_at' in _dict:
            args['run_at'] = string_to_datetime(_dict.get('run_at'))
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceGroupManagerActionPatch object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'cron_spec') and self.cron_spec is not None:
            _dict['cron_spec'] = self.cron_spec
        if hasattr(self, 'group') and self.group is not None:
            if isinstance(self.group, dict):
                _dict['group'] = self.group
            else:
                _dict['group'] = self.group.to_dict()
        if hasattr(self, 'manager') and self.manager is not None:
            if isinstance(self.manager, dict):
                _dict['manager'] = self.manager
            else:
                _dict['manager'] = self.manager.to_dict()
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'run_at') and self.run_at is not None:
            _dict['run_at'] = datetime_to_string(self.run_at)
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceGroupManagerActionPatch object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceGroupManagerActionPatch') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceGroupManagerActionPatch') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceGroupManagerActionPrototype:
    """
    InstanceGroupManagerActionPrototype.

    :attr str name: (optional) The name for this instance group manager action. The
          name must not be used by another action for the instance group manager. If
          unspecified, the name will be a hyphenated list of randomly-selected words.
    """

    def __init__(
        self,
        *,
        name: str = None,
    ) -> None:
        """
        Initialize a InstanceGroupManagerActionPrototype object.

        :param str name: (optional) The name for this instance group manager
               action. The name must not be used by another action for the instance group
               manager. 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(['InstanceGroupManagerActionPrototypeScheduledActionPrototype'])
        )
        raise Exception(msg)


class InstanceGroupManagerActionReference:
    """
    InstanceGroupManagerActionReference.

    :attr InstanceGroupManagerActionReferenceDeleted deleted: (optional) If present,
          this property indicates the referenced resource has been deleted, and provides
          some supplementary information.
    :attr str href: The URL for this instance group manager action.
    :attr str id: The unique identifier for this instance group manager action.
    :attr str name: The name for this instance group manager action. The name is
          unique across all actions for the instance group manager.
    :attr str resource_type: The resource type.
    """

    def __init__(
        self,
        href: str,
        id: str,
        name: str,
        resource_type: str,
        *,
        deleted: 'InstanceGroupManagerActionReferenceDeleted' = None,
    ) -> None:
        """
        Initialize a InstanceGroupManagerActionReference object.

        :param str href: The URL for this instance group manager action.
        :param str id: The unique identifier for this instance group manager
               action.
        :param str name: The name for this instance group manager action. The name
               is unique across all actions for the instance group manager.
        :param str resource_type: The resource type.
        :param InstanceGroupManagerActionReferenceDeleted deleted: (optional) If
               present, this property indicates the referenced resource has been deleted,
               and provides
               some supplementary information.
        """
        self.deleted = deleted
        self.href = href
        self.id = id
        self.name = name
        self.resource_type = resource_type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceGroupManagerActionReference':
        """Initialize a InstanceGroupManagerActionReference object from a json dictionary."""
        args = {}
        if 'deleted' in _dict:
            args['deleted'] = InstanceGroupManagerActionReferenceDeleted.from_dict(_dict.get('deleted'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in InstanceGroupManagerActionReference JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in InstanceGroupManagerActionReference JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in InstanceGroupManagerActionReference JSON')
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError('Required property \'resource_type\' not present in InstanceGroupManagerActionReference JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceGroupManagerActionReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'deleted') and self.deleted is not None:
            if isinstance(self.deleted, dict):
                _dict['deleted'] = self.deleted
            else:
                _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'resource_type') and self.resource_type is not None:
            _dict['resource_type'] = self.resource_type
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceGroupManagerActionReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceGroupManagerActionReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceGroupManagerActionReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        INSTANCE_GROUP_MANAGER_ACTION = 'instance_group_manager_action'



class InstanceGroupManagerActionReferenceDeleted:
    """
    If present, this property indicates the referenced resource has been deleted, and
    provides some supplementary information.

    :attr str more_info: Link to documentation about deleted resources.
    """

    def __init__(
        self,
        more_info: str,
    ) -> None:
        """
        Initialize a InstanceGroupManagerActionReferenceDeleted object.

        :param str more_info: Link to documentation about deleted resources.
        """
        self.more_info = more_info

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceGroupManagerActionReferenceDeleted':
        """Initialize a InstanceGroupManagerActionReferenceDeleted object from a json dictionary."""
        args = {}
        if 'more_info' in _dict:
            args['more_info'] = _dict.get('more_info')
        else:
            raise ValueError('Required property \'more_info\' not present in InstanceGroupManagerActionReferenceDeleted JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceGroupManagerActionReferenceDeleted object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'more_info') and self.more_info is not None:
            _dict['more_info'] = self.more_info
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceGroupManagerActionReferenceDeleted object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceGroupManagerActionReferenceDeleted') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceGroupManagerActionReferenceDeleted') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceGroupManagerActionsCollection:
    """
    InstanceGroupManagerActionsCollection.

    :attr List[InstanceGroupManagerAction] actions: Collection of instance group
          manager actions.
    :attr InstanceGroupManagerActionsCollectionFirst first: A link to the first page
          of resources.
    :attr int limit: The maximum number of resources that can be returned by the
          request.
    :attr InstanceGroupManagerActionsCollectionNext next: (optional) A link to the
          next page of resources. This property is present for all pages
          except the last page.
    :attr int total_count: The total number of resources across all pages.
    """

    def __init__(
        self,
        actions: List['InstanceGroupManagerAction'],
        first: 'InstanceGroupManagerActionsCollectionFirst',
        limit: int,
        total_count: int,
        *,
        next: 'InstanceGroupManagerActionsCollectionNext' = None,
    ) -> None:
        """
        Initialize a InstanceGroupManagerActionsCollection object.

        :param List[InstanceGroupManagerAction] actions: Collection of instance
               group manager actions.
        :param InstanceGroupManagerActionsCollectionFirst first: A link to the
               first page of resources.
        :param int limit: The maximum number of resources that can be returned by
               the request.
        :param int total_count: The total number of resources across all pages.
        :param InstanceGroupManagerActionsCollectionNext next: (optional) A link to
               the next page of resources. This property is present for all pages
               except the last page.
        """
        self.actions = actions
        self.first = first
        self.limit = limit
        self.next = next
        self.total_count = total_count

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceGroupManagerActionsCollection':
        """Initialize a InstanceGroupManagerActionsCollection object from a json dictionary."""
        args = {}
        if 'actions' in _dict:
            args['actions'] = _dict.get('actions')
        else:
            raise ValueError('Required property \'actions\' not present in InstanceGroupManagerActionsCollection JSON')
        if 'first' in _dict:
            args['first'] = InstanceGroupManagerActionsCollectionFirst.from_dict(_dict.get('first'))
        else:
            raise ValueError('Required property \'first\' not present in InstanceGroupManagerActionsCollection JSON')
        if 'limit' in _dict:
            args['limit'] = _dict.get('limit')
        else:
            raise ValueError('Required property \'limit\' not present in InstanceGroupManagerActionsCollection JSON')
        if 'next' in _dict:
            args['next'] = InstanceGroupManagerActionsCollectionNext.from_dict(_dict.get('next'))
        if 'total_count' in _dict:
            args['total_count'] = _dict.get('total_count')
        else:
            raise ValueError('Required property \'total_count\' not present in InstanceGroupManagerActionsCollection JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceGroupManagerActionsCollection object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'actions') and self.actions is not None:
            actions_list = []
            for v in self.actions:
                if isinstance(v, dict):
                    actions_list.append(v)
                else:
                    actions_list.append(v.to_dict())
            _dict['actions'] = actions_list
        if hasattr(self, 'first') and self.first is not None:
            if isinstance(self.first, dict):
                _dict['first'] = self.first
            else:
                _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:
            if isinstance(self.next, dict):
                _dict['next'] = self.next
            else:
                _dict['next'] = self.next.to_dict()
        if hasattr(self, 'total_count') and self.total_count is not None:
            _dict['total_count'] = self.total_count
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceGroupManagerActionsCollection object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceGroupManagerActionsCollection') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceGroupManagerActionsCollection') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceGroupManagerActionsCollectionFirst:
    """
    A link to the first page of resources.

    :attr str href: The URL for a page of resources.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a InstanceGroupManagerActionsCollectionFirst object.

        :param str href: The URL for a page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceGroupManagerActionsCollectionFirst':
        """Initialize a InstanceGroupManagerActionsCollectionFirst object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in InstanceGroupManagerActionsCollectionFirst JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceGroupManagerActionsCollectionFirst object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceGroupManagerActionsCollectionFirst object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceGroupManagerActionsCollectionFirst') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceGroupManagerActionsCollectionFirst') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceGroupManagerActionsCollectionNext:
    """
    A link to the next page of resources. This property is present for all pages except
    the last page.

    :attr str href: The URL for a page of resources.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a InstanceGroupManagerActionsCollectionNext object.

        :param str href: The URL for a page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceGroupManagerActionsCollectionNext':
        """Initialize a InstanceGroupManagerActionsCollectionNext object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in InstanceGroupManagerActionsCollectionNext JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceGroupManagerActionsCollectionNext object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceGroupManagerActionsCollectionNext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceGroupManagerActionsCollectionNext') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceGroupManagerActionsCollectionNext') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceGroupManagerCollection:
    """
    InstanceGroupManagerCollection.

    :attr InstanceGroupManagerCollectionFirst first: A link to the first page of
          resources.
    :attr int limit: The maximum number of resources that can be returned by the
          request.
    :attr List[InstanceGroupManager] managers: Collection of instance group
          managers.
    :attr InstanceGroupManagerCollectionNext next: (optional) A link to the next
          page of resources. This property is present for all pages
          except the last page.
    :attr int total_count: The total number of resources across all pages.
    """

    def __init__(
        self,
        first: 'InstanceGroupManagerCollectionFirst',
        limit: int,
        managers: List['InstanceGroupManager'],
        total_count: int,
        *,
        next: 'InstanceGroupManagerCollectionNext' = None,
    ) -> None:
        """
        Initialize a InstanceGroupManagerCollection object.

        :param InstanceGroupManagerCollectionFirst first: A link to the first page
               of resources.
        :param int limit: The maximum number of resources that can be returned by
               the request.
        :param List[InstanceGroupManager] managers: Collection of instance group
               managers.
        :param int total_count: The total number of resources across all pages.
        :param InstanceGroupManagerCollectionNext next: (optional) A link to the
               next page of resources. This property is present for all pages
               except the last page.
        """
        self.first = first
        self.limit = limit
        self.managers = managers
        self.next = next
        self.total_count = total_count

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceGroupManagerCollection':
        """Initialize a InstanceGroupManagerCollection object from a json dictionary."""
        args = {}
        if 'first' in _dict:
            args['first'] = InstanceGroupManagerCollectionFirst.from_dict(_dict.get('first'))
        else:
            raise ValueError('Required property \'first\' not present in InstanceGroupManagerCollection JSON')
        if 'limit' in _dict:
            args['limit'] = _dict.get('limit')
        else:
            raise ValueError('Required property \'limit\' not present in InstanceGroupManagerCollection JSON')
        if 'managers' in _dict:
            args['managers'] = _dict.get('managers')
        else:
            raise ValueError('Required property \'managers\' not present in InstanceGroupManagerCollection JSON')
        if 'next' in _dict:
            args['next'] = InstanceGroupManagerCollectionNext.from_dict(_dict.get('next'))
        if 'total_count' in _dict:
            args['total_count'] = _dict.get('total_count')
        else:
            raise ValueError('Required property \'total_count\' not present in InstanceGroupManagerCollection JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceGroupManagerCollection object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'first') and self.first is not None:
            if isinstance(self.first, dict):
                _dict['first'] = self.first
            else:
                _dict['first'] = self.first.to_dict()
        if hasattr(self, 'limit') and self.limit is not None:
            _dict['limit'] = self.limit
        if hasattr(self, 'managers') and self.managers is not None:
            managers_list = []
            for v in self.managers:
                if isinstance(v, dict):
                    managers_list.append(v)
                else:
                    managers_list.append(v.to_dict())
            _dict['managers'] = managers_list
        if hasattr(self, 'next') and self.next is not None:
            if isinstance(self.next, dict):
                _dict['next'] = self.next
            else:
                _dict['next'] = self.next.to_dict()
        if hasattr(self, 'total_count') and self.total_count is not None:
            _dict['total_count'] = self.total_count
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceGroupManagerCollection object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceGroupManagerCollection') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceGroupManagerCollection') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceGroupManagerCollectionFirst:
    """
    A link to the first page of resources.

    :attr str href: The URL for a page of resources.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a InstanceGroupManagerCollectionFirst object.

        :param str href: The URL for a page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceGroupManagerCollectionFirst':
        """Initialize a InstanceGroupManagerCollectionFirst object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in InstanceGroupManagerCollectionFirst JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceGroupManagerCollectionFirst object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceGroupManagerCollectionFirst object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceGroupManagerCollectionFirst') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceGroupManagerCollectionFirst') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceGroupManagerCollectionNext:
    """
    A link to the next page of resources. This property is present for all pages except
    the last page.

    :attr str href: The URL for a page of resources.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a InstanceGroupManagerCollectionNext object.

        :param str href: The URL for a page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceGroupManagerCollectionNext':
        """Initialize a InstanceGroupManagerCollectionNext object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in InstanceGroupManagerCollectionNext JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceGroupManagerCollectionNext object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceGroupManagerCollectionNext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceGroupManagerCollectionNext') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceGroupManagerCollectionNext') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceGroupManagerPatch:
    """
    InstanceGroupManagerPatch.

    :attr int aggregation_window: (optional) The time window in seconds to aggregate
          metrics prior to evaluation.
    :attr int cooldown: (optional) The duration of time in seconds to pause further
          scale actions after scaling has taken place.
    :attr bool management_enabled: (optional) Indicates whether this manager will
          control the instance group.
    :attr int max_membership_count: (optional) The maximum number of members in a
          managed instance group.
    :attr int min_membership_count: (optional) The minimum number of members in a
          managed instance group.
    :attr str name: (optional) The name for this instance group manager. The name
          must not be used by another manager for the instance group.
    """

    def __init__(
        self,
        *,
        aggregation_window: int = None,
        cooldown: int = None,
        management_enabled: bool = None,
        max_membership_count: int = None,
        min_membership_count: int = None,
        name: str = None,
    ) -> None:
        """
        Initialize a InstanceGroupManagerPatch object.

        :param int aggregation_window: (optional) The time window in seconds to
               aggregate metrics prior to evaluation.
        :param int cooldown: (optional) The duration of time in seconds to pause
               further scale actions after scaling has taken place.
        :param bool management_enabled: (optional) Indicates whether this manager
               will control the instance group.
        :param int max_membership_count: (optional) The maximum number of members
               in a managed instance group.
        :param int min_membership_count: (optional) The minimum number of members
               in a managed instance group.
        :param str name: (optional) The name for this instance group manager. The
               name must not be used by another manager for the instance group.
        """
        self.aggregation_window = aggregation_window
        self.cooldown = cooldown
        self.management_enabled = management_enabled
        self.max_membership_count = max_membership_count
        self.min_membership_count = min_membership_count
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceGroupManagerPatch':
        """Initialize a InstanceGroupManagerPatch object from a json dictionary."""
        args = {}
        if 'aggregation_window' in _dict:
            args['aggregation_window'] = _dict.get('aggregation_window')
        if 'cooldown' in _dict:
            args['cooldown'] = _dict.get('cooldown')
        if 'management_enabled' in _dict:
            args['management_enabled'] = _dict.get('management_enabled')
        if 'max_membership_count' in _dict:
            args['max_membership_count'] = _dict.get('max_membership_count')
        if 'min_membership_count' in _dict:
            args['min_membership_count'] = _dict.get('min_membership_count')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceGroupManagerPatch object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'aggregation_window') and self.aggregation_window is not None:
            _dict['aggregation_window'] = self.aggregation_window
        if hasattr(self, 'cooldown') and self.cooldown is not None:
            _dict['cooldown'] = self.cooldown
        if hasattr(self, 'management_enabled') and self.management_enabled is not None:
            _dict['management_enabled'] = self.management_enabled
        if hasattr(self, 'max_membership_count') and self.max_membership_count is not None:
            _dict['max_membership_count'] = self.max_membership_count
        if hasattr(self, 'min_membership_count') and self.min_membership_count is not None:
            _dict['min_membership_count'] = self.min_membership_count
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceGroupManagerPatch object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceGroupManagerPatch') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceGroupManagerPatch') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceGroupManagerPolicy:
    """
    InstanceGroupManagerPolicy.

    :attr datetime created_at: The date and time that the instance group manager
          policy was created.
    :attr str href: The URL for this instance group manager policy.
    :attr str id: The unique identifier for this instance group manager policy.
    :attr str name: The name for this instance group manager policy. The name is
          unique across all policies for the instance group manager.
    :attr datetime updated_at: The date and time that the instance group manager
          policy was updated.
    """

    def __init__(
        self,
        created_at: datetime,
        href: str,
        id: str,
        name: str,
        updated_at: datetime,
    ) -> None:
        """
        Initialize a InstanceGroupManagerPolicy object.

        :param datetime created_at: The date and time that the instance group
               manager policy was created.
        :param str href: The URL for this instance group manager policy.
        :param str id: The unique identifier for this instance group manager
               policy.
        :param str name: The name for this instance group manager policy. The name
               is unique across all policies for the instance group manager.
        :param datetime updated_at: The date and time that the instance group
               manager policy was updated.
        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['InstanceGroupManagerPolicyInstanceGroupManagerTargetPolicy'])
        )
        raise Exception(msg)


class InstanceGroupManagerPolicyCollection:
    """
    InstanceGroupManagerPolicyCollection.

    :attr InstanceGroupManagerPolicyCollectionFirst first: A link to the first page
          of resources.
    :attr int limit: The maximum number of resources that can be returned by the
          request.
    :attr InstanceGroupManagerPolicyCollectionNext next: (optional) A link to the
          next page of resources. This property is present for all pages
          except the last page.
    :attr List[InstanceGroupManagerPolicy] policies: Collection of instance group
          manager policies.
    :attr int total_count: The total number of resources across all pages.
    """

    def __init__(
        self,
        first: 'InstanceGroupManagerPolicyCollectionFirst',
        limit: int,
        policies: List['InstanceGroupManagerPolicy'],
        total_count: int,
        *,
        next: 'InstanceGroupManagerPolicyCollectionNext' = None,
    ) -> None:
        """
        Initialize a InstanceGroupManagerPolicyCollection object.

        :param InstanceGroupManagerPolicyCollectionFirst first: A link to the first
               page of resources.
        :param int limit: The maximum number of resources that can be returned by
               the request.
        :param List[InstanceGroupManagerPolicy] policies: Collection of instance
               group manager policies.
        :param int total_count: The total number of resources across all pages.
        :param InstanceGroupManagerPolicyCollectionNext next: (optional) A link to
               the next page of resources. This property is present for all pages
               except the last page.
        """
        self.first = first
        self.limit = limit
        self.next = next
        self.policies = policies
        self.total_count = total_count

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceGroupManagerPolicyCollection':
        """Initialize a InstanceGroupManagerPolicyCollection object from a json dictionary."""
        args = {}
        if 'first' in _dict:
            args['first'] = InstanceGroupManagerPolicyCollectionFirst.from_dict(_dict.get('first'))
        else:
            raise ValueError('Required property \'first\' not present in InstanceGroupManagerPolicyCollection JSON')
        if 'limit' in _dict:
            args['limit'] = _dict.get('limit')
        else:
            raise ValueError('Required property \'limit\' not present in InstanceGroupManagerPolicyCollection JSON')
        if 'next' in _dict:
            args['next'] = InstanceGroupManagerPolicyCollectionNext.from_dict(_dict.get('next'))
        if 'policies' in _dict:
            args['policies'] = _dict.get('policies')
        else:
            raise ValueError('Required property \'policies\' not present in InstanceGroupManagerPolicyCollection JSON')
        if 'total_count' in _dict:
            args['total_count'] = _dict.get('total_count')
        else:
            raise ValueError('Required property \'total_count\' not present in InstanceGroupManagerPolicyCollection JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceGroupManagerPolicyCollection object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'first') and self.first is not None:
            if isinstance(self.first, dict):
                _dict['first'] = self.first
            else:
                _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:
            if isinstance(self.next, dict):
                _dict['next'] = self.next
            else:
                _dict['next'] = self.next.to_dict()
        if hasattr(self, 'policies') and self.policies is not None:
            policies_list = []
            for v in self.policies:
                if isinstance(v, dict):
                    policies_list.append(v)
                else:
                    policies_list.append(v.to_dict())
            _dict['policies'] = policies_list
        if hasattr(self, 'total_count') and self.total_count is not None:
            _dict['total_count'] = self.total_count
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceGroupManagerPolicyCollection object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceGroupManagerPolicyCollection') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceGroupManagerPolicyCollection') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceGroupManagerPolicyCollectionFirst:
    """
    A link to the first page of resources.

    :attr str href: The URL for a page of resources.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a InstanceGroupManagerPolicyCollectionFirst object.

        :param str href: The URL for a page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceGroupManagerPolicyCollectionFirst':
        """Initialize a InstanceGroupManagerPolicyCollectionFirst object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in InstanceGroupManagerPolicyCollectionFirst JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceGroupManagerPolicyCollectionFirst object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceGroupManagerPolicyCollectionFirst object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceGroupManagerPolicyCollectionFirst') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceGroupManagerPolicyCollectionFirst') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceGroupManagerPolicyCollectionNext:
    """
    A link to the next page of resources. This property is present for all pages except
    the last page.

    :attr str href: The URL for a page of resources.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a InstanceGroupManagerPolicyCollectionNext object.

        :param str href: The URL for a page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceGroupManagerPolicyCollectionNext':
        """Initialize a InstanceGroupManagerPolicyCollectionNext object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in InstanceGroupManagerPolicyCollectionNext JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceGroupManagerPolicyCollectionNext object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceGroupManagerPolicyCollectionNext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceGroupManagerPolicyCollectionNext') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceGroupManagerPolicyCollectionNext') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceGroupManagerPolicyPatch:
    """
    InstanceGroupManagerPolicyPatch.

    :attr str metric_type: (optional) The type of metric to be evaluated.
    :attr int metric_value: (optional) The metric value to be evaluated.
    :attr str name: (optional) The name for this instance group manager policy. The
          name must not be used by another policy for the instance group manager.
    """

    def __init__(
        self,
        *,
        metric_type: str = None,
        metric_value: int = None,
        name: str = None,
    ) -> None:
        """
        Initialize a InstanceGroupManagerPolicyPatch object.

        :param str metric_type: (optional) The type of metric to be evaluated.
        :param int metric_value: (optional) The metric value to be evaluated.
        :param str name: (optional) The name for this instance group manager
               policy. The name must not be used by another policy for the instance group
               manager.
        """
        self.metric_type = metric_type
        self.metric_value = metric_value
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceGroupManagerPolicyPatch':
        """Initialize a InstanceGroupManagerPolicyPatch object from a json dictionary."""
        args = {}
        if 'metric_type' in _dict:
            args['metric_type'] = _dict.get('metric_type')
        if 'metric_value' in _dict:
            args['metric_value'] = _dict.get('metric_value')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceGroupManagerPolicyPatch object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'metric_type') and self.metric_type is not None:
            _dict['metric_type'] = self.metric_type
        if hasattr(self, 'metric_value') and self.metric_value is not None:
            _dict['metric_value'] = self.metric_value
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceGroupManagerPolicyPatch object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceGroupManagerPolicyPatch') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceGroupManagerPolicyPatch') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class MetricTypeEnum(str, Enum):
        """
        The type of metric to be evaluated.
        """

        CPU = 'cpu'
        MEMORY = 'memory'
        NETWORK_IN = 'network_in'
        NETWORK_OUT = 'network_out'



class InstanceGroupManagerPolicyPrototype:
    """
    InstanceGroupManagerPolicyPrototype.

    :attr str name: (optional) The name for this instance group manager policy. The
          name must not be used by another policy for the instance group manager. If
          unspecified, the name will be a hyphenated list of randomly-selected words.
    """

    def __init__(
        self,
        *,
        name: str = None,
    ) -> None:
        """
        Initialize a InstanceGroupManagerPolicyPrototype object.

        :param str name: (optional) The name for this instance group manager
               policy. The name must not be used by another policy for the instance group
               manager. 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(['InstanceGroupManagerPolicyPrototypeInstanceGroupManagerTargetPolicyPrototype'])
        )
        raise Exception(msg)


class InstanceGroupManagerPolicyReference:
    """
    InstanceGroupManagerPolicyReference.

    :attr InstanceGroupManagerPolicyReferenceDeleted deleted: (optional) If present,
          this property indicates the referenced resource has been deleted, and provides
          some supplementary information.
    :attr str href: The URL for this instance group manager policy.
    :attr str id: The unique identifier for this instance group manager policy.
    :attr str name: The name for this instance group manager policy. The name is
          unique across all policies for the instance group manager.
    """

    def __init__(
        self,
        href: str,
        id: str,
        name: str,
        *,
        deleted: 'InstanceGroupManagerPolicyReferenceDeleted' = None,
    ) -> None:
        """
        Initialize a InstanceGroupManagerPolicyReference object.

        :param str href: The URL for this instance group manager policy.
        :param str id: The unique identifier for this instance group manager
               policy.
        :param str name: The name for this instance group manager policy. The name
               is unique across all policies for the instance group manager.
        :param InstanceGroupManagerPolicyReferenceDeleted deleted: (optional) If
               present, this property indicates the referenced resource has been deleted,
               and provides
               some supplementary information.
        """
        self.deleted = deleted
        self.href = href
        self.id = id
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceGroupManagerPolicyReference':
        """Initialize a InstanceGroupManagerPolicyReference object from a json dictionary."""
        args = {}
        if 'deleted' in _dict:
            args['deleted'] = InstanceGroupManagerPolicyReferenceDeleted.from_dict(_dict.get('deleted'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in InstanceGroupManagerPolicyReference JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in InstanceGroupManagerPolicyReference JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in InstanceGroupManagerPolicyReference JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceGroupManagerPolicyReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'deleted') and self.deleted is not None:
            if isinstance(self.deleted, dict):
                _dict['deleted'] = self.deleted
            else:
                _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceGroupManagerPolicyReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceGroupManagerPolicyReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceGroupManagerPolicyReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceGroupManagerPolicyReferenceDeleted:
    """
    If present, this property indicates the referenced resource has been deleted, and
    provides some supplementary information.

    :attr str more_info: Link to documentation about deleted resources.
    """

    def __init__(
        self,
        more_info: str,
    ) -> None:
        """
        Initialize a InstanceGroupManagerPolicyReferenceDeleted object.

        :param str more_info: Link to documentation about deleted resources.
        """
        self.more_info = more_info

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceGroupManagerPolicyReferenceDeleted':
        """Initialize a InstanceGroupManagerPolicyReferenceDeleted object from a json dictionary."""
        args = {}
        if 'more_info' in _dict:
            args['more_info'] = _dict.get('more_info')
        else:
            raise ValueError('Required property \'more_info\' not present in InstanceGroupManagerPolicyReferenceDeleted JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceGroupManagerPolicyReferenceDeleted object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'more_info') and self.more_info is not None:
            _dict['more_info'] = self.more_info
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceGroupManagerPolicyReferenceDeleted object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceGroupManagerPolicyReferenceDeleted') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceGroupManagerPolicyReferenceDeleted') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceGroupManagerPrototype:
    """
    InstanceGroupManagerPrototype.

    :attr bool management_enabled: (optional) Indicates whether this manager will
          control the instance group.
    :attr str name: (optional) The name for this instance group manager. The name
          must not be used by another manager for the instance group. If unspecified, the
          name will be a hyphenated list of randomly-selected words.
    """

    def __init__(
        self,
        *,
        management_enabled: bool = None,
        name: str = None,
    ) -> None:
        """
        Initialize a InstanceGroupManagerPrototype object.

        :param bool management_enabled: (optional) Indicates whether this manager
               will control the instance group.
        :param str name: (optional) The name for this instance group manager. The
               name must not be used by another manager for the instance group. 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(['InstanceGroupManagerPrototypeInstanceGroupManagerAutoScalePrototype', 'InstanceGroupManagerPrototypeInstanceGroupManagerScheduledPrototype'])
        )
        raise Exception(msg)


class InstanceGroupManagerReference:
    """
    InstanceGroupManagerReference.

    :attr InstanceGroupManagerReferenceDeleted deleted: (optional) If present, this
          property indicates the referenced resource has been deleted, and provides
          some supplementary information.
    :attr str href: The URL for this instance group manager.
    :attr str id: The unique identifier for this instance group manager.
    :attr str name: The name for this instance group manager. The name is unique
          across all managers for the instance group.
    """

    def __init__(
        self,
        href: str,
        id: str,
        name: str,
        *,
        deleted: 'InstanceGroupManagerReferenceDeleted' = None,
    ) -> None:
        """
        Initialize a InstanceGroupManagerReference object.

        :param str href: The URL for this instance group manager.
        :param str id: The unique identifier for this instance group manager.
        :param str name: The name for this instance group manager. The name is
               unique across all managers for the instance group.
        :param InstanceGroupManagerReferenceDeleted deleted: (optional) If present,
               this property indicates the referenced resource has been deleted, and
               provides
               some supplementary information.
        """
        self.deleted = deleted
        self.href = href
        self.id = id
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceGroupManagerReference':
        """Initialize a InstanceGroupManagerReference object from a json dictionary."""
        args = {}
        if 'deleted' in _dict:
            args['deleted'] = InstanceGroupManagerReferenceDeleted.from_dict(_dict.get('deleted'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in InstanceGroupManagerReference JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in InstanceGroupManagerReference JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in InstanceGroupManagerReference JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceGroupManagerReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'deleted') and self.deleted is not None:
            if isinstance(self.deleted, dict):
                _dict['deleted'] = self.deleted
            else:
                _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceGroupManagerReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceGroupManagerReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceGroupManagerReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceGroupManagerReferenceDeleted:
    """
    If present, this property indicates the referenced resource has been deleted, and
    provides some supplementary information.

    :attr str more_info: Link to documentation about deleted resources.
    """

    def __init__(
        self,
        more_info: str,
    ) -> None:
        """
        Initialize a InstanceGroupManagerReferenceDeleted object.

        :param str more_info: Link to documentation about deleted resources.
        """
        self.more_info = more_info

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceGroupManagerReferenceDeleted':
        """Initialize a InstanceGroupManagerReferenceDeleted object from a json dictionary."""
        args = {}
        if 'more_info' in _dict:
            args['more_info'] = _dict.get('more_info')
        else:
            raise ValueError('Required property \'more_info\' not present in InstanceGroupManagerReferenceDeleted JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceGroupManagerReferenceDeleted object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'more_info') and self.more_info is not None:
            _dict['more_info'] = self.more_info
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceGroupManagerReferenceDeleted object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceGroupManagerReferenceDeleted') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceGroupManagerReferenceDeleted') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceGroupManagerScheduledActionGroup:
    """
    InstanceGroupManagerScheduledActionGroup.

    :attr int membership_count: The desired number of instance group members at the
          scheduled time.
    """

    def __init__(
        self,
        membership_count: int,
    ) -> None:
        """
        Initialize a InstanceGroupManagerScheduledActionGroup object.

        :param int membership_count: The desired number of instance group members
               at the scheduled time.
        """
        self.membership_count = membership_count

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceGroupManagerScheduledActionGroup':
        """Initialize a InstanceGroupManagerScheduledActionGroup object from a json dictionary."""
        args = {}
        if 'membership_count' in _dict:
            args['membership_count'] = _dict.get('membership_count')
        else:
            raise ValueError('Required property \'membership_count\' not present in InstanceGroupManagerScheduledActionGroup JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceGroupManagerScheduledActionGroup object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'membership_count') and self.membership_count is not None:
            _dict['membership_count'] = self.membership_count
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceGroupManagerScheduledActionGroup object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceGroupManagerScheduledActionGroup') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceGroupManagerScheduledActionGroup') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceGroupManagerScheduledActionGroupPrototype:
    """
    InstanceGroupManagerScheduledActionGroupPrototype.

    :attr int membership_count: The desired number of instance group members at the
          scheduled time.
    """

    def __init__(
        self,
        membership_count: int,
    ) -> None:
        """
        Initialize a InstanceGroupManagerScheduledActionGroupPrototype object.

        :param int membership_count: The desired number of instance group members
               at the scheduled time.
        """
        self.membership_count = membership_count

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceGroupManagerScheduledActionGroupPrototype':
        """Initialize a InstanceGroupManagerScheduledActionGroupPrototype object from a json dictionary."""
        args = {}
        if 'membership_count' in _dict:
            args['membership_count'] = _dict.get('membership_count')
        else:
            raise ValueError('Required property \'membership_count\' not present in InstanceGroupManagerScheduledActionGroupPrototype JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceGroupManagerScheduledActionGroupPrototype object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'membership_count') and self.membership_count is not None:
            _dict['membership_count'] = self.membership_count
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceGroupManagerScheduledActionGroupPrototype object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceGroupManagerScheduledActionGroupPrototype') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceGroupManagerScheduledActionGroupPrototype') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceGroupManagerScheduledActionManager:
    """
    InstanceGroupManagerScheduledActionManager.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a InstanceGroupManagerScheduledActionManager object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['InstanceGroupManagerScheduledActionManagerAutoScale'])
        )
        raise Exception(msg)


class InstanceGroupManagerScheduledActionManagerPrototype:
    """
    InstanceGroupManagerScheduledActionManagerPrototype.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a InstanceGroupManagerScheduledActionManagerPrototype object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['InstanceGroupManagerScheduledActionManagerPrototypeAutoScalePrototype'])
        )
        raise Exception(msg)


class InstanceGroupMembership:
    """
    InstanceGroupMembership.

    :attr datetime created_at: The date and time that the instance group manager
          policy was created.
    :attr bool delete_instance_on_membership_delete: If set to true, when deleting
          the membership the instance will also be deleted.
    :attr str href: The URL for this instance group membership.
    :attr str id: The unique identifier for this instance group membership.
    :attr InstanceReference instance:
    :attr InstanceTemplateReference instance_template:
    :attr str name: The name for this instance group membership. The name is unique
          across all memberships for the instance group.
    :attr LoadBalancerPoolMemberReference pool_member: (optional)
    :attr str status: The status of the instance group membership
          - `deleting`: Membership is deleting dependent resources
          - `failed`: Membership was unable to maintain dependent resources
          - `healthy`: Membership is active and serving in the group
          - `pending`: Membership is waiting for dependent resources
          - `unhealthy`: Membership has unhealthy dependent resources.
    :attr datetime updated_at: The date and time that the instance group membership
          was updated.
    """

    def __init__(
        self,
        created_at: datetime,
        delete_instance_on_membership_delete: bool,
        href: str,
        id: str,
        instance: 'InstanceReference',
        instance_template: 'InstanceTemplateReference',
        name: str,
        status: str,
        updated_at: datetime,
        *,
        pool_member: 'LoadBalancerPoolMemberReference' = None,
    ) -> None:
        """
        Initialize a InstanceGroupMembership object.

        :param datetime created_at: The date and time that the instance group
               manager policy was created.
        :param bool delete_instance_on_membership_delete: If set to true, when
               deleting the membership the instance will also be deleted.
        :param str href: The URL for this instance group membership.
        :param str id: The unique identifier for this instance group membership.
        :param InstanceReference instance:
        :param InstanceTemplateReference instance_template:
        :param str name: The name for this instance group membership. The name is
               unique across all memberships for the instance group.
        :param str status: The status of the instance group membership
               - `deleting`: Membership is deleting dependent resources
               - `failed`: Membership was unable to maintain dependent resources
               - `healthy`: Membership is active and serving in the group
               - `pending`: Membership is waiting for dependent resources
               - `unhealthy`: Membership has unhealthy dependent resources.
        :param datetime updated_at: The date and time that the instance group
               membership was updated.
        :param LoadBalancerPoolMemberReference pool_member: (optional)
        """
        self.created_at = created_at
        self.delete_instance_on_membership_delete = delete_instance_on_membership_delete
        self.href = href
        self.id = id
        self.instance = instance
        self.instance_template = instance_template
        self.name = name
        self.pool_member = pool_member
        self.status = status
        self.updated_at = updated_at

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceGroupMembership':
        """Initialize a InstanceGroupMembership object from a json dictionary."""
        args = {}
        if 'created_at' in _dict:
            args['created_at'] = string_to_datetime(_dict.get('created_at'))
        else:
            raise ValueError('Required property \'created_at\' not present in InstanceGroupMembership JSON')
        if 'delete_instance_on_membership_delete' in _dict:
            args['delete_instance_on_membership_delete'] = _dict.get('delete_instance_on_membership_delete')
        else:
            raise ValueError('Required property \'delete_instance_on_membership_delete\' not present in InstanceGroupMembership JSON')
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in InstanceGroupMembership JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in InstanceGroupMembership JSON')
        if 'instance' in _dict:
            args['instance'] = InstanceReference.from_dict(_dict.get('instance'))
        else:
            raise ValueError('Required property \'instance\' not present in InstanceGroupMembership JSON')
        if 'instance_template' in _dict:
            args['instance_template'] = InstanceTemplateReference.from_dict(_dict.get('instance_template'))
        else:
            raise ValueError('Required property \'instance_template\' not present in InstanceGroupMembership JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in InstanceGroupMembership JSON')
        if 'pool_member' in _dict:
            args['pool_member'] = LoadBalancerPoolMemberReference.from_dict(_dict.get('pool_member'))
        if 'status' in _dict:
            args['status'] = _dict.get('status')
        else:
            raise ValueError('Required property \'status\' not present in InstanceGroupMembership JSON')
        if 'updated_at' in _dict:
            args['updated_at'] = string_to_datetime(_dict.get('updated_at'))
        else:
            raise ValueError('Required property \'updated_at\' not present in InstanceGroupMembership JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceGroupMembership object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'created_at') and self.created_at is not None:
            _dict['created_at'] = datetime_to_string(self.created_at)
        if hasattr(self, 'delete_instance_on_membership_delete') and self.delete_instance_on_membership_delete is not None:
            _dict['delete_instance_on_membership_delete'] = self.delete_instance_on_membership_delete
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'instance') and self.instance is not None:
            if isinstance(self.instance, dict):
                _dict['instance'] = self.instance
            else:
                _dict['instance'] = self.instance.to_dict()
        if hasattr(self, 'instance_template') and self.instance_template is not None:
            if isinstance(self.instance_template, dict):
                _dict['instance_template'] = self.instance_template
            else:
                _dict['instance_template'] = self.instance_template.to_dict()
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'pool_member') and self.pool_member is not None:
            if isinstance(self.pool_member, dict):
                _dict['pool_member'] = self.pool_member
            else:
                _dict['pool_member'] = self.pool_member.to_dict()
        if hasattr(self, 'status') and self.status is not None:
            _dict['status'] = self.status
        if hasattr(self, 'updated_at') and self.updated_at is not None:
            _dict['updated_at'] = datetime_to_string(self.updated_at)
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceGroupMembership object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceGroupMembership') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceGroupMembership') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class StatusEnum(str, Enum):
        """
        The status of the instance group membership
        - `deleting`: Membership is deleting dependent resources
        - `failed`: Membership was unable to maintain dependent resources
        - `healthy`: Membership is active and serving in the group
        - `pending`: Membership is waiting for dependent resources
        - `unhealthy`: Membership has unhealthy dependent resources.
        """

        DELETING = 'deleting'
        FAILED = 'failed'
        HEALTHY = 'healthy'
        PENDING = 'pending'
        UNHEALTHY = 'unhealthy'



class InstanceGroupMembershipCollection:
    """
    InstanceGroupMembershipCollection.

    :attr InstanceGroupMembershipCollectionFirst first: A link to the first page of
          resources.
    :attr int limit: The maximum number of resources that can be returned by the
          request.
    :attr List[InstanceGroupMembership] memberships: Collection of instance group
          memberships.
    :attr InstanceGroupMembershipCollectionNext next: (optional) A link to the next
          page of resources. This property is present for all pages
          except the last page.
    :attr int total_count: The total number of resources across all pages.
    """

    def __init__(
        self,
        first: 'InstanceGroupMembershipCollectionFirst',
        limit: int,
        memberships: List['InstanceGroupMembership'],
        total_count: int,
        *,
        next: 'InstanceGroupMembershipCollectionNext' = None,
    ) -> None:
        """
        Initialize a InstanceGroupMembershipCollection object.

        :param InstanceGroupMembershipCollectionFirst first: A link to the first
               page of resources.
        :param int limit: The maximum number of resources that can be returned by
               the request.
        :param List[InstanceGroupMembership] memberships: Collection of instance
               group memberships.
        :param int total_count: The total number of resources across all pages.
        :param InstanceGroupMembershipCollectionNext next: (optional) A link to the
               next page of resources. This property is present for all pages
               except the last page.
        """
        self.first = first
        self.limit = limit
        self.memberships = memberships
        self.next = next
        self.total_count = total_count

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceGroupMembershipCollection':
        """Initialize a InstanceGroupMembershipCollection object from a json dictionary."""
        args = {}
        if 'first' in _dict:
            args['first'] = InstanceGroupMembershipCollectionFirst.from_dict(_dict.get('first'))
        else:
            raise ValueError('Required property \'first\' not present in InstanceGroupMembershipCollection JSON')
        if 'limit' in _dict:
            args['limit'] = _dict.get('limit')
        else:
            raise ValueError('Required property \'limit\' not present in InstanceGroupMembershipCollection JSON')
        if 'memberships' in _dict:
            args['memberships'] = [InstanceGroupMembership.from_dict(v) for v in _dict.get('memberships')]
        else:
            raise ValueError('Required property \'memberships\' not present in InstanceGroupMembershipCollection JSON')
        if 'next' in _dict:
            args['next'] = InstanceGroupMembershipCollectionNext.from_dict(_dict.get('next'))
        if 'total_count' in _dict:
            args['total_count'] = _dict.get('total_count')
        else:
            raise ValueError('Required property \'total_count\' not present in InstanceGroupMembershipCollection JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceGroupMembershipCollection object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'first') and self.first is not None:
            if isinstance(self.first, dict):
                _dict['first'] = self.first
            else:
                _dict['first'] = self.first.to_dict()
        if hasattr(self, 'limit') and self.limit is not None:
            _dict['limit'] = self.limit
        if hasattr(self, 'memberships') and self.memberships is not None:
            memberships_list = []
            for v in self.memberships:
                if isinstance(v, dict):
                    memberships_list.append(v)
                else:
                    memberships_list.append(v.to_dict())
            _dict['memberships'] = memberships_list
        if hasattr(self, 'next') and self.next is not None:
            if isinstance(self.next, dict):
                _dict['next'] = self.next
            else:
                _dict['next'] = self.next.to_dict()
        if hasattr(self, 'total_count') and self.total_count is not None:
            _dict['total_count'] = self.total_count
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceGroupMembershipCollection object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceGroupMembershipCollection') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceGroupMembershipCollection') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceGroupMembershipCollectionFirst:
    """
    A link to the first page of resources.

    :attr str href: The URL for a page of resources.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a InstanceGroupMembershipCollectionFirst object.

        :param str href: The URL for a page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceGroupMembershipCollectionFirst':
        """Initialize a InstanceGroupMembershipCollectionFirst object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in InstanceGroupMembershipCollectionFirst JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceGroupMembershipCollectionFirst object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceGroupMembershipCollectionFirst object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceGroupMembershipCollectionFirst') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceGroupMembershipCollectionFirst') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceGroupMembershipCollectionNext:
    """
    A link to the next page of resources. This property is present for all pages except
    the last page.

    :attr str href: The URL for a page of resources.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a InstanceGroupMembershipCollectionNext object.

        :param str href: The URL for a page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceGroupMembershipCollectionNext':
        """Initialize a InstanceGroupMembershipCollectionNext object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in InstanceGroupMembershipCollectionNext JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceGroupMembershipCollectionNext object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceGroupMembershipCollectionNext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceGroupMembershipCollectionNext') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceGroupMembershipCollectionNext') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceGroupMembershipPatch:
    """
    InstanceGroupMembershipPatch.

    :attr str name: (optional) The name for this instance group membership. The name
          must not be used by another membership for the instance group manager.
    """

    def __init__(
        self,
        *,
        name: str = None,
    ) -> None:
        """
        Initialize a InstanceGroupMembershipPatch object.

        :param str name: (optional) The name for this instance group membership.
               The name must not be used by another membership for the instance group
               manager.
        """
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceGroupMembershipPatch':
        """Initialize a InstanceGroupMembershipPatch object from a json dictionary."""
        args = {}
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceGroupMembershipPatch object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceGroupMembershipPatch object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceGroupMembershipPatch') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceGroupMembershipPatch') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceGroupPatch:
    """
    To add or update load balancer specification for an instance group the
    `membership_count` must first be set to 0.

    :attr int application_port: (optional) The port to use for new load balancer
          pool members created by this instance group.
          This property must be set if and only if `load_balancer_pool` has been set.
    :attr InstanceTemplateIdentity instance_template: (optional) Instance template
          to use when creating new instances.
          Instance groups are not compatible with instance templates that specify `true`
          for
          `default_trusted_profile.auto_link`.
    :attr LoadBalancerIdentity load_balancer: (optional) The load balancer
          associated with `load_balancer_pool`.
          The load balancer must have `instance_groups_supported` set to `true`.
          This property must be set if and only if `load_balancer_pool` has been set.
    :attr LoadBalancerPoolIdentity load_balancer_pool: (optional) If specified, this
          instance group will manage the load balancer pool. A pool member
          will be created for each instance created by this group.  The specified load
          balancer pool must not be used by another instance group in the VPC.
          If set, `load_balancer` and `application_port` must also be set.
    :attr int membership_count: (optional) The number of instances in the instance
          group.
    :attr str name: (optional) The name for this instance group. The name must not
          be used by another instance group in the region.
    :attr List[SubnetIdentity] subnets: (optional) The subnets to use when creating
          new instances.
    """

    def __init__(
        self,
        *,
        application_port: int = None,
        instance_template: 'InstanceTemplateIdentity' = None,
        load_balancer: 'LoadBalancerIdentity' = None,
        load_balancer_pool: 'LoadBalancerPoolIdentity' = None,
        membership_count: int = None,
        name: str = None,
        subnets: List['SubnetIdentity'] = None,
    ) -> None:
        """
        Initialize a InstanceGroupPatch object.

        :param int application_port: (optional) The port to use for new load
               balancer pool members created by this instance group.
               This property must be set if and only if `load_balancer_pool` has been set.
        :param InstanceTemplateIdentity instance_template: (optional) Instance
               template to use when creating new instances.
               Instance groups are not compatible with instance templates that specify
               `true` for
               `default_trusted_profile.auto_link`.
        :param LoadBalancerIdentity load_balancer: (optional) The load balancer
               associated with `load_balancer_pool`.
               The load balancer must have `instance_groups_supported` set to `true`.
               This property must be set if and only if `load_balancer_pool` has been set.
        :param LoadBalancerPoolIdentity load_balancer_pool: (optional) If
               specified, this instance group will manage the load balancer pool. A pool
               member
               will be created for each instance created by this group.  The specified
               load
               balancer pool must not be used by another instance group in the VPC.
               If set, `load_balancer` and `application_port` must also be set.
        :param int membership_count: (optional) The number of instances in the
               instance group.
        :param str name: (optional) The name for this instance group. The name must
               not be used by another instance group in the region.
        :param List[SubnetIdentity] subnets: (optional) The subnets to use when
               creating new instances.
        """
        self.application_port = application_port
        self.instance_template = instance_template
        self.load_balancer = load_balancer
        self.load_balancer_pool = load_balancer_pool
        self.membership_count = membership_count
        self.name = name
        self.subnets = subnets

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceGroupPatch':
        """Initialize a InstanceGroupPatch object from a json dictionary."""
        args = {}
        if 'application_port' in _dict:
            args['application_port'] = _dict.get('application_port')
        if 'instance_template' in _dict:
            args['instance_template'] = _dict.get('instance_template')
        if 'load_balancer' in _dict:
            args['load_balancer'] = _dict.get('load_balancer')
        if 'load_balancer_pool' in _dict:
            args['load_balancer_pool'] = _dict.get('load_balancer_pool')
        if 'membership_count' in _dict:
            args['membership_count'] = _dict.get('membership_count')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        if 'subnets' in _dict:
            args['subnets'] = _dict.get('subnets')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceGroupPatch object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'application_port') and self.application_port is not None:
            _dict['application_port'] = self.application_port
        if hasattr(self, 'instance_template') and self.instance_template is not None:
            if isinstance(self.instance_template, dict):
                _dict['instance_template'] = self.instance_template
            else:
                _dict['instance_template'] = self.instance_template.to_dict()
        if hasattr(self, 'load_balancer') and self.load_balancer is not None:
            if isinstance(self.load_balancer, dict):
                _dict['load_balancer'] = self.load_balancer
            else:
                _dict['load_balancer'] = self.load_balancer.to_dict()
        if hasattr(self, 'load_balancer_pool') and self.load_balancer_pool is not None:
            if isinstance(self.load_balancer_pool, dict):
                _dict['load_balancer_pool'] = self.load_balancer_pool
            else:
                _dict['load_balancer_pool'] = self.load_balancer_pool.to_dict()
        if hasattr(self, 'membership_count') and self.membership_count is not None:
            _dict['membership_count'] = self.membership_count
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'subnets') and self.subnets is not None:
            subnets_list = []
            for v in self.subnets:
                if isinstance(v, dict):
                    subnets_list.append(v)
                else:
                    subnets_list.append(v.to_dict())
            _dict['subnets'] = subnets_list
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceGroupPatch object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceGroupPatch') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceGroupPatch') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceGroupReference:
    """
    InstanceGroupReference.

    :attr str crn: The CRN for this instance group.
    :attr InstanceGroupReferenceDeleted deleted: (optional) If present, this
          property indicates the referenced resource has been deleted, and provides
          some supplementary information.
    :attr str href: The URL for this instance group.
    :attr str id: The unique identifier for this instance group.
    :attr str name: The name for this instance group. The name is unique across all
          instance groups in the region.
    """

    def __init__(
        self,
        crn: str,
        href: str,
        id: str,
        name: str,
        *,
        deleted: 'InstanceGroupReferenceDeleted' = None,
    ) -> None:
        """
        Initialize a InstanceGroupReference object.

        :param str crn: The CRN for this instance group.
        :param str href: The URL for this instance group.
        :param str id: The unique identifier for this instance group.
        :param str name: The name for this instance group. The name is unique
               across all instance groups in the region.
        :param InstanceGroupReferenceDeleted deleted: (optional) If present, this
               property indicates the referenced resource has been deleted, and provides
               some supplementary information.
        """
        self.crn = crn
        self.deleted = deleted
        self.href = href
        self.id = id
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceGroupReference':
        """Initialize a InstanceGroupReference object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError('Required property \'crn\' not present in InstanceGroupReference JSON')
        if 'deleted' in _dict:
            args['deleted'] = InstanceGroupReferenceDeleted.from_dict(_dict.get('deleted'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in InstanceGroupReference JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in InstanceGroupReference JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in InstanceGroupReference JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceGroupReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'deleted') and self.deleted is not None:
            if isinstance(self.deleted, dict):
                _dict['deleted'] = self.deleted
            else:
                _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceGroupReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceGroupReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceGroupReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceGroupReferenceDeleted:
    """
    If present, this property indicates the referenced resource has been deleted, and
    provides some supplementary information.

    :attr str more_info: Link to documentation about deleted resources.
    """

    def __init__(
        self,
        more_info: str,
    ) -> None:
        """
        Initialize a InstanceGroupReferenceDeleted object.

        :param str more_info: Link to documentation about deleted resources.
        """
        self.more_info = more_info

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceGroupReferenceDeleted':
        """Initialize a InstanceGroupReferenceDeleted object from a json dictionary."""
        args = {}
        if 'more_info' in _dict:
            args['more_info'] = _dict.get('more_info')
        else:
            raise ValueError('Required property \'more_info\' not present in InstanceGroupReferenceDeleted JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceGroupReferenceDeleted object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'more_info') and self.more_info is not None:
            _dict['more_info'] = self.more_info
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceGroupReferenceDeleted object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceGroupReferenceDeleted') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceGroupReferenceDeleted') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceInitialization:
    """
    InstanceInitialization.

    :attr InstanceInitializationDefaultTrustedProfile default_trusted_profile:
          (optional) The default trusted profile configuration specified at virtual server
          instance
          creation. If absent, no default trusted profile was specified.
    :attr List[KeyReference] keys: The public SSH keys used at instance
          initialization.
    :attr InstanceInitializationPassword password: (optional)
    """

    def __init__(
        self,
        keys: List['KeyReference'],
        *,
        default_trusted_profile: 'InstanceInitializationDefaultTrustedProfile' = None,
        password: 'InstanceInitializationPassword' = None,
    ) -> None:
        """
        Initialize a InstanceInitialization object.

        :param List[KeyReference] keys: The public SSH keys used at instance
               initialization.
        :param InstanceInitializationDefaultTrustedProfile default_trusted_profile:
               (optional) The default trusted profile configuration specified at virtual
               server instance
               creation. If absent, no default trusted profile was specified.
        :param InstanceInitializationPassword password: (optional)
        """
        self.default_trusted_profile = default_trusted_profile
        self.keys = keys
        self.password = password

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceInitialization':
        """Initialize a InstanceInitialization object from a json dictionary."""
        args = {}
        if 'default_trusted_profile' in _dict:
            args['default_trusted_profile'] = InstanceInitializationDefaultTrustedProfile.from_dict(_dict.get('default_trusted_profile'))
        if 'keys' in _dict:
            args['keys'] = [KeyReference.from_dict(v) for v in _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, 'default_trusted_profile') and self.default_trusted_profile is not None:
            if isinstance(self.default_trusted_profile, dict):
                _dict['default_trusted_profile'] = self.default_trusted_profile
            else:
                _dict['default_trusted_profile'] = self.default_trusted_profile.to_dict()
        if hasattr(self, 'keys') and self.keys is not None:
            keys_list = []
            for v in self.keys:
                if isinstance(v, dict):
                    keys_list.append(v)
                else:
                    keys_list.append(v.to_dict())
            _dict['keys'] = keys_list
        if hasattr(self, 'password') and self.password is not None:
            if isinstance(self.password, dict):
                _dict['password'] = self.password
            else:
                _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 InstanceInitializationDefaultTrustedProfile:
    """
    InstanceInitializationDefaultTrustedProfile.

    :attr bool auto_link: If set to `true`, the system created a link to the
          specified `target` trusted profile during instance creation. Regardless of
          whether a link was created by the system or manually using the IAM Identity
          service, it will be automatically deleted when the instance is deleted.
    :attr TrustedProfileReference target: The default IAM trusted profile to use for
          this virtual server instance.
    """

    def __init__(
        self,
        auto_link: bool,
        target: 'TrustedProfileReference',
    ) -> None:
        """
        Initialize a InstanceInitializationDefaultTrustedProfile object.

        :param bool auto_link: If set to `true`, the system created a link to the
               specified `target` trusted profile during instance creation. Regardless of
               whether a link was created by the system or manually using the IAM Identity
               service, it will be automatically deleted when the instance is deleted.
        :param TrustedProfileReference target: The default IAM trusted profile to
               use for this virtual server instance.
        """
        self.auto_link = auto_link
        self.target = target

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceInitializationDefaultTrustedProfile':
        """Initialize a InstanceInitializationDefaultTrustedProfile object from a json dictionary."""
        args = {}
        if 'auto_link' in _dict:
            args['auto_link'] = _dict.get('auto_link')
        else:
            raise ValueError('Required property \'auto_link\' not present in InstanceInitializationDefaultTrustedProfile JSON')
        if 'target' in _dict:
            args['target'] = TrustedProfileReference.from_dict(_dict.get('target'))
        else:
            raise ValueError('Required property \'target\' not present in InstanceInitializationDefaultTrustedProfile JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceInitializationDefaultTrustedProfile object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'auto_link') and self.auto_link is not None:
            _dict['auto_link'] = self.auto_link
        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 InstanceInitializationDefaultTrustedProfile object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceInitializationDefaultTrustedProfile') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceInitializationDefaultTrustedProfile') -> 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 KeyIdentityByFingerprint encryption_key: The public SSH key used to
          encrypt the administrator password.
    """

    def __init__(
        self,
        encrypted_password: bytes,
        encryption_key: 'KeyIdentityByFingerprint',
    ) -> None:
        """
        Initialize a InstanceInitializationPassword object.

        :param bytes encrypted_password: The administrator password at
               initialization, encrypted using `encryption_key`, and returned
               base64-encoded.
        :param KeyIdentityByFingerprint encryption_key: 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'] = KeyIdentityByFingerprint.from_dict(_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 InstanceLifecycleReason:
    """
    InstanceLifecycleReason.

    :attr str code: A snake case string succinctly identifying the reason for this
          lifecycle state.
    :attr str message: An explanation of the reason for this lifecycle state.
    :attr str more_info: (optional) Link to documentation about the reason for this
          lifecycle state.
    """

    def __init__(
        self,
        code: str,
        message: str,
        *,
        more_info: str = None,
    ) -> None:
        """
        Initialize a InstanceLifecycleReason object.

        :param str code: A snake case string succinctly identifying the reason for
               this lifecycle state.
        :param str message: An explanation of the reason for this lifecycle state.
        :param str more_info: (optional) Link to documentation about the reason for
               this lifecycle state.
        """
        self.code = code
        self.message = message
        self.more_info = more_info

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceLifecycleReason':
        """Initialize a InstanceLifecycleReason object from a json dictionary."""
        args = {}
        if 'code' in _dict:
            args['code'] = _dict.get('code')
        else:
            raise ValueError('Required property \'code\' not present in InstanceLifecycleReason JSON')
        if 'message' in _dict:
            args['message'] = _dict.get('message')
        else:
            raise ValueError('Required property \'message\' not present in InstanceLifecycleReason JSON')
        if 'more_info' in _dict:
            args['more_info'] = _dict.get('more_info')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceLifecycleReason object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'code') and self.code is not None:
            _dict['code'] = self.code
        if hasattr(self, 'message') and self.message is not None:
            _dict['message'] = self.message
        if hasattr(self, 'more_info') and self.more_info is not None:
            _dict['more_info'] = self.more_info
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceLifecycleReason object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceLifecycleReason') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceLifecycleReason') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class CodeEnum(str, Enum):
        """
        A snake case string succinctly identifying the reason for this lifecycle state.
        """

        RESOURCE_SUSPENDED_BY_PROVIDER = 'resource_suspended_by_provider'



class InstanceMetadataService:
    """
    The metadata service configuration.

    :attr bool enabled: Indicates whether the metadata service endpoint is available
          to the virtual server instance.
    :attr str protocol: The communication protocol to use for the metadata service
          endpoint. Applies only when the metadata service is enabled.
          - `http`: HTTP protocol (unencrypted)
          - `https`: HTTP Secure protocol.
    :attr int response_hop_limit: The hop limit (IP time to live) for IP response
          packets from the metadata service. Applies only when the metadata service is
          enabled.
    """

    def __init__(
        self,
        enabled: bool,
        protocol: str,
        response_hop_limit: int,
    ) -> None:
        """
        Initialize a InstanceMetadataService object.

        :param bool enabled: Indicates whether the metadata service endpoint is
               available to the virtual server instance.
        :param str protocol: The communication protocol to use for the metadata
               service endpoint. Applies only when the metadata service is enabled.
               - `http`: HTTP protocol (unencrypted)
               - `https`: HTTP Secure protocol.
        :param int response_hop_limit: The hop limit (IP time to live) for IP
               response packets from the metadata service. Applies only when the metadata
               service is enabled.
        """
        self.enabled = enabled
        self.protocol = protocol
        self.response_hop_limit = response_hop_limit

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceMetadataService':
        """Initialize a InstanceMetadataService object from a json dictionary."""
        args = {}
        if 'enabled' in _dict:
            args['enabled'] = _dict.get('enabled')
        else:
            raise ValueError('Required property \'enabled\' not present in InstanceMetadataService JSON')
        if 'protocol' in _dict:
            args['protocol'] = _dict.get('protocol')
        else:
            raise ValueError('Required property \'protocol\' not present in InstanceMetadataService JSON')
        if 'response_hop_limit' in _dict:
            args['response_hop_limit'] = _dict.get('response_hop_limit')
        else:
            raise ValueError('Required property \'response_hop_limit\' not present in InstanceMetadataService JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceMetadataService object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'enabled') and self.enabled is not None:
            _dict['enabled'] = self.enabled
        if hasattr(self, 'protocol') and self.protocol is not None:
            _dict['protocol'] = self.protocol
        if hasattr(self, 'response_hop_limit') and self.response_hop_limit is not None:
            _dict['response_hop_limit'] = self.response_hop_limit
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceMetadataService object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceMetadataService') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceMetadataService') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ProtocolEnum(str, Enum):
        """
        The communication protocol to use for the metadata service endpoint. Applies only
        when the metadata service is enabled.
        - `http`: HTTP protocol (unencrypted)
        - `https`: HTTP Secure protocol.
        """

        HTTP = 'http'
        HTTPS = 'https'



class InstanceMetadataServicePatch:
    """
    The metadata service configuration.

    :attr bool enabled: (optional) Indicates whether the metadata service endpoint
          will be available to the virtual server instance.
    :attr str protocol: (optional) The communication protocol to use for the
          metadata service endpoint. Applies only when the metadata service is enabled.
          - `http`: HTTP protocol (unencrypted)
          - `https`: HTTP Secure protocol.
    :attr int response_hop_limit: (optional) The hop limit (IP time to live) for IP
          response packets from the metadata service. Applies only when the metadata
          service is enabled.
    """

    def __init__(
        self,
        *,
        enabled: bool = None,
        protocol: str = None,
        response_hop_limit: int = None,
    ) -> None:
        """
        Initialize a InstanceMetadataServicePatch object.

        :param bool enabled: (optional) Indicates whether the metadata service
               endpoint will be available to the virtual server instance.
        :param str protocol: (optional) The communication protocol to use for the
               metadata service endpoint. Applies only when the metadata service is
               enabled.
               - `http`: HTTP protocol (unencrypted)
               - `https`: HTTP Secure protocol.
        :param int response_hop_limit: (optional) The hop limit (IP time to live)
               for IP response packets from the metadata service. Applies only when the
               metadata service is enabled.
        """
        self.enabled = enabled
        self.protocol = protocol
        self.response_hop_limit = response_hop_limit

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceMetadataServicePatch':
        """Initialize a InstanceMetadataServicePatch object from a json dictionary."""
        args = {}
        if 'enabled' in _dict:
            args['enabled'] = _dict.get('enabled')
        if 'protocol' in _dict:
            args['protocol'] = _dict.get('protocol')
        if 'response_hop_limit' in _dict:
            args['response_hop_limit'] = _dict.get('response_hop_limit')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceMetadataServicePatch object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'enabled') and self.enabled is not None:
            _dict['enabled'] = self.enabled
        if hasattr(self, 'protocol') and self.protocol is not None:
            _dict['protocol'] = self.protocol
        if hasattr(self, 'response_hop_limit') and self.response_hop_limit is not None:
            _dict['response_hop_limit'] = self.response_hop_limit
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceMetadataServicePatch object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceMetadataServicePatch') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceMetadataServicePatch') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ProtocolEnum(str, Enum):
        """
        The communication protocol to use for the metadata service endpoint. Applies only
        when the metadata service is enabled.
        - `http`: HTTP protocol (unencrypted)
        - `https`: HTTP Secure protocol.
        """

        HTTP = 'http'
        HTTPS = 'https'



class InstanceMetadataServicePrototype:
    """
    The metadata service configuration.

    :attr bool enabled: (optional) Indicates whether the metadata service endpoint
          will be available to the virtual server instance.
    :attr str protocol: (optional) The communication protocol to use for the
          metadata service endpoint. Applies only when the metadata service is enabled.
          - `http`: HTTP protocol (unencrypted)
          - `https`: HTTP Secure protocol.
    :attr int response_hop_limit: (optional) The hop limit (IP time to live) for IP
          response packets from the metadata service. Applies only when the metadata
          service is enabled.
    """

    def __init__(
        self,
        *,
        enabled: bool = None,
        protocol: str = None,
        response_hop_limit: int = None,
    ) -> None:
        """
        Initialize a InstanceMetadataServicePrototype object.

        :param bool enabled: (optional) Indicates whether the metadata service
               endpoint will be available to the virtual server instance.
        :param str protocol: (optional) The communication protocol to use for the
               metadata service endpoint. Applies only when the metadata service is
               enabled.
               - `http`: HTTP protocol (unencrypted)
               - `https`: HTTP Secure protocol.
        :param int response_hop_limit: (optional) The hop limit (IP time to live)
               for IP response packets from the metadata service. Applies only when the
               metadata service is enabled.
        """
        self.enabled = enabled
        self.protocol = protocol
        self.response_hop_limit = response_hop_limit

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceMetadataServicePrototype':
        """Initialize a InstanceMetadataServicePrototype object from a json dictionary."""
        args = {}
        if 'enabled' in _dict:
            args['enabled'] = _dict.get('enabled')
        if 'protocol' in _dict:
            args['protocol'] = _dict.get('protocol')
        if 'response_hop_limit' in _dict:
            args['response_hop_limit'] = _dict.get('response_hop_limit')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceMetadataServicePrototype object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'enabled') and self.enabled is not None:
            _dict['enabled'] = self.enabled
        if hasattr(self, 'protocol') and self.protocol is not None:
            _dict['protocol'] = self.protocol
        if hasattr(self, 'response_hop_limit') and self.response_hop_limit is not None:
            _dict['response_hop_limit'] = self.response_hop_limit
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceMetadataServicePrototype object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceMetadataServicePrototype') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceMetadataServicePrototype') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ProtocolEnum(str, Enum):
        """
        The communication protocol to use for the metadata service endpoint. Applies only
        when the metadata service is enabled.
        - `http`: HTTP protocol (unencrypted)
        - `https`: HTTP Secure protocol.
        """

        HTTP = 'http'
        HTTPS = 'https'



class InstancePatch:
    """
    InstancePatch.

    :attr InstanceAvailabilityPolicyPatch availability_policy: (optional) The
          availability policy for this virtual server instance.
    :attr InstanceMetadataServicePatch metadata_service: (optional) The metadata
          service configuration.
    :attr str name: (optional) The name for this virtual server instance. The name
          must not be used by another virtual server instance in the region. Changing the
          name will not affect the system hostname.
    :attr InstancePlacementTargetPatch placement_target: (optional) The placement
          restrictions to use for the virtual server instance. For the placement
          restrictions to be changed, the instance `status` must be `stopping` or
          `stopped`.
    :attr InstancePatchProfile profile: (optional) The profile to use for this
          virtual server instance. For the profile to be changed,
          the instance `status` must be `stopping` or `stopped`. In addition, the
          requested
          profile must:
          - Have matching instance disk support. Any disks associated with the current
          profile
            will be deleted, and any disks associated with the requested profile will be
            created.
          - Be compatible with any `placement_target` constraints. For example, if the
            instance is placed on a dedicated host, the requested profile `family` must be
            the same as the dedicated host `family`.
          - Have the same `vcpu.architecture`.
          - Support the number of network interfaces the instance currently has.
    :attr int total_volume_bandwidth: (optional) The amount of bandwidth (in
          megabits per second) allocated exclusively to instance storage volumes. An
          increase in this value will result in a corresponding decrease to
          `total_network_bandwidth`.
    """

    def __init__(
        self,
        *,
        availability_policy: 'InstanceAvailabilityPolicyPatch' = None,
        metadata_service: 'InstanceMetadataServicePatch' = None,
        name: str = None,
        placement_target: 'InstancePlacementTargetPatch' = None,
        profile: 'InstancePatchProfile' = None,
        total_volume_bandwidth: int = None,
    ) -> None:
        """
        Initialize a InstancePatch object.

        :param InstanceAvailabilityPolicyPatch availability_policy: (optional) The
               availability policy for this virtual server instance.
        :param InstanceMetadataServicePatch metadata_service: (optional) The
               metadata service configuration.
        :param str name: (optional) The name for this virtual server instance. The
               name must not be used by another virtual server instance in the region.
               Changing the name will not affect the system hostname.
        :param InstancePlacementTargetPatch placement_target: (optional) The
               placement restrictions to use for the virtual server instance. For the
               placement
               restrictions to be changed, the instance `status` must be `stopping` or
               `stopped`.
        :param InstancePatchProfile profile: (optional) The profile to use for this
               virtual server instance. For the profile to be changed,
               the instance `status` must be `stopping` or `stopped`. In addition, the
               requested
               profile must:
               - Have matching instance disk support. Any disks associated with the
               current profile
                 will be deleted, and any disks associated with the requested profile will
               be
                 created.
               - Be compatible with any `placement_target` constraints. For example, if
               the
                 instance is placed on a dedicated host, the requested profile `family`
               must be
                 the same as the dedicated host `family`.
               - Have the same `vcpu.architecture`.
               - Support the number of network interfaces the instance currently has.
        :param int total_volume_bandwidth: (optional) The amount of bandwidth (in
               megabits per second) allocated exclusively to instance storage volumes. An
               increase in this value will result in a corresponding decrease to
               `total_network_bandwidth`.
        """
        self.availability_policy = availability_policy
        self.metadata_service = metadata_service
        self.name = name
        self.placement_target = placement_target
        self.profile = profile
        self.total_volume_bandwidth = total_volume_bandwidth

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstancePatch':
        """Initialize a InstancePatch object from a json dictionary."""
        args = {}
        if 'availability_policy' in _dict:
            args['availability_policy'] = InstanceAvailabilityPolicyPatch.from_dict(_dict.get('availability_policy'))
        if 'metadata_service' in _dict:
            args['metadata_service'] = InstanceMetadataServicePatch.from_dict(_dict.get('metadata_service'))
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        if 'placement_target' in _dict:
            args['placement_target'] = _dict.get('placement_target')
        if 'profile' in _dict:
            args['profile'] = _dict.get('profile')
        if 'total_volume_bandwidth' in _dict:
            args['total_volume_bandwidth'] = _dict.get('total_volume_bandwidth')
        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, 'availability_policy') and self.availability_policy is not None:
            if isinstance(self.availability_policy, dict):
                _dict['availability_policy'] = self.availability_policy
            else:
                _dict['availability_policy'] = self.availability_policy.to_dict()
        if hasattr(self, 'metadata_service') and self.metadata_service is not None:
            if isinstance(self.metadata_service, dict):
                _dict['metadata_service'] = self.metadata_service
            else:
                _dict['metadata_service'] = self.metadata_service.to_dict()
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'placement_target') and self.placement_target is not None:
            if isinstance(self.placement_target, dict):
                _dict['placement_target'] = self.placement_target
            else:
                _dict['placement_target'] = self.placement_target.to_dict()
        if hasattr(self, 'profile') and self.profile is not None:
            if isinstance(self.profile, dict):
                _dict['profile'] = self.profile
            else:
                _dict['profile'] = self.profile.to_dict()
        if hasattr(self, 'total_volume_bandwidth') and self.total_volume_bandwidth is not None:
            _dict['total_volume_bandwidth'] = self.total_volume_bandwidth
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstancePatch object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstancePatch') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstancePatch') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstancePatchProfile:
    """
    The profile to use for this virtual server instance. For the profile to be changed,
    the instance `status` must be `stopping` or `stopped`. In addition, the requested
    profile must:
    - Have matching instance disk support. Any disks associated with the current profile
      will be deleted, and any disks associated with the requested profile will be
      created.
    - Be compatible with any `placement_target` constraints. For example, if the
      instance is placed on a dedicated host, the requested profile `family` must be
      the same as the dedicated host `family`.
    - Have the same `vcpu.architecture`.
    - Support the number of network interfaces the instance currently has.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a InstancePatchProfile object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['InstancePatchProfileInstanceProfileIdentityByName', 'InstancePatchProfileInstanceProfileIdentityByHref'])
        )
        raise Exception(msg)


class InstancePlacementTarget:
    """
    InstancePlacementTarget.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a InstancePlacementTarget object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['InstancePlacementTargetDedicatedHostGroupReference', 'InstancePlacementTargetDedicatedHostReference', 'InstancePlacementTargetPlacementGroupReference'])
        )
        raise Exception(msg)


class InstancePlacementTargetPatch:
    """
    InstancePlacementTargetPatch.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a InstancePlacementTargetPatch object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['InstancePlacementTargetPatchDedicatedHostIdentity', 'InstancePlacementTargetPatchDedicatedHostGroupIdentity'])
        )
        raise Exception(msg)


class InstancePlacementTargetPrototype:
    """
    InstancePlacementTargetPrototype.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a InstancePlacementTargetPrototype object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['InstancePlacementTargetPrototypeDedicatedHostIdentity', 'InstancePlacementTargetPrototypeDedicatedHostGroupIdentity', 'InstancePlacementTargetPrototypePlacementGroupIdentity'])
        )
        raise Exception(msg)


class InstanceProfile:
    """
    InstanceProfile.

    :attr InstanceProfileBandwidth bandwidth:
    :attr List[InstanceProfileDisk] disks: Collection of the instance profile's
          disks.
    :attr str family: The product family this virtual server instance profile
          belongs to.
    :attr InstanceProfileGPU gpu_count: (optional)
    :attr InstanceProfileGPUManufacturer gpu_manufacturer: (optional)
    :attr InstanceProfileGPUMemory gpu_memory: (optional)
    :attr InstanceProfileGPUModel gpu_model: (optional)
    :attr str href: The URL for this virtual server instance profile.
    :attr InstanceProfileMemory memory:
    :attr str name: The globally unique name for this virtual server instance
          profile.
    :attr InstanceProfileNetworkInterfaceCount network_interface_count:
    :attr InstanceProfileNUMACount numa_count: (optional)
    :attr InstanceProfileOSArchitecture os_architecture:
    :attr InstanceProfilePortSpeed port_speed:
    :attr str status: The status of the instance profile:
            - `previous`:  This instance profile is an older revision, but remains
          provisionable and
            usable.
            - `current`:  This profile is the latest revision.
          Note that revisions are indicated by the generation of an instance profile.
          Refer to the
          [profile naming conventions]
          (https://cloud.ibm.com/docs/vpc?topic=vpc-profiles&interface=ui#profiles-naming-rule)
          for information on how generations are defined within an instance profile.
          The enumerated values for this property are expected to expand in the future.
          When processing this property, check for and log unknown values. Optionally halt
          processing and surface the error, or bypass the profile on which the unexpected
          property value was encountered.
    :attr InstanceProfileVolumeBandwidth total_volume_bandwidth:
    :attr InstanceProfileVCPUArchitecture vcpu_architecture:
    :attr InstanceProfileVCPU vcpu_count:
    :attr InstanceProfileVCPUManufacturer vcpu_manufacturer:
    """

    def __init__(
        self,
        bandwidth: 'InstanceProfileBandwidth',
        disks: List['InstanceProfileDisk'],
        family: str,
        href: str,
        memory: 'InstanceProfileMemory',
        name: str,
        network_interface_count: 'InstanceProfileNetworkInterfaceCount',
        os_architecture: 'InstanceProfileOSArchitecture',
        port_speed: 'InstanceProfilePortSpeed',
        status: str,
        total_volume_bandwidth: 'InstanceProfileVolumeBandwidth',
        vcpu_architecture: 'InstanceProfileVCPUArchitecture',
        vcpu_count: 'InstanceProfileVCPU',
        vcpu_manufacturer: 'InstanceProfileVCPUManufacturer',
        *,
        gpu_count: 'InstanceProfileGPU' = None,
        gpu_manufacturer: 'InstanceProfileGPUManufacturer' = None,
        gpu_memory: 'InstanceProfileGPUMemory' = None,
        gpu_model: 'InstanceProfileGPUModel' = None,
        numa_count: 'InstanceProfileNUMACount' = None,
    ) -> None:
        """
        Initialize a InstanceProfile object.

        :param InstanceProfileBandwidth bandwidth:
        :param List[InstanceProfileDisk] disks: Collection of the instance
               profile's disks.
        :param str family: The product family this virtual server instance profile
               belongs to.
        :param str href: The URL for this virtual server instance profile.
        :param InstanceProfileMemory memory:
        :param str name: The globally unique name for this virtual server instance
               profile.
        :param InstanceProfileNetworkInterfaceCount network_interface_count:
        :param InstanceProfileOSArchitecture os_architecture:
        :param InstanceProfilePortSpeed port_speed:
        :param str status: The status of the instance profile:
                 - `previous`:  This instance profile is an older revision, but remains
               provisionable and
                 usable.
                 - `current`:  This profile is the latest revision.
               Note that revisions are indicated by the generation of an instance profile.
                Refer to the
               [profile naming conventions]
               (https://cloud.ibm.com/docs/vpc?topic=vpc-profiles&interface=ui#profiles-naming-rule)
               for information on how generations are defined within an instance profile.
               The enumerated values for this property are expected to expand in the
               future. When processing this property, check for and log unknown values.
               Optionally halt processing and surface the error, or bypass the profile on
               which the unexpected property value was encountered.
        :param InstanceProfileVolumeBandwidth total_volume_bandwidth:
        :param InstanceProfileVCPUArchitecture vcpu_architecture:
        :param InstanceProfileVCPU vcpu_count:
        :param InstanceProfileVCPUManufacturer vcpu_manufacturer:
        :param InstanceProfileGPU gpu_count: (optional)
        :param InstanceProfileGPUManufacturer gpu_manufacturer: (optional)
        :param InstanceProfileGPUMemory gpu_memory: (optional)
        :param InstanceProfileGPUModel gpu_model: (optional)
        :param InstanceProfileNUMACount numa_count: (optional)
        """
        self.bandwidth = bandwidth
        self.disks = disks
        self.family = family
        self.gpu_count = gpu_count
        self.gpu_manufacturer = gpu_manufacturer
        self.gpu_memory = gpu_memory
        self.gpu_model = gpu_model
        self.href = href
        self.memory = memory
        self.name = name
        self.network_interface_count = network_interface_count
        self.numa_count = numa_count
        self.os_architecture = os_architecture
        self.port_speed = port_speed
        self.status = status
        self.total_volume_bandwidth = total_volume_bandwidth
        self.vcpu_architecture = vcpu_architecture
        self.vcpu_count = vcpu_count
        self.vcpu_manufacturer = vcpu_manufacturer

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceProfile':
        """Initialize a InstanceProfile object from a json dictionary."""
        args = {}
        if 'bandwidth' in _dict:
            args['bandwidth'] = _dict.get('bandwidth')
        else:
            raise ValueError('Required property \'bandwidth\' not present in InstanceProfile JSON')
        if 'disks' in _dict:
            args['disks'] = [InstanceProfileDisk.from_dict(v) for v in _dict.get('disks')]
        else:
            raise ValueError('Required property \'disks\' not present in InstanceProfile JSON')
        if 'family' in _dict:
            args['family'] = _dict.get('family')
        else:
            raise ValueError('Required property \'family\' not present in InstanceProfile JSON')
        if 'gpu_count' in _dict:
            args['gpu_count'] = _dict.get('gpu_count')
        if 'gpu_manufacturer' in _dict:
            args['gpu_manufacturer'] = InstanceProfileGPUManufacturer.from_dict(_dict.get('gpu_manufacturer'))
        if 'gpu_memory' in _dict:
            args['gpu_memory'] = _dict.get('gpu_memory')
        if 'gpu_model' in _dict:
            args['gpu_model'] = InstanceProfileGPUModel.from_dict(_dict.get('gpu_model'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in InstanceProfile JSON')
        if 'memory' in _dict:
            args['memory'] = _dict.get('memory')
        else:
            raise ValueError('Required property \'memory\' not present in InstanceProfile JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in InstanceProfile JSON')
        if 'network_interface_count' in _dict:
            args['network_interface_count'] = _dict.get('network_interface_count')
        else:
            raise ValueError('Required property \'network_interface_count\' not present in InstanceProfile JSON')
        if 'numa_count' in _dict:
            args['numa_count'] = _dict.get('numa_count')
        if 'os_architecture' in _dict:
            args['os_architecture'] = InstanceProfileOSArchitecture.from_dict(_dict.get('os_architecture'))
        else:
            raise ValueError('Required property \'os_architecture\' not present in InstanceProfile JSON')
        if 'port_speed' in _dict:
            args['port_speed'] = _dict.get('port_speed')
        else:
            raise ValueError('Required property \'port_speed\' not present in InstanceProfile JSON')
        if 'status' in _dict:
            args['status'] = _dict.get('status')
        else:
            raise ValueError('Required property \'status\' not present in InstanceProfile JSON')
        if 'total_volume_bandwidth' in _dict:
            args['total_volume_bandwidth'] = _dict.get('total_volume_bandwidth')
        else:
            raise ValueError('Required property \'total_volume_bandwidth\' not present in InstanceProfile JSON')
        if 'vcpu_architecture' in _dict:
            args['vcpu_architecture'] = InstanceProfileVCPUArchitecture.from_dict(_dict.get('vcpu_architecture'))
        else:
            raise ValueError('Required property \'vcpu_architecture\' not present in InstanceProfile JSON')
        if 'vcpu_count' in _dict:
            args['vcpu_count'] = _dict.get('vcpu_count')
        else:
            raise ValueError('Required property \'vcpu_count\' not present in InstanceProfile JSON')
        if 'vcpu_manufacturer' in _dict:
            args['vcpu_manufacturer'] = InstanceProfileVCPUManufacturer.from_dict(_dict.get('vcpu_manufacturer'))
        else:
            raise ValueError('Required property \'vcpu_manufacturer\' not present in InstanceProfile JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceProfile object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'bandwidth') and self.bandwidth is not None:
            if isinstance(self.bandwidth, dict):
                _dict['bandwidth'] = self.bandwidth
            else:
                _dict['bandwidth'] = self.bandwidth.to_dict()
        if hasattr(self, 'disks') and self.disks is not None:
            disks_list = []
            for v in self.disks:
                if isinstance(v, dict):
                    disks_list.append(v)
                else:
                    disks_list.append(v.to_dict())
            _dict['disks'] = disks_list
        if hasattr(self, 'family') and self.family is not None:
            _dict['family'] = self.family
        if hasattr(self, 'gpu_count') and self.gpu_count is not None:
            if isinstance(self.gpu_count, dict):
                _dict['gpu_count'] = self.gpu_count
            else:
                _dict['gpu_count'] = self.gpu_count.to_dict()
        if hasattr(self, 'gpu_manufacturer') and self.gpu_manufacturer is not None:
            if isinstance(self.gpu_manufacturer, dict):
                _dict['gpu_manufacturer'] = self.gpu_manufacturer
            else:
                _dict['gpu_manufacturer'] = self.gpu_manufacturer.to_dict()
        if hasattr(self, 'gpu_memory') and self.gpu_memory is not None:
            if isinstance(self.gpu_memory, dict):
                _dict['gpu_memory'] = self.gpu_memory
            else:
                _dict['gpu_memory'] = self.gpu_memory.to_dict()
        if hasattr(self, 'gpu_model') and self.gpu_model is not None:
            if isinstance(self.gpu_model, dict):
                _dict['gpu_model'] = self.gpu_model
            else:
                _dict['gpu_model'] = self.gpu_model.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'memory') and self.memory is not None:
            if isinstance(self.memory, dict):
                _dict['memory'] = self.memory
            else:
                _dict['memory'] = self.memory.to_dict()
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'network_interface_count') and self.network_interface_count is not None:
            if isinstance(self.network_interface_count, dict):
                _dict['network_interface_count'] = self.network_interface_count
            else:
                _dict['network_interface_count'] = self.network_interface_count.to_dict()
        if hasattr(self, 'numa_count') and self.numa_count is not None:
            if isinstance(self.numa_count, dict):
                _dict['numa_count'] = self.numa_count
            else:
                _dict['numa_count'] = self.numa_count.to_dict()
        if hasattr(self, 'os_architecture') and self.os_architecture is not None:
            if isinstance(self.os_architecture, dict):
                _dict['os_architecture'] = self.os_architecture
            else:
                _dict['os_architecture'] = self.os_architecture.to_dict()
        if hasattr(self, 'port_speed') and self.port_speed is not None:
            if isinstance(self.port_speed, dict):
                _dict['port_speed'] = self.port_speed
            else:
                _dict['port_speed'] = self.port_speed.to_dict()
        if hasattr(self, 'status') and self.status is not None:
            _dict['status'] = self.status
        if hasattr(self, 'total_volume_bandwidth') and self.total_volume_bandwidth is not None:
            if isinstance(self.total_volume_bandwidth, dict):
                _dict['total_volume_bandwidth'] = self.total_volume_bandwidth
            else:
                _dict['total_volume_bandwidth'] = self.total_volume_bandwidth.to_dict()
        if hasattr(self, 'vcpu_architecture') and self.vcpu_architecture is not None:
            if isinstance(self.vcpu_architecture, dict):
                _dict['vcpu_architecture'] = self.vcpu_architecture
            else:
                _dict['vcpu_architecture'] = self.vcpu_architecture.to_dict()
        if hasattr(self, 'vcpu_count') and self.vcpu_count is not None:
            if isinstance(self.vcpu_count, dict):
                _dict['vcpu_count'] = self.vcpu_count
            else:
                _dict['vcpu_count'] = self.vcpu_count.to_dict()
        if hasattr(self, 'vcpu_manufacturer') and self.vcpu_manufacturer is not None:
            if isinstance(self.vcpu_manufacturer, dict):
                _dict['vcpu_manufacturer'] = self.vcpu_manufacturer
            else:
                _dict['vcpu_manufacturer'] = self.vcpu_manufacturer.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 StatusEnum(str, Enum):
        """
        The status of the instance profile:
          - `previous`:  This instance profile is an older revision, but remains
        provisionable and
          usable.
          - `current`:  This profile is the latest revision.
        Note that revisions are indicated by the generation of an instance profile.  Refer
        to the
        [profile naming conventions]
        (https://cloud.ibm.com/docs/vpc?topic=vpc-profiles&interface=ui#profiles-naming-rule)
        for information on how generations are defined within an instance profile.
        The enumerated values for this property are expected to expand in the future. When
        processing this property, check for and log unknown values. Optionally halt
        processing and surface the error, or bypass the profile on which the unexpected
        property value was encountered.
        """

        CURRENT = 'current'
        PREVIOUS = 'previous'



class InstanceProfileBandwidth:
    """
    InstanceProfileBandwidth.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a InstanceProfileBandwidth object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['InstanceProfileBandwidthFixed', 'InstanceProfileBandwidthRange', 'InstanceProfileBandwidthEnum', 'InstanceProfileBandwidthDependent'])
        )
        raise Exception(msg)


class InstanceProfileCollection:
    """
    InstanceProfileCollection.

    :attr List[InstanceProfile] profiles: Collection of virtual server instance
          profiles.
    """

    def __init__(
        self,
        profiles: List['InstanceProfile'],
    ) -> None:
        """
        Initialize a InstanceProfileCollection object.

        :param List[InstanceProfile] profiles: Collection of virtual server
               instance profiles.
        """
        self.profiles = profiles

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceProfileCollection':
        """Initialize a InstanceProfileCollection object from a json dictionary."""
        args = {}
        if 'profiles' in _dict:
            args['profiles'] = [InstanceProfile.from_dict(v) for v in _dict.get('profiles')]
        else:
            raise ValueError('Required property \'profiles\' not present in InstanceProfileCollection JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceProfileCollection object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'profiles') and self.profiles is not None:
            profiles_list = []
            for v in self.profiles:
                if isinstance(v, dict):
                    profiles_list.append(v)
                else:
                    profiles_list.append(v.to_dict())
            _dict['profiles'] = profiles_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 InstanceProfileCollection object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceProfileCollection') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceProfileCollection') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceProfileDisk:
    """
    Disks provided by this profile.

    :attr InstanceProfileDiskQuantity quantity:
    :attr InstanceProfileDiskSize size:
    :attr InstanceProfileDiskSupportedInterfaces supported_interface_types:
    """

    def __init__(
        self,
        quantity: 'InstanceProfileDiskQuantity',
        size: 'InstanceProfileDiskSize',
        supported_interface_types: 'InstanceProfileDiskSupportedInterfaces',
    ) -> None:
        """
        Initialize a InstanceProfileDisk object.

        :param InstanceProfileDiskQuantity quantity:
        :param InstanceProfileDiskSize size:
        :param InstanceProfileDiskSupportedInterfaces supported_interface_types:
        """
        self.quantity = quantity
        self.size = size
        self.supported_interface_types = supported_interface_types

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceProfileDisk':
        """Initialize a InstanceProfileDisk object from a json dictionary."""
        args = {}
        if 'quantity' in _dict:
            args['quantity'] = _dict.get('quantity')
        else:
            raise ValueError('Required property \'quantity\' not present in InstanceProfileDisk JSON')
        if 'size' in _dict:
            args['size'] = _dict.get('size')
        else:
            raise ValueError('Required property \'size\' not present in InstanceProfileDisk JSON')
        if 'supported_interface_types' in _dict:
            args['supported_interface_types'] = InstanceProfileDiskSupportedInterfaces.from_dict(_dict.get('supported_interface_types'))
        else:
            raise ValueError('Required property \'supported_interface_types\' not present in InstanceProfileDisk JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceProfileDisk object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'quantity') and self.quantity is not None:
            if isinstance(self.quantity, dict):
                _dict['quantity'] = self.quantity
            else:
                _dict['quantity'] = self.quantity.to_dict()
        if hasattr(self, 'size') and self.size is not None:
            if isinstance(self.size, dict):
                _dict['size'] = self.size
            else:
                _dict['size'] = self.size.to_dict()
        if hasattr(self, 'supported_interface_types') and self.supported_interface_types is not None:
            if isinstance(self.supported_interface_types, dict):
                _dict['supported_interface_types'] = self.supported_interface_types
            else:
                _dict['supported_interface_types'] = self.supported_interface_types.to_dict()
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceProfileDisk object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceProfileDisk') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceProfileDisk') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceProfileDiskQuantity:
    """
    InstanceProfileDiskQuantity.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a InstanceProfileDiskQuantity object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['InstanceProfileDiskQuantityFixed', 'InstanceProfileDiskQuantityRange', 'InstanceProfileDiskQuantityEnum', 'InstanceProfileDiskQuantityDependent'])
        )
        raise Exception(msg)


class InstanceProfileDiskSize:
    """
    InstanceProfileDiskSize.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a InstanceProfileDiskSize object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['InstanceProfileDiskSizeFixed', 'InstanceProfileDiskSizeRange', 'InstanceProfileDiskSizeEnum', 'InstanceProfileDiskSizeDependent'])
        )
        raise Exception(msg)


class InstanceProfileDiskSupportedInterfaces:
    """
    InstanceProfileDiskSupportedInterfaces.

    :attr str default: The disk interface used for attaching the disk.
          The enumerated values for this property are expected to expand in the future.
          When processing this property, check for and log unknown values. Optionally halt
          processing and surface the error, or bypass the resource on which the unexpected
          property value was encountered.
    :attr str type: The type for this profile field.
    :attr List[str] values: The supported disk interfaces used for attaching the
          disk.
    """

    def __init__(
        self,
        default: str,
        type: str,
        values: List[str],
    ) -> None:
        """
        Initialize a InstanceProfileDiskSupportedInterfaces object.

        :param str default: The disk interface used for attaching the disk.
               The enumerated values for this property are expected to expand in the
               future. When processing this property, check for and log unknown values.
               Optionally halt processing and surface the error, or bypass the resource on
               which the unexpected property value was encountered.
        :param str type: The type for this profile field.
        :param List[str] values: The supported disk interfaces used for attaching
               the disk.
        """
        self.default = default
        self.type = type
        self.values = values

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceProfileDiskSupportedInterfaces':
        """Initialize a InstanceProfileDiskSupportedInterfaces object from a json dictionary."""
        args = {}
        if 'default' in _dict:
            args['default'] = _dict.get('default')
        else:
            raise ValueError('Required property \'default\' not present in InstanceProfileDiskSupportedInterfaces JSON')
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in InstanceProfileDiskSupportedInterfaces JSON')
        if 'values' in _dict:
            args['values'] = _dict.get('values')
        else:
            raise ValueError('Required property \'values\' not present in InstanceProfileDiskSupportedInterfaces JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceProfileDiskSupportedInterfaces object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'default') and self.default is not None:
            _dict['default'] = self.default
        if hasattr(self, 'type') and self.type is not None:
            _dict['type'] = self.type
        if hasattr(self, 'values') and self.values is not None:
            _dict['values'] = self.values
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceProfileDiskSupportedInterfaces object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceProfileDiskSupportedInterfaces') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceProfileDiskSupportedInterfaces') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class DefaultEnum(str, Enum):
        """
        The disk interface used for attaching the disk.
        The enumerated values for this property are expected to expand in the future. When
        processing this property, check for and log unknown values. Optionally halt
        processing and surface the error, or bypass the resource on which the unexpected
        property value was encountered.
        """

        NVME = 'nvme'
        VIRTIO_BLK = 'virtio_blk'


    class TypeEnum(str, Enum):
        """
        The type for this profile field.
        """

        ENUM = 'enum'


    class ValuesEnum(str, Enum):
        """
        The disk interface used for attaching the disk.
        The enumerated values for this property are expected to expand in the future. When
        processing this property, check for and log unknown values. Optionally halt
        processing and surface the error, or bypass the resource on which the unexpected
        property value was encountered.
        """

        NVME = 'nvme'
        VIRTIO_BLK = 'virtio_blk'



class InstanceProfileGPU:
    """
    InstanceProfileGPU.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a InstanceProfileGPU object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['InstanceProfileGPUFixed', 'InstanceProfileGPURange', 'InstanceProfileGPUEnum', 'InstanceProfileGPUDependent'])
        )
        raise Exception(msg)


class InstanceProfileGPUManufacturer:
    """
    InstanceProfileGPUManufacturer.

    :attr str type: The type for this profile field.
    :attr List[str] values: The possible GPU manufacturer(s) for an instance with
          this profile.
    """

    def __init__(
        self,
        type: str,
        values: List[str],
    ) -> None:
        """
        Initialize a InstanceProfileGPUManufacturer object.

        :param str type: The type for this profile field.
        :param List[str] values: The possible GPU manufacturer(s) for an instance
               with this profile.
        """
        self.type = type
        self.values = values

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceProfileGPUManufacturer':
        """Initialize a InstanceProfileGPUManufacturer object from a json dictionary."""
        args = {}
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in InstanceProfileGPUManufacturer JSON')
        if 'values' in _dict:
            args['values'] = _dict.get('values')
        else:
            raise ValueError('Required property \'values\' not present in InstanceProfileGPUManufacturer JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceProfileGPUManufacturer object from 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, '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 InstanceProfileGPUManufacturer object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceProfileGPUManufacturer') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceProfileGPUManufacturer') -> 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 InstanceProfileGPUMemory:
    """
    InstanceProfileGPUMemory.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a InstanceProfileGPUMemory object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['InstanceProfileGPUMemoryFixed', 'InstanceProfileGPUMemoryRange', 'InstanceProfileGPUMemoryEnum', 'InstanceProfileGPUMemoryDependent'])
        )
        raise Exception(msg)


class InstanceProfileGPUModel:
    """
    InstanceProfileGPUModel.

    :attr str type: The type for this profile field.
    :attr List[str] values: The possible GPU model(s) for an instance with this
          profile.
    """

    def __init__(
        self,
        type: str,
        values: List[str],
    ) -> None:
        """
        Initialize a InstanceProfileGPUModel object.

        :param str type: The type for this profile field.
        :param List[str] values: The possible GPU model(s) for an instance with
               this profile.
        """
        self.type = type
        self.values = values

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceProfileGPUModel':
        """Initialize a InstanceProfileGPUModel object from a json dictionary."""
        args = {}
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in InstanceProfileGPUModel JSON')
        if 'values' in _dict:
            args['values'] = _dict.get('values')
        else:
            raise ValueError('Required property \'values\' not present in InstanceProfileGPUModel JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceProfileGPUModel object from 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, '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 InstanceProfileGPUModel object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceProfileGPUModel') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceProfileGPUModel') -> 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 InstanceProfileIdentity:
    """
    Identifies an instance profile by a unique property.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a InstanceProfileIdentity object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['InstanceProfileIdentityByName', 'InstanceProfileIdentityByHref'])
        )
        raise Exception(msg)


class InstanceProfileMemory:
    """
    InstanceProfileMemory.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a InstanceProfileMemory object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['InstanceProfileMemoryFixed', 'InstanceProfileMemoryRange', 'InstanceProfileMemoryEnum', 'InstanceProfileMemoryDependent'])
        )
        raise Exception(msg)


class InstanceProfileNUMACount:
    """
    InstanceProfileNUMACount.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a InstanceProfileNUMACount object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['InstanceProfileNUMACountFixed', 'InstanceProfileNUMACountDependent'])
        )
        raise Exception(msg)


class InstanceProfileNetworkInterfaceCount:
    """
    InstanceProfileNetworkInterfaceCount.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a InstanceProfileNetworkInterfaceCount object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['InstanceProfileNetworkInterfaceCountRange', 'InstanceProfileNetworkInterfaceCountDependent'])
        )
        raise Exception(msg)


class InstanceProfileOSArchitecture:
    """
    InstanceProfileOSArchitecture.

    :attr str default: The default OS architecture for an instance with this
          profile.
    :attr str type: The type for this profile field.
    :attr List[str] values: The supported OS architecture(s) for an instance with
          this profile.
    """

    def __init__(
        self,
        default: str,
        type: str,
        values: List[str],
    ) -> None:
        """
        Initialize a InstanceProfileOSArchitecture object.

        :param str default: The default OS architecture for an instance with this
               profile.
        :param str type: The type for this profile field.
        :param List[str] values: The supported OS architecture(s) for an instance
               with this profile.
        """
        self.default = default
        self.type = type
        self.values = values

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceProfileOSArchitecture':
        """Initialize a InstanceProfileOSArchitecture object from a json dictionary."""
        args = {}
        if 'default' in _dict:
            args['default'] = _dict.get('default')
        else:
            raise ValueError('Required property \'default\' not present in InstanceProfileOSArchitecture JSON')
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in InstanceProfileOSArchitecture JSON')
        if 'values' in _dict:
            args['values'] = _dict.get('values')
        else:
            raise ValueError('Required property \'values\' not present in InstanceProfileOSArchitecture JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceProfileOSArchitecture object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'default') and self.default is not None:
            _dict['default'] = self.default
        if hasattr(self, 'type') and self.type is not None:
            _dict['type'] = self.type
        if hasattr(self, 'values') and self.values is not None:
            _dict['values'] = self.values
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceProfileOSArchitecture object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceProfileOSArchitecture') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceProfileOSArchitecture') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class TypeEnum(str, Enum):
        """
        The type for this profile field.
        """

        ENUM = 'enum'



class InstanceProfilePortSpeed:
    """
    InstanceProfilePortSpeed.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a InstanceProfilePortSpeed object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['InstanceProfilePortSpeedFixed', 'InstanceProfilePortSpeedDependent'])
        )
        raise Exception(msg)


class InstanceProfileReference:
    """
    InstanceProfileReference.

    :attr str href: The URL for this virtual server instance profile.
    :attr str name: The globally unique name for this virtual server instance
          profile.
    """

    def __init__(
        self,
        href: str,
        name: str,
    ) -> None:
        """
        Initialize a InstanceProfileReference object.

        :param str href: The URL for this virtual server instance profile.
        :param str name: The globally unique name for this virtual server instance
               profile.
        """
        self.href = href
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceProfileReference':
        """Initialize a InstanceProfileReference object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in InstanceProfileReference JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in InstanceProfileReference JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceProfileReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceProfileReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceProfileReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceProfileReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceProfileVCPU:
    """
    InstanceProfileVCPU.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a InstanceProfileVCPU object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['InstanceProfileVCPUFixed', 'InstanceProfileVCPURange', 'InstanceProfileVCPUEnum', 'InstanceProfileVCPUDependent'])
        )
        raise Exception(msg)


class InstanceProfileVCPUArchitecture:
    """
    InstanceProfileVCPUArchitecture.

    :attr str default: (optional) The default VCPU architecture for an instance with
          this profile.
    :attr str type: The type for this profile field.
    :attr str value: The VCPU architecture for an instance with this profile.
    """

    def __init__(
        self,
        type: str,
        value: str,
        *,
        default: str = None,
    ) -> None:
        """
        Initialize a InstanceProfileVCPUArchitecture object.

        :param str type: The type for this profile field.
        :param str value: The VCPU architecture for an instance with this profile.
        :param str default: (optional) The default VCPU architecture for an
               instance with this profile.
        """
        self.default = default
        self.type = type
        self.value = value

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceProfileVCPUArchitecture':
        """Initialize a InstanceProfileVCPUArchitecture object from a json dictionary."""
        args = {}
        if 'default' in _dict:
            args['default'] = _dict.get('default')
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in InstanceProfileVCPUArchitecture JSON')
        if 'value' in _dict:
            args['value'] = _dict.get('value')
        else:
            raise ValueError('Required property \'value\' not present in InstanceProfileVCPUArchitecture JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceProfileVCPUArchitecture object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'default') and self.default is not None:
            _dict['default'] = self.default
        if hasattr(self, 'type') and self.type is not None:
            _dict['type'] = self.type
        if hasattr(self, 'value') and self.value is not None:
            _dict['value'] = self.value
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceProfileVCPUArchitecture object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceProfileVCPUArchitecture') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceProfileVCPUArchitecture') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class TypeEnum(str, Enum):
        """
        The type for this profile field.
        """

        FIXED = 'fixed'



class InstanceProfileVCPUManufacturer:
    """
    InstanceProfileVCPUManufacturer.

    :attr str default: (optional) The default VCPU manufacturer for an instance with
          this profile.
    :attr str type: The type for this profile field.
    :attr str value: The VCPU manufacturer for an instance with this profile.
    """

    def __init__(
        self,
        type: str,
        value: str,
        *,
        default: str = None,
    ) -> None:
        """
        Initialize a InstanceProfileVCPUManufacturer object.

        :param str type: The type for this profile field.
        :param str value: The VCPU manufacturer for an instance with this profile.
        :param str default: (optional) The default VCPU manufacturer for an
               instance with this profile.
        """
        self.default = default
        self.type = type
        self.value = value

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceProfileVCPUManufacturer':
        """Initialize a InstanceProfileVCPUManufacturer object from a json dictionary."""
        args = {}
        if 'default' in _dict:
            args['default'] = _dict.get('default')
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in InstanceProfileVCPUManufacturer JSON')
        if 'value' in _dict:
            args['value'] = _dict.get('value')
        else:
            raise ValueError('Required property \'value\' not present in InstanceProfileVCPUManufacturer JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceProfileVCPUManufacturer object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'default') and self.default is not None:
            _dict['default'] = self.default
        if hasattr(self, 'type') and self.type is not None:
            _dict['type'] = self.type
        if hasattr(self, 'value') and self.value is not None:
            _dict['value'] = self.value
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceProfileVCPUManufacturer object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceProfileVCPUManufacturer') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceProfileVCPUManufacturer') -> 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 InstanceProfileVolumeBandwidth:
    """
    InstanceProfileVolumeBandwidth.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a InstanceProfileVolumeBandwidth object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['InstanceProfileVolumeBandwidthFixed', 'InstanceProfileVolumeBandwidthRange', 'InstanceProfileVolumeBandwidthEnum', 'InstanceProfileVolumeBandwidthDependent'])
        )
        raise Exception(msg)


class InstancePrototype:
    """
    InstancePrototype.

    :attr InstanceAvailabilityPolicyPrototype availability_policy: (optional) The
          availability policy to use for this virtual server instance.
    :attr InstanceDefaultTrustedProfilePrototype default_trusted_profile: (optional)
          The default trusted profile configuration to use for this virtual server
          instance
          This property's value is used when provisioning the virtual server instance, but
          not
          subsequently managed. Accordingly, it is reflected as an [instance
          initialization](https://cloud.ibm.com/apidocs/vpc#get-instance-initialization)
          property.
    :attr List[KeyIdentity] keys: (optional) The public SSH keys for the
          administrative user of the virtual server instance. 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.
          For Windows images, the keys of type `rsa` must be specified, and one will be
          selected to encrypt [the administrator
          password](https://cloud.ibm.com/apidocs/vpc#get-instance-initialization). Keys
          are optional for other images, but if no keys are specified, the instance will
          be inaccessible unless the specified image provides another means of access.
          This property's value is used when provisioning the virtual server instance, but
          not subsequently managed. Accordingly, it is reflected as an [instance
          initialization](https://cloud.ibm.com/apidocs/vpc#get-instance-initialization)
          property.
    :attr InstanceMetadataServicePrototype metadata_service: (optional) The metadata
          service configuration.
    :attr str name: (optional) The name for this virtual server instance. The name
          must not be used by another virtual server instance in the region. If
          unspecified, the name will be a hyphenated list of randomly-selected words.
          The system hostname will be based on this name.
    :attr InstancePlacementTargetPrototype placement_target: (optional) The
          placement restrictions to use for the virtual server instance.
    :attr InstanceProfileIdentity profile: (optional) The
          [profile](https://cloud.ibm.com/docs/vpc?topic=vpc-profiles) to use for this
          virtual server instance.
          If unspecified, `bx2-2x8` will be used, but this default value is expected to
          change
          in the future.
    :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) will be
          used.
    :attr int total_volume_bandwidth: (optional) The amount of bandwidth (in
          megabits per second) allocated exclusively to instance storage volumes. An
          increase in this value will result in a corresponding decrease to
          `total_network_bandwidth`.
    :attr str user_data: (optional) [User
          data](https://cloud.ibm.com/docs/vpc?topic=vpc-user-data) to make available when
          setting up the virtual server instance.
    :attr List[VolumeAttachmentPrototype] volume_attachments: (optional) The
          additional volume attachments to create for the virtual server instance.
    :attr VPCIdentity vpc: (optional) The VPC this virtual server instance will
          reside in.
          If specified, it must match the VPC for the subnets of the instance network
          interfaces.
    """

    def __init__(
        self,
        *,
        availability_policy: 'InstanceAvailabilityPolicyPrototype' = None,
        default_trusted_profile: 'InstanceDefaultTrustedProfilePrototype' = None,
        keys: List['KeyIdentity'] = None,
        metadata_service: 'InstanceMetadataServicePrototype' = None,
        name: str = None,
        placement_target: 'InstancePlacementTargetPrototype' = None,
        profile: 'InstanceProfileIdentity' = None,
        resource_group: 'ResourceGroupIdentity' = None,
        total_volume_bandwidth: int = None,
        user_data: str = None,
        volume_attachments: List['VolumeAttachmentPrototype'] = None,
        vpc: 'VPCIdentity' = None,
    ) -> None:
        """
        Initialize a InstancePrototype object.

        :param InstanceAvailabilityPolicyPrototype availability_policy: (optional)
               The availability policy to use for this virtual server instance.
        :param InstanceDefaultTrustedProfilePrototype default_trusted_profile:
               (optional) The default trusted profile configuration to use for this
               virtual server instance
               This property's value is used when provisioning the virtual server
               instance, but not
               subsequently managed. Accordingly, it is reflected as an [instance
               initialization](https://cloud.ibm.com/apidocs/vpc#get-instance-initialization)
               property.
        :param List[KeyIdentity] keys: (optional) The public SSH keys for the
               administrative user of the virtual server instance. 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.
               For Windows images, the keys of type `rsa` must be specified, and one will
               be selected to encrypt [the administrator
               password](https://cloud.ibm.com/apidocs/vpc#get-instance-initialization).
               Keys are optional for other images, but if no keys are specified, the
               instance will be inaccessible unless the specified image provides another
               means of access.
               This property's value is used when provisioning the virtual server
               instance, but not subsequently managed. Accordingly, it is reflected as an
               [instance
               initialization](https://cloud.ibm.com/apidocs/vpc#get-instance-initialization)
               property.
        :param InstanceMetadataServicePrototype metadata_service: (optional) The
               metadata service configuration.
        :param str name: (optional) The name for this virtual server instance. The
               name must not be used by another virtual server instance in the region. If
               unspecified, the name will be a hyphenated list of randomly-selected words.
               The system hostname will be based on this name.
        :param InstancePlacementTargetPrototype placement_target: (optional) The
               placement restrictions to use for the virtual server instance.
        :param InstanceProfileIdentity profile: (optional) The
               [profile](https://cloud.ibm.com/docs/vpc?topic=vpc-profiles) to use for
               this
               virtual server instance.
               If unspecified, `bx2-2x8` will be used, but this default value is expected
               to change
               in the future.
        :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) will be
               used.
        :param int total_volume_bandwidth: (optional) The amount of bandwidth (in
               megabits per second) allocated exclusively to instance storage volumes. An
               increase in this value will result in a corresponding decrease to
               `total_network_bandwidth`.
        :param str user_data: (optional) [User
               data](https://cloud.ibm.com/docs/vpc?topic=vpc-user-data) to make available
               when setting up the virtual server instance.
        :param List[VolumeAttachmentPrototype] volume_attachments: (optional) The
               additional volume attachments to create for the virtual server instance.
        :param VPCIdentity vpc: (optional) The VPC this virtual server instance
               will reside in.
               If specified, it must match the VPC for the subnets of the instance network
               interfaces.
        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['InstancePrototypeInstanceByImage', 'InstancePrototypeInstanceByCatalogOffering', 'InstancePrototypeInstanceByVolume', 'InstancePrototypeInstanceBySourceSnapshot', 'InstancePrototypeInstanceBySourceTemplate'])
        )
        raise Exception(msg)


class InstanceReference:
    """
    InstanceReference.

    :attr str crn: The CRN for this virtual server instance.
    :attr InstanceReferenceDeleted deleted: (optional) If present, this property
          indicates the referenced resource has been deleted, and provides
          some supplementary information.
    :attr str href: The URL for this virtual server instance.
    :attr str id: The unique identifier for this virtual server instance.
    :attr str name: The name for this virtual server instance. The name is unique
          across all virtual server instances in the region.
    """

    def __init__(
        self,
        crn: str,
        href: str,
        id: str,
        name: str,
        *,
        deleted: 'InstanceReferenceDeleted' = None,
    ) -> None:
        """
        Initialize a InstanceReference object.

        :param str crn: The CRN for this virtual server instance.
        :param str href: The URL for this virtual server instance.
        :param str id: The unique identifier for this virtual server instance.
        :param str name: The name for this virtual server instance. The name is
               unique across all virtual server instances in the region.
        :param InstanceReferenceDeleted deleted: (optional) If present, this
               property indicates the referenced resource has been deleted, and provides
               some supplementary information.
        """
        self.crn = crn
        self.deleted = deleted
        self.href = href
        self.id = id
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceReference':
        """Initialize a InstanceReference object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError('Required property \'crn\' not present in InstanceReference JSON')
        if 'deleted' in _dict:
            args['deleted'] = InstanceReferenceDeleted.from_dict(_dict.get('deleted'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in InstanceReference JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in InstanceReference JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in InstanceReference JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'deleted') and self.deleted is not None:
            if isinstance(self.deleted, dict):
                _dict['deleted'] = self.deleted
            else:
                _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceReferenceDeleted:
    """
    If present, this property indicates the referenced resource has been deleted, and
    provides some supplementary information.

    :attr str more_info: Link to documentation about deleted resources.
    """

    def __init__(
        self,
        more_info: str,
    ) -> None:
        """
        Initialize a InstanceReferenceDeleted object.

        :param str more_info: Link to documentation about deleted resources.
        """
        self.more_info = more_info

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceReferenceDeleted':
        """Initialize a InstanceReferenceDeleted object from a json dictionary."""
        args = {}
        if 'more_info' in _dict:
            args['more_info'] = _dict.get('more_info')
        else:
            raise ValueError('Required property \'more_info\' not present in InstanceReferenceDeleted JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceReferenceDeleted object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'more_info') and self.more_info is not None:
            _dict['more_info'] = self.more_info
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceReferenceDeleted object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceReferenceDeleted') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceReferenceDeleted') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceStatusReason:
    """
    InstanceStatusReason.

    :attr str code: A snake case string succinctly identifying the status reason.
    :attr str message: An explanation of the status reason.
    :attr str more_info: (optional) Link to documentation about this status reason.
    """

    def __init__(
        self,
        code: str,
        message: str,
        *,
        more_info: str = None,
    ) -> None:
        """
        Initialize a InstanceStatusReason object.

        :param str code: A snake case string succinctly identifying the status
               reason.
        :param str message: An explanation of the status reason.
        :param str more_info: (optional) Link to documentation about this status
               reason.
        """
        self.code = code
        self.message = message
        self.more_info = more_info

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceStatusReason':
        """Initialize a InstanceStatusReason object from a json dictionary."""
        args = {}
        if 'code' in _dict:
            args['code'] = _dict.get('code')
        else:
            raise ValueError('Required property \'code\' not present in InstanceStatusReason JSON')
        if 'message' in _dict:
            args['message'] = _dict.get('message')
        else:
            raise ValueError('Required property \'message\' not present in InstanceStatusReason JSON')
        if 'more_info' in _dict:
            args['more_info'] = _dict.get('more_info')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceStatusReason object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'code') and self.code is not None:
            _dict['code'] = self.code
        if hasattr(self, 'message') and self.message is not None:
            _dict['message'] = self.message
        if hasattr(self, 'more_info') and self.more_info is not None:
            _dict['more_info'] = self.more_info
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceStatusReason object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceStatusReason') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceStatusReason') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class CodeEnum(str, Enum):
        """
        A snake case string succinctly identifying the status reason.
        """

        CANNOT_START = 'cannot_start'
        CANNOT_START_CAPACITY = 'cannot_start_capacity'
        CANNOT_START_COMPUTE = 'cannot_start_compute'
        CANNOT_START_IP_ADDRESS = 'cannot_start_ip_address'
        CANNOT_START_NETWORK = 'cannot_start_network'
        CANNOT_START_PLACEMENT_GROUP = 'cannot_start_placement_group'
        CANNOT_START_STORAGE = 'cannot_start_storage'
        ENCRYPTION_KEY_DELETED = 'encryption_key_deleted'
        STOPPED_BY_HOST_FAILURE = 'stopped_by_host_failure'
        STOPPED_FOR_IMAGE_CREATION = 'stopped_for_image_creation'



class InstanceTemplate:
    """
    InstanceTemplate.

    :attr InstanceAvailabilityPolicyPrototype availability_policy: (optional) The
          availability policy to use for this virtual server instance.
    :attr datetime created_at: The date and time that the instance template was
          created.
    :attr str crn: The CRN for this instance template.
    :attr InstanceDefaultTrustedProfilePrototype default_trusted_profile: (optional)
          The default trusted profile configuration to use for this virtual server
          instance
          This property's value is used when provisioning the virtual server instance, but
          not
          subsequently managed. Accordingly, it is reflected as an [instance
          initialization](https://cloud.ibm.com/apidocs/vpc#get-instance-initialization)
          property.
    :attr str href: The URL for this instance template.
    :attr str id: The unique identifier for this instance template.
    :attr List[KeyIdentity] keys: (optional) The public SSH keys for the
          administrative user of the virtual server instance. 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.
          For Windows images, the keys of type `rsa` must be specified, and one will be
          selected to encrypt [the administrator
          password](https://cloud.ibm.com/apidocs/vpc#get-instance-initialization). Keys
          are optional for other images, but if no keys are specified, the instance will
          be inaccessible unless the specified image provides another means of access.
          This property's value is used when provisioning the virtual server instance, but
          not subsequently managed. Accordingly, it is reflected as an [instance
          initialization](https://cloud.ibm.com/apidocs/vpc#get-instance-initialization)
          property.
    :attr InstanceMetadataServicePrototype metadata_service: (optional) The metadata
          service configuration.
    :attr str name: The name for this instance template. The name is unique across
          all instance templates in the region.
    :attr InstancePlacementTargetPrototype placement_target: (optional) The
          placement restrictions to use for the virtual server instance.
    :attr InstanceProfileIdentity profile: (optional) The
          [profile](https://cloud.ibm.com/docs/vpc?topic=vpc-profiles) to use for this
          virtual server instance.
          If unspecified, `bx2-2x8` will be used, but this default value is expected to
          change
          in the future.
    :attr ResourceGroupReference resource_group: The resource group for this
          instance template.
    :attr int total_volume_bandwidth: (optional) The amount of bandwidth (in
          megabits per second) allocated exclusively to instance storage volumes. An
          increase in this value will result in a corresponding decrease to
          `total_network_bandwidth`.
    :attr str user_data: (optional) [User
          data](https://cloud.ibm.com/docs/vpc?topic=vpc-user-data) to make available when
          setting up the virtual server instance.
    :attr List[VolumeAttachmentPrototype] volume_attachments: (optional) The
          additional volume attachments to create for the virtual server instance.
    :attr VPCIdentity vpc: (optional) The VPC this virtual server instance will
          reside in.
          If specified, it must match the VPC for the subnets of the instance network
          interfaces.
    """

    def __init__(
        self,
        created_at: datetime,
        crn: str,
        href: str,
        id: str,
        name: str,
        resource_group: 'ResourceGroupReference',
        *,
        availability_policy: 'InstanceAvailabilityPolicyPrototype' = None,
        default_trusted_profile: 'InstanceDefaultTrustedProfilePrototype' = None,
        keys: List['KeyIdentity'] = None,
        metadata_service: 'InstanceMetadataServicePrototype' = None,
        placement_target: 'InstancePlacementTargetPrototype' = None,
        profile: 'InstanceProfileIdentity' = None,
        total_volume_bandwidth: int = None,
        user_data: str = None,
        volume_attachments: List['VolumeAttachmentPrototype'] = None,
        vpc: 'VPCIdentity' = None,
    ) -> None:
        """
        Initialize a InstanceTemplate object.

        :param datetime created_at: The date and time that the instance template
               was created.
        :param str crn: The CRN for this instance template.
        :param str href: The URL for this instance template.
        :param str id: The unique identifier for this instance template.
        :param str name: The name for this instance template. The name is unique
               across all instance templates in the region.
        :param ResourceGroupReference resource_group: The resource group for this
               instance template.
        :param InstanceAvailabilityPolicyPrototype availability_policy: (optional)
               The availability policy to use for this virtual server instance.
        :param InstanceDefaultTrustedProfilePrototype default_trusted_profile:
               (optional) The default trusted profile configuration to use for this
               virtual server instance
               This property's value is used when provisioning the virtual server
               instance, but not
               subsequently managed. Accordingly, it is reflected as an [instance
               initialization](https://cloud.ibm.com/apidocs/vpc#get-instance-initialization)
               property.
        :param List[KeyIdentity] keys: (optional) The public SSH keys for the
               administrative user of the virtual server instance. 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.
               For Windows images, the keys of type `rsa` must be specified, and one will
               be selected to encrypt [the administrator
               password](https://cloud.ibm.com/apidocs/vpc#get-instance-initialization).
               Keys are optional for other images, but if no keys are specified, the
               instance will be inaccessible unless the specified image provides another
               means of access.
               This property's value is used when provisioning the virtual server
               instance, but not subsequently managed. Accordingly, it is reflected as an
               [instance
               initialization](https://cloud.ibm.com/apidocs/vpc#get-instance-initialization)
               property.
        :param InstanceMetadataServicePrototype metadata_service: (optional) The
               metadata service configuration.
        :param InstancePlacementTargetPrototype placement_target: (optional) The
               placement restrictions to use for the virtual server instance.
        :param InstanceProfileIdentity profile: (optional) The
               [profile](https://cloud.ibm.com/docs/vpc?topic=vpc-profiles) to use for
               this
               virtual server instance.
               If unspecified, `bx2-2x8` will be used, but this default value is expected
               to change
               in the future.
        :param int total_volume_bandwidth: (optional) The amount of bandwidth (in
               megabits per second) allocated exclusively to instance storage volumes. An
               increase in this value will result in a corresponding decrease to
               `total_network_bandwidth`.
        :param str user_data: (optional) [User
               data](https://cloud.ibm.com/docs/vpc?topic=vpc-user-data) to make available
               when setting up the virtual server instance.
        :param List[VolumeAttachmentPrototype] volume_attachments: (optional) The
               additional volume attachments to create for the virtual server instance.
        :param VPCIdentity vpc: (optional) The VPC this virtual server instance
               will reside in.
               If specified, it must match the VPC for the subnets of the instance network
               interfaces.
        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['InstanceTemplateInstanceByImageInstanceTemplateContext', 'InstanceTemplateInstanceBySourceSnapshotInstanceTemplateContext', 'InstanceTemplateInstanceByCatalogOfferingInstanceTemplateContext'])
        )
        raise Exception(msg)


class InstanceTemplateCollection:
    """
    InstanceTemplateCollection.

    :attr InstanceTemplateCollectionFirst first: A link to the first page of
          resources.
    :attr int limit: The maximum number of resources that can be returned by the
          request.
    :attr InstanceTemplateCollectionNext next: (optional) A link to the next page of
          resources. This property is present for all pages
          except the last page.
    :attr List[InstanceTemplate] templates: Collection of instance templates.
    :attr int total_count: The total number of resources across all pages.
    """

    def __init__(
        self,
        first: 'InstanceTemplateCollectionFirst',
        limit: int,
        templates: List['InstanceTemplate'],
        total_count: int,
        *,
        next: 'InstanceTemplateCollectionNext' = None,
    ) -> None:
        """
        Initialize a InstanceTemplateCollection object.

        :param InstanceTemplateCollectionFirst first: A link to the first page of
               resources.
        :param int limit: The maximum number of resources that can be returned by
               the request.
        :param List[InstanceTemplate] templates: Collection of instance templates.
        :param int total_count: The total number of resources across all pages.
        :param InstanceTemplateCollectionNext next: (optional) A link to the next
               page of resources. This property is present for all pages
               except the last page.
        """
        self.first = first
        self.limit = limit
        self.next = next
        self.templates = templates
        self.total_count = total_count

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceTemplateCollection':
        """Initialize a InstanceTemplateCollection object from a json dictionary."""
        args = {}
        if 'first' in _dict:
            args['first'] = InstanceTemplateCollectionFirst.from_dict(_dict.get('first'))
        else:
            raise ValueError('Required property \'first\' not present in InstanceTemplateCollection JSON')
        if 'limit' in _dict:
            args['limit'] = _dict.get('limit')
        else:
            raise ValueError('Required property \'limit\' not present in InstanceTemplateCollection JSON')
        if 'next' in _dict:
            args['next'] = InstanceTemplateCollectionNext.from_dict(_dict.get('next'))
        if 'templates' in _dict:
            args['templates'] = _dict.get('templates')
        else:
            raise ValueError('Required property \'templates\' not present in InstanceTemplateCollection JSON')
        if 'total_count' in _dict:
            args['total_count'] = _dict.get('total_count')
        else:
            raise ValueError('Required property \'total_count\' not present in InstanceTemplateCollection JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceTemplateCollection object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'first') and self.first is not None:
            if isinstance(self.first, dict):
                _dict['first'] = self.first
            else:
                _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:
            if isinstance(self.next, dict):
                _dict['next'] = self.next
            else:
                _dict['next'] = self.next.to_dict()
        if hasattr(self, 'templates') and self.templates is not None:
            templates_list = []
            for v in self.templates:
                if isinstance(v, dict):
                    templates_list.append(v)
                else:
                    templates_list.append(v.to_dict())
            _dict['templates'] = templates_list
        if hasattr(self, 'total_count') and self.total_count is not None:
            _dict['total_count'] = self.total_count
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceTemplateCollection object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceTemplateCollection') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceTemplateCollection') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceTemplateCollectionFirst:
    """
    A link to the first page of resources.

    :attr str href: The URL for a page of resources.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a InstanceTemplateCollectionFirst object.

        :param str href: The URL for a page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceTemplateCollectionFirst':
        """Initialize a InstanceTemplateCollectionFirst object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in InstanceTemplateCollectionFirst JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceTemplateCollectionFirst object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceTemplateCollectionFirst object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceTemplateCollectionFirst') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceTemplateCollectionFirst') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceTemplateCollectionNext:
    """
    A link to the next page of resources. This property is present for all pages except
    the last page.

    :attr str href: The URL for a page of resources.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a InstanceTemplateCollectionNext object.

        :param str href: The URL for a page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceTemplateCollectionNext':
        """Initialize a InstanceTemplateCollectionNext object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in InstanceTemplateCollectionNext JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceTemplateCollectionNext object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceTemplateCollectionNext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceTemplateCollectionNext') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceTemplateCollectionNext') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceTemplateIdentity:
    """
    Identifies an instance template by a unique property.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a InstanceTemplateIdentity object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['InstanceTemplateIdentityById', 'InstanceTemplateIdentityByHref', 'InstanceTemplateIdentityByCRN'])
        )
        raise Exception(msg)


class InstanceTemplatePatch:
    """
    InstanceTemplatePatch.

    :attr str name: (optional) The name for this instance template. The name must
          not be used by another instance template in the region.
    """

    def __init__(
        self,
        *,
        name: str = None,
    ) -> None:
        """
        Initialize a InstanceTemplatePatch object.

        :param str name: (optional) The name for this instance template. The name
               must not be used by another instance template in the region.
        """
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceTemplatePatch':
        """Initialize a InstanceTemplatePatch object from a json dictionary."""
        args = {}
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceTemplatePatch object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceTemplatePatch object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceTemplatePatch') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceTemplatePatch') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceTemplatePrototype:
    """
    InstanceTemplatePrototype.

    :attr InstanceAvailabilityPolicyPrototype availability_policy: (optional) The
          availability policy to use for this virtual server instance.
    :attr InstanceDefaultTrustedProfilePrototype default_trusted_profile: (optional)
          The default trusted profile configuration to use for this virtual server
          instance
          This property's value is used when provisioning the virtual server instance, but
          not
          subsequently managed. Accordingly, it is reflected as an [instance
          initialization](https://cloud.ibm.com/apidocs/vpc#get-instance-initialization)
          property.
    :attr List[KeyIdentity] keys: (optional) The public SSH keys for the
          administrative user of the virtual server instance. 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.
          For Windows images, the keys of type `rsa` must be specified, and one will be
          selected to encrypt [the administrator
          password](https://cloud.ibm.com/apidocs/vpc#get-instance-initialization). Keys
          are optional for other images, but if no keys are specified, the instance will
          be inaccessible unless the specified image provides another means of access.
          This property's value is used when provisioning the virtual server instance, but
          not subsequently managed. Accordingly, it is reflected as an [instance
          initialization](https://cloud.ibm.com/apidocs/vpc#get-instance-initialization)
          property.
    :attr InstanceMetadataServicePrototype metadata_service: (optional) The metadata
          service configuration.
    :attr str name: (optional) The name for this instance template. The name must
          not be used by another instance template in the region. If unspecified, the name
          will be a hyphenated list of randomly-selected words.
    :attr InstancePlacementTargetPrototype placement_target: (optional) The
          placement restrictions to use for the virtual server instance.
    :attr InstanceProfileIdentity profile: (optional) The
          [profile](https://cloud.ibm.com/docs/vpc?topic=vpc-profiles) to use for this
          virtual server instance.
          If unspecified, `bx2-2x8` will be used, but this default value is expected to
          change
          in the future.
    :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) will be
          used.
    :attr int total_volume_bandwidth: (optional) The amount of bandwidth (in
          megabits per second) allocated exclusively to instance storage volumes. An
          increase in this value will result in a corresponding decrease to
          `total_network_bandwidth`.
    :attr str user_data: (optional) [User
          data](https://cloud.ibm.com/docs/vpc?topic=vpc-user-data) to make available when
          setting up the virtual server instance.
    :attr List[VolumeAttachmentPrototype] volume_attachments: (optional) The
          additional volume attachments to create for the virtual server instance.
    :attr VPCIdentity vpc: (optional) The VPC this virtual server instance will
          reside in.
          If specified, it must match the VPC for the subnets of the instance network
          interfaces.
    """

    def __init__(
        self,
        *,
        availability_policy: 'InstanceAvailabilityPolicyPrototype' = None,
        default_trusted_profile: 'InstanceDefaultTrustedProfilePrototype' = None,
        keys: List['KeyIdentity'] = None,
        metadata_service: 'InstanceMetadataServicePrototype' = None,
        name: str = None,
        placement_target: 'InstancePlacementTargetPrototype' = None,
        profile: 'InstanceProfileIdentity' = None,
        resource_group: 'ResourceGroupIdentity' = None,
        total_volume_bandwidth: int = None,
        user_data: str = None,
        volume_attachments: List['VolumeAttachmentPrototype'] = None,
        vpc: 'VPCIdentity' = None,
    ) -> None:
        """
        Initialize a InstanceTemplatePrototype object.

        :param InstanceAvailabilityPolicyPrototype availability_policy: (optional)
               The availability policy to use for this virtual server instance.
        :param InstanceDefaultTrustedProfilePrototype default_trusted_profile:
               (optional) The default trusted profile configuration to use for this
               virtual server instance
               This property's value is used when provisioning the virtual server
               instance, but not
               subsequently managed. Accordingly, it is reflected as an [instance
               initialization](https://cloud.ibm.com/apidocs/vpc#get-instance-initialization)
               property.
        :param List[KeyIdentity] keys: (optional) The public SSH keys for the
               administrative user of the virtual server instance. 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.
               For Windows images, the keys of type `rsa` must be specified, and one will
               be selected to encrypt [the administrator
               password](https://cloud.ibm.com/apidocs/vpc#get-instance-initialization).
               Keys are optional for other images, but if no keys are specified, the
               instance will be inaccessible unless the specified image provides another
               means of access.
               This property's value is used when provisioning the virtual server
               instance, but not subsequently managed. Accordingly, it is reflected as an
               [instance
               initialization](https://cloud.ibm.com/apidocs/vpc#get-instance-initialization)
               property.
        :param InstanceMetadataServicePrototype metadata_service: (optional) The
               metadata service configuration.
        :param str name: (optional) The name for this instance template. The name
               must not be used by another instance template in the region. If
               unspecified, the name will be a hyphenated list of randomly-selected words.
        :param InstancePlacementTargetPrototype placement_target: (optional) The
               placement restrictions to use for the virtual server instance.
        :param InstanceProfileIdentity profile: (optional) The
               [profile](https://cloud.ibm.com/docs/vpc?topic=vpc-profiles) to use for
               this
               virtual server instance.
               If unspecified, `bx2-2x8` will be used, but this default value is expected
               to change
               in the future.
        :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) will be
               used.
        :param int total_volume_bandwidth: (optional) The amount of bandwidth (in
               megabits per second) allocated exclusively to instance storage volumes. An
               increase in this value will result in a corresponding decrease to
               `total_network_bandwidth`.
        :param str user_data: (optional) [User
               data](https://cloud.ibm.com/docs/vpc?topic=vpc-user-data) to make available
               when setting up the virtual server instance.
        :param List[VolumeAttachmentPrototype] volume_attachments: (optional) The
               additional volume attachments to create for the virtual server instance.
        :param VPCIdentity vpc: (optional) The VPC this virtual server instance
               will reside in.
               If specified, it must match the VPC for the subnets of the instance network
               interfaces.
        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['InstanceTemplatePrototypeInstanceTemplateByImage', 'InstanceTemplatePrototypeInstanceTemplateBySourceTemplate', 'InstanceTemplatePrototypeInstanceTemplateBySourceSnapshot', 'InstanceTemplatePrototypeInstanceTemplateByCatalogOffering'])
        )
        raise Exception(msg)


class InstanceTemplateReference:
    """
    InstanceTemplateReference.

    :attr str crn: The CRN for this instance template.
    :attr InstanceTemplateReferenceDeleted deleted: (optional) If present, this
          property indicates the referenced resource has been deleted, and provides
          some supplementary information.
    :attr str href: The URL for this instance template.
    :attr str id: The unique identifier for this instance template.
    :attr str name: The name for this instance template. The name is unique across
          all instance templates in the region.
    """

    def __init__(
        self,
        crn: str,
        href: str,
        id: str,
        name: str,
        *,
        deleted: 'InstanceTemplateReferenceDeleted' = None,
    ) -> None:
        """
        Initialize a InstanceTemplateReference object.

        :param str crn: The CRN for this instance template.
        :param str href: The URL for this instance template.
        :param str id: The unique identifier for this instance template.
        :param str name: The name for this instance template. The name is unique
               across all instance templates in the region.
        :param InstanceTemplateReferenceDeleted deleted: (optional) If present,
               this property indicates the referenced resource has been deleted, and
               provides
               some supplementary information.
        """
        self.crn = crn
        self.deleted = deleted
        self.href = href
        self.id = id
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceTemplateReference':
        """Initialize a InstanceTemplateReference object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError('Required property \'crn\' not present in InstanceTemplateReference JSON')
        if 'deleted' in _dict:
            args['deleted'] = InstanceTemplateReferenceDeleted.from_dict(_dict.get('deleted'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in InstanceTemplateReference JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in InstanceTemplateReference JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in InstanceTemplateReference JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceTemplateReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'deleted') and self.deleted is not None:
            if isinstance(self.deleted, dict):
                _dict['deleted'] = self.deleted
            else:
                _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceTemplateReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceTemplateReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceTemplateReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceTemplateReferenceDeleted:
    """
    If present, this property indicates the referenced resource has been deleted, and
    provides some supplementary information.

    :attr str more_info: Link to documentation about deleted resources.
    """

    def __init__(
        self,
        more_info: str,
    ) -> None:
        """
        Initialize a InstanceTemplateReferenceDeleted object.

        :param str more_info: Link to documentation about deleted resources.
        """
        self.more_info = more_info

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceTemplateReferenceDeleted':
        """Initialize a InstanceTemplateReferenceDeleted object from a json dictionary."""
        args = {}
        if 'more_info' in _dict:
            args['more_info'] = _dict.get('more_info')
        else:
            raise ValueError('Required property \'more_info\' not present in InstanceTemplateReferenceDeleted JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceTemplateReferenceDeleted object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'more_info') and self.more_info is not None:
            _dict['more_info'] = self.more_info
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceTemplateReferenceDeleted object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceTemplateReferenceDeleted') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceTemplateReferenceDeleted') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceVCPU:
    """
    The virtual server instance VCPU configuration.

    :attr str architecture: The VCPU architecture.
    :attr int count: The number of VCPUs assigned.
    :attr str manufacturer: The VCPU manufacturer.
    """

    def __init__(
        self,
        architecture: str,
        count: int,
        manufacturer: str,
    ) -> None:
        """
        Initialize a InstanceVCPU object.

        :param str architecture: The VCPU architecture.
        :param int count: The number of VCPUs assigned.
        :param str manufacturer: The VCPU manufacturer.
        """
        self.architecture = architecture
        self.count = count
        self.manufacturer = manufacturer

    @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')
        if 'manufacturer' in _dict:
            args['manufacturer'] = _dict.get('manufacturer')
        else:
            raise ValueError('Required property \'manufacturer\' 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
        if hasattr(self, 'manufacturer') and self.manufacturer is not None:
            _dict['manufacturer'] = self.manufacturer
        return _dict

    def _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 name for this key. The name must not be used by another key
          in the region. If unspecified, the name will be a hyphenated list of
          randomly-selected words.
    :attr str public_key: The public SSH key, consisting of two space-separated
          fields: the algorithm name, and the base64-encoded 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 name for this key. The name must not be used by
               another key in the region. If unspecified, the name will be a hyphenated
               list of randomly-selected words.
        :param str public_key: The public SSH key, consisting of two
               space-separated fields: the algorithm name, and the base64-encoded 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:
            if isinstance(self.resource_group, dict):
                _dict['resource_group'] = self.resource_group
            else:
                _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.
        """

        ED25519 = 'ed25519'
        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(v) for v 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:
            if isinstance(self.first, dict):
                _dict['first'] = self.first
            else:
                _dict['first'] = self.first.to_dict()
        if hasattr(self, 'keys') and self.keys is not None:
            keys_list = []
            for v in self.keys:
                if isinstance(v, dict):
                    keys_list.append(v)
                else:
                    keys_list.append(v.to_dict())
            _dict['keys'] = keys_list
        if hasattr(self, 'limit') and self.limit is not None:
            _dict['limit'] = self.limit
        if hasattr(self, 'next') and self.next is not None:
            if isinstance(self.next, dict):
                _dict['next'] = self.next
            else:
                _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', 'KeyIdentityByFingerprint'])
        )
        raise Exception(msg)


class KeyPatch:
    """
    KeyPatch.

    :attr str name: (optional) The name for this key. The name must not be used by
          another key in the region.
    """

    def __init__(
        self,
        *,
        name: str = None,
    ) -> None:
        """
        Initialize a KeyPatch object.

        :param str name: (optional) The name for this key. The name must not be
               used by another key in the region.
        """
        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 KeyReference:
    """
    KeyReference.

    :attr str crn: The CRN for this key.
    :attr KeyReferenceDeleted deleted: (optional) If present, this property
          indicates the referenced resource has been deleted, and provides
          some supplementary information.
    :attr str fingerprint: The fingerprint for this key.  The value is returned
          base64-encoded and prefixed with the hash algorithm (always `SHA256`).
    :attr str href: The URL for this key.
    :attr str id: The unique identifier for this key.
    :attr str name: The name for this key. The name is unique across all keys in the
          region.
    """

    def __init__(
        self,
        crn: str,
        fingerprint: str,
        href: str,
        id: str,
        name: str,
        *,
        deleted: 'KeyReferenceDeleted' = None,
    ) -> None:
        """
        Initialize a KeyReference 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 name for this key. The name is unique across all keys
               in the region.
        :param KeyReferenceDeleted deleted: (optional) If present, this property
               indicates the referenced resource has been deleted, and provides
               some supplementary information.
        """
        self.crn = crn
        self.deleted = deleted
        self.fingerprint = fingerprint
        self.href = href
        self.id = id
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'KeyReference':
        """Initialize a KeyReference object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError('Required property \'crn\' not present in KeyReference JSON')
        if 'deleted' in _dict:
            args['deleted'] = KeyReferenceDeleted.from_dict(_dict.get('deleted'))
        if 'fingerprint' in _dict:
            args['fingerprint'] = _dict.get('fingerprint')
        else:
            raise ValueError('Required property \'fingerprint\' not present in KeyReference JSON')
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in KeyReference JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in KeyReference JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in KeyReference JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a KeyReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'deleted') and self.deleted is not None:
            if isinstance(self.deleted, dict):
                _dict['deleted'] = self.deleted
            else:
                _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'fingerprint') and self.fingerprint is not None:
            _dict['fingerprint'] = self.fingerprint
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this KeyReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'KeyReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'KeyReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class KeyReferenceDeleted:
    """
    If present, this property indicates the referenced resource has been deleted, and
    provides some supplementary information.

    :attr str more_info: Link to documentation about deleted resources.
    """

    def __init__(
        self,
        more_info: str,
    ) -> None:
        """
        Initialize a KeyReferenceDeleted object.

        :param str more_info: Link to documentation about deleted resources.
        """
        self.more_info = more_info

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'KeyReferenceDeleted':
        """Initialize a KeyReferenceDeleted object from a json dictionary."""
        args = {}
        if 'more_info' in _dict:
            args['more_info'] = _dict.get('more_info')
        else:
            raise ValueError('Required property \'more_info\' not present in KeyReferenceDeleted JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a KeyReferenceDeleted object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'more_info') and self.more_info is not None:
            _dict['more_info'] = self.more_info
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this KeyReferenceDeleted object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'KeyReferenceDeleted') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'KeyReferenceDeleted') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class LegacyCloudObjectStorageBucketIdentity:
    """
    Identifies a Cloud Object Storage bucket by a unique property.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a LegacyCloudObjectStorageBucketIdentity object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['LegacyCloudObjectStorageBucketIdentityCloudObjectStorageBucketIdentityByName'])
        )
        raise Exception(msg)


class LegacyCloudObjectStorageBucketReference:
    """
    LegacyCloudObjectStorageBucketReference.

    :attr str name: The globally unique name of this Cloud Object Storage bucket.
    """

    def __init__(
        self,
        name: str,
    ) -> None:
        """
        Initialize a LegacyCloudObjectStorageBucketReference object.

        :param str name: The globally unique name of this Cloud Object Storage
               bucket.
        """
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LegacyCloudObjectStorageBucketReference':
        """Initialize a LegacyCloudObjectStorageBucketReference object from a json dictionary."""
        args = {}
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in LegacyCloudObjectStorageBucketReference JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LegacyCloudObjectStorageBucketReference object from 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 LegacyCloudObjectStorageBucketReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LegacyCloudObjectStorageBucketReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LegacyCloudObjectStorageBucketReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


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 LoadBalancerDNS dns: (optional) The DNS configuration for this load
          balancer.
          If absent, DNS `A` records for this load balancer's `hostname` property will be
          added to
          the public DNS zone `lb.appdomain.cloud`.
    :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 instance_groups_supported: Indicates whether this load balancer
          supports instance groups.
    :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 name for this load balancer. The name is unique across all
          load balancers in the VPC.
    :attr str operating_status: The operating status of this load balancer.
    :attr List[LoadBalancerPoolReference] pools: The pools of this load balancer.
    :attr List[LoadBalancerPrivateIpsItem] private_ips: The private IP addresses
          assigned to this load balancer.
    :attr LoadBalancerProfileReference profile: The profile for this load balancer.
    :attr str provisioning_status: The provisioning status of this load balancer:
          - `active`: The load balancer is running.
          - `create_pending`: The load balancer is being created.
          - `delete_pending`: The load balancer is being deleted.
          - `maintenance_pending`: The load balancer is unavailable due to an internal
                                    error (contact IBM support).
          - `migrate_pending`: The load balancer is migrating to the requested
          configuration.
                                Performance may be degraded.
          - `update_pending`: The load balancer is being updated
              to the requested configuration.
            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 load balancer on which the
            unexpected property value was encountered.
    :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 str resource_type: The resource type.
    :attr bool route_mode: Indicates whether route mode is enabled for this load
          balancer.
          At present, public load balancers are not supported with route mode enabled.
    :attr List[SecurityGroupReference] security_groups: The security groups
          targeting this load balancer.
          If empty, all inbound and outbound traffic is allowed.
          Applicable only for load balancers that support security groups.
    :attr bool security_groups_supported: Indicates whether this load balancer
          supports security groups.
    :attr List[SubnetReference] subnets: The subnets this load balancer is
          provisioned in.  The load balancer's availability depends on the availability of
          the zones that the subnets reside in.
          All subnets will be in the same VPC.
    :attr bool udp_supported: Indicates whether this load balancer supports UDP.
    """

    def __init__(
        self,
        created_at: datetime,
        crn: str,
        hostname: str,
        href: str,
        id: str,
        instance_groups_supported: bool,
        is_public: bool,
        listeners: List['LoadBalancerListenerReference'],
        logging: 'LoadBalancerLogging',
        name: str,
        operating_status: str,
        pools: List['LoadBalancerPoolReference'],
        private_ips: List['LoadBalancerPrivateIpsItem'],
        profile: 'LoadBalancerProfileReference',
        provisioning_status: str,
        public_ips: List['IP'],
        resource_group: 'ResourceGroupReference',
        resource_type: str,
        route_mode: bool,
        security_groups: List['SecurityGroupReference'],
        security_groups_supported: bool,
        subnets: List['SubnetReference'],
        udp_supported: bool,
        *,
        dns: 'LoadBalancerDNS' = None,
    ) -> 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 instance_groups_supported: Indicates whether this load balancer
               supports instance groups.
        :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 name for this load balancer. The name is unique across
               all load balancers in the VPC.
        :param str operating_status: The operating status of this load balancer.
        :param List[LoadBalancerPoolReference] pools: The pools of this load
               balancer.
        :param List[LoadBalancerPrivateIpsItem] private_ips: The private IP
               addresses assigned to this load balancer.
        :param LoadBalancerProfileReference profile: The profile for this load
               balancer.
        :param str provisioning_status: The provisioning status of this load
               balancer:
               - `active`: The load balancer is running.
               - `create_pending`: The load balancer is being created.
               - `delete_pending`: The load balancer is being deleted.
               - `maintenance_pending`: The load balancer is unavailable due to an
               internal
                                         error (contact IBM support).
               - `migrate_pending`: The load balancer is migrating to the requested
               configuration.
                                     Performance may be degraded.
               - `update_pending`: The load balancer is being updated
                   to the requested configuration.
                 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 load balancer on which
               the
                 unexpected property value was encountered.
        :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 str resource_type: The resource type.
        :param bool route_mode: Indicates whether route mode is enabled for this
               load balancer.
               At present, public load balancers are not supported with route mode
               enabled.
        :param List[SecurityGroupReference] security_groups: The security groups
               targeting this load balancer.
               If empty, all inbound and outbound traffic is allowed.
               Applicable only for load balancers that support security groups.
        :param bool security_groups_supported: Indicates whether this load balancer
               supports security groups.
        :param List[SubnetReference] subnets: The subnets this load balancer is
               provisioned in.  The load balancer's availability depends on the
               availability of the zones that the subnets reside in.
               All subnets will be in the same VPC.
        :param bool udp_supported: Indicates whether this load balancer supports
               UDP.
        :param LoadBalancerDNS dns: (optional) The DNS configuration for this load
               balancer.
               If absent, DNS `A` records for this load balancer's `hostname` property
               will be added to
               the public DNS zone `lb.appdomain.cloud`.
        """
        self.created_at = created_at
        self.crn = crn
        self.dns = dns
        self.hostname = hostname
        self.href = href
        self.id = id
        self.instance_groups_supported = instance_groups_supported
        self.is_public = is_public
        self.listeners = listeners
        self.logging = logging
        self.name = name
        self.operating_status = operating_status
        self.pools = pools
        self.private_ips = private_ips
        self.profile = profile
        self.provisioning_status = provisioning_status
        self.public_ips = public_ips
        self.resource_group = resource_group
        self.resource_type = resource_type
        self.route_mode = route_mode
        self.security_groups = security_groups
        self.security_groups_supported = security_groups_supported
        self.subnets = subnets
        self.udp_supported = udp_supported

    @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 'dns' in _dict:
            args['dns'] = LoadBalancerDNS.from_dict(_dict.get('dns'))
        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 'instance_groups_supported' in _dict:
            args['instance_groups_supported'] = _dict.get('instance_groups_supported')
        else:
            raise ValueError('Required property \'instance_groups_supported\' 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(v) for v 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(v) for v in _dict.get('pools')]
        else:
            raise ValueError('Required property \'pools\' not present in LoadBalancer JSON')
        if 'private_ips' in _dict:
            args['private_ips'] = [LoadBalancerPrivateIpsItem.from_dict(v) for v in _dict.get('private_ips')]
        else:
            raise ValueError('Required property \'private_ips\' not present in LoadBalancer JSON')
        if 'profile' in _dict:
            args['profile'] = LoadBalancerProfileReference.from_dict(_dict.get('profile'))
        else:
            raise ValueError('Required property \'profile\' not present in LoadBalancer JSON')
        if 'provisioning_status' in _dict:
            args['provisioning_status'] = _dict.get('provisioning_status')
        else:
            raise ValueError('Required property \'provisioning_status\' not present in LoadBalancer JSON')
        if 'public_ips' in _dict:
            args['public_ips'] = [IP.from_dict(v) for v 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 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError('Required property \'resource_type\' not present in LoadBalancer JSON')
        if 'route_mode' in _dict:
            args['route_mode'] = _dict.get('route_mode')
        else:
            raise ValueError('Required property \'route_mode\' not present in LoadBalancer JSON')
        if 'security_groups' in _dict:
            args['security_groups'] = [SecurityGroupReference.from_dict(v) for v in _dict.get('security_groups')]
        else:
            raise ValueError('Required property \'security_groups\' not present in LoadBalancer JSON')
        if 'security_groups_supported' in _dict:
            args['security_groups_supported'] = _dict.get('security_groups_supported')
        else:
            raise ValueError('Required property \'security_groups_supported\' not present in LoadBalancer JSON')
        if 'subnets' in _dict:
            args['subnets'] = [SubnetReference.from_dict(v) for v in _dict.get('subnets')]
        else:
            raise ValueError('Required property \'subnets\' not present in LoadBalancer JSON')
        if 'udp_supported' in _dict:
            args['udp_supported'] = _dict.get('udp_supported')
        else:
            raise ValueError('Required property \'udp_supported\' 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, 'dns') and self.dns is not None:
            if isinstance(self.dns, dict):
                _dict['dns'] = self.dns
            else:
                _dict['dns'] = self.dns.to_dict()
        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, 'instance_groups_supported') and self.instance_groups_supported is not None:
            _dict['instance_groups_supported'] = self.instance_groups_supported
        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:
            listeners_list = []
            for v in self.listeners:
                if isinstance(v, dict):
                    listeners_list.append(v)
                else:
                    listeners_list.append(v.to_dict())
            _dict['listeners'] = listeners_list
        if hasattr(self, 'logging') and self.logging is not None:
            if isinstance(self.logging, dict):
                _dict['logging'] = self.logging
            else:
                _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:
            pools_list = []
            for v in self.pools:
                if isinstance(v, dict):
                    pools_list.append(v)
                else:
                    pools_list.append(v.to_dict())
            _dict['pools'] = pools_list
        if hasattr(self, 'private_ips') and self.private_ips is not None:
            private_ips_list = []
            for v in self.private_ips:
                if isinstance(v, dict):
                    private_ips_list.append(v)
                else:
                    private_ips_list.append(v.to_dict())
            _dict['private_ips'] = private_ips_list
        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, '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:
            public_ips_list = []
            for v in self.public_ips:
                if isinstance(v, dict):
                    public_ips_list.append(v)
                else:
                    public_ips_list.append(v.to_dict())
            _dict['public_ips'] = public_ips_list
        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, 'resource_type') and self.resource_type is not None:
            _dict['resource_type'] = self.resource_type
        if hasattr(self, 'route_mode') and self.route_mode is not None:
            _dict['route_mode'] = self.route_mode
        if hasattr(self, 'security_groups') and self.security_groups is not None:
            security_groups_list = []
            for v in self.security_groups:
                if isinstance(v, dict):
                    security_groups_list.append(v)
                else:
                    security_groups_list.append(v.to_dict())
            _dict['security_groups'] = security_groups_list
        if hasattr(self, 'security_groups_supported') and self.security_groups_supported is not None:
            _dict['security_groups_supported'] = self.security_groups_supported
        if hasattr(self, 'subnets') and self.subnets is not None:
            subnets_list = []
            for v in self.subnets:
                if isinstance(v, dict):
                    subnets_list.append(v)
                else:
                    subnets_list.append(v.to_dict())
            _dict['subnets'] = subnets_list
        if hasattr(self, 'udp_supported') and self.udp_supported is not None:
            _dict['udp_supported'] = self.udp_supported
        return _dict

    def _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`: The load balancer is running.
        - `create_pending`: The load balancer is being created.
        - `delete_pending`: The load balancer is being deleted.
        - `maintenance_pending`: The load balancer is unavailable due to an internal
                                  error (contact IBM support).
        - `migrate_pending`: The load balancer is migrating to the requested
        configuration.
                              Performance may be degraded.
        - `update_pending`: The load balancer is being updated
            to the requested configuration.
          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 load balancer on which the
          unexpected property value was encountered.
        """

        ACTIVE = 'active'
        CREATE_PENDING = 'create_pending'
        DELETE_PENDING = 'delete_pending'
        FAILED = 'failed'
        MAINTENANCE_PENDING = 'maintenance_pending'
        MIGRATE_PENDING = 'migrate_pending'
        UPDATE_PENDING = 'update_pending'


    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        LOAD_BALANCER = 'load_balancer'



class LoadBalancerCollection:
    """
    LoadBalancerCollection.

    :attr LoadBalancerCollectionFirst 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[LoadBalancer] load_balancers: Collection of load balancers.
    :attr LoadBalancerCollectionNext 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: 'LoadBalancerCollectionFirst',
        limit: int,
        load_balancers: List['LoadBalancer'],
        total_count: int,
        *,
        next: 'LoadBalancerCollectionNext' = None,
    ) -> None:
        """
        Initialize a LoadBalancerCollection object.

        :param LoadBalancerCollectionFirst 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[LoadBalancer] load_balancers: Collection of load balancers.
        :param int total_count: The total number of resources across all pages.
        :param LoadBalancerCollectionNext 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.load_balancers = load_balancers
        self.next = next
        self.total_count = total_count

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerCollection':
        """Initialize a LoadBalancerCollection object from a json dictionary."""
        args = {}
        if 'first' in _dict:
            args['first'] = LoadBalancerCollectionFirst.from_dict(_dict.get('first'))
        else:
            raise ValueError('Required property \'first\' not present in LoadBalancerCollection JSON')
        if 'limit' in _dict:
            args['limit'] = _dict.get('limit')
        else:
            raise ValueError('Required property \'limit\' not present in LoadBalancerCollection JSON')
        if 'load_balancers' in _dict:
            args['load_balancers'] = [LoadBalancer.from_dict(v) for v in _dict.get('load_balancers')]
        else:
            raise ValueError('Required property \'load_balancers\' not present in LoadBalancerCollection JSON')
        if 'next' in _dict:
            args['next'] = LoadBalancerCollectionNext.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 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, 'first') and self.first is not None:
            if isinstance(self.first, dict):
                _dict['first'] = self.first
            else:
                _dict['first'] = self.first.to_dict()
        if hasattr(self, 'limit') and self.limit is not None:
            _dict['limit'] = self.limit
        if hasattr(self, 'load_balancers') and self.load_balancers is not None:
            load_balancers_list = []
            for v in self.load_balancers:
                if isinstance(v, dict):
                    load_balancers_list.append(v)
                else:
                    load_balancers_list.append(v.to_dict())
            _dict['load_balancers'] = load_balancers_list
        if hasattr(self, 'next') and self.next is not None:
            if isinstance(self.next, dict):
                _dict['next'] = self.next
            else:
                _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 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 LoadBalancerCollectionFirst:
    """
    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 LoadBalancerCollectionFirst object.

        :param str href: The URL for a page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerCollectionFirst':
        """Initialize a LoadBalancerCollectionFirst object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in LoadBalancerCollectionFirst JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerCollectionFirst object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(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 LoadBalancerCollectionFirst object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerCollectionFirst') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerCollectionFirst') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class LoadBalancerCollectionNext:
    """
    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 LoadBalancerCollectionNext object.

        :param str href: The URL for a page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerCollectionNext':
        """Initialize a LoadBalancerCollectionNext object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in LoadBalancerCollectionNext JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerCollectionNext object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(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 LoadBalancerCollectionNext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerCollectionNext') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerCollectionNext') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class LoadBalancerDNS:
    """
    The DNS configuration for this load balancer.
    If absent, DNS `A` records for this load balancer's `hostname` property will be added
    to the public DNS zone `lb.appdomain.cloud`.

    :attr DNSInstanceReference instance: The DNS instance associated with this load
          balancer.
    :attr DNSZoneReference zone: The DNS zone associated with this load balancer.
    """

    def __init__(
        self,
        instance: 'DNSInstanceReference',
        zone: 'DNSZoneReference',
    ) -> None:
        """
        Initialize a LoadBalancerDNS object.

        :param DNSInstanceReference instance: The DNS instance associated with this
               load balancer.
        :param DNSZoneReference zone: The DNS zone associated with this load
               balancer.
        """
        self.instance = instance
        self.zone = zone

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerDNS':
        """Initialize a LoadBalancerDNS object from a json dictionary."""
        args = {}
        if 'instance' in _dict:
            args['instance'] = DNSInstanceReference.from_dict(_dict.get('instance'))
        else:
            raise ValueError('Required property \'instance\' not present in LoadBalancerDNS JSON')
        if 'zone' in _dict:
            args['zone'] = DNSZoneReference.from_dict(_dict.get('zone'))
        else:
            raise ValueError('Required property \'zone\' not present in LoadBalancerDNS JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerDNS object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'instance') and self.instance is not None:
            if isinstance(self.instance, dict):
                _dict['instance'] = self.instance
            else:
                _dict['instance'] = self.instance.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 LoadBalancerDNS object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerDNS') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerDNS') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class LoadBalancerDNSPatch:
    """
    The DNS configuration for this load balancer.
    Specify `null` to remove the existing DNS configuration, which will remove all DNS `A`
    records for this load balancer that had been added to `zone`, and add equivalent `A`
    records to the public DNS zone `lb.appdomain.cloud`.

    :attr DNSInstanceIdentity instance: (optional) The DNS instance to associate
          with this load balancer.
          The specified instance may be in a different region or account, subject to IAM
          policies.
    :attr DNSZoneIdentity zone: (optional) The DNS zone to associate with this load
          balancer.
          The specified zone may be in a different region or account, subject to IAM
          policies.
    """

    def __init__(
        self,
        *,
        instance: 'DNSInstanceIdentity' = None,
        zone: 'DNSZoneIdentity' = None,
    ) -> None:
        """
        Initialize a LoadBalancerDNSPatch object.

        :param DNSInstanceIdentity instance: (optional) The DNS instance to
               associate with this load balancer.
               The specified instance may be in a different region or account, subject to
               IAM
               policies.
        :param DNSZoneIdentity zone: (optional) The DNS zone to associate with this
               load balancer.
               The specified zone may be in a different region or account, subject to IAM
               policies.
        """
        self.instance = instance
        self.zone = zone

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerDNSPatch':
        """Initialize a LoadBalancerDNSPatch object from a json dictionary."""
        args = {}
        if 'instance' in _dict:
            args['instance'] = _dict.get('instance')
        if 'zone' in _dict:
            args['zone'] = _dict.get('zone')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerDNSPatch object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'instance') and self.instance is not None:
            if isinstance(self.instance, dict):
                _dict['instance'] = self.instance
            else:
                _dict['instance'] = self.instance.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 LoadBalancerDNSPatch object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerDNSPatch') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerDNSPatch') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class LoadBalancerDNSPrototype:
    """
    The DNS configuration for this load balancer.
    If unspecified, DNS `A` records for this load balancer's `hostname` property will be
    added to the public DNS zone `lb.appdomain.cloud`. Otherwise, those DNS `A` records
    will be added to the specified `zone`.

    :attr DNSInstanceIdentity instance: The DNS instance to associate with this load
          balancer.
          The specified instance may be in a different region or account, subject to IAM
          policies.
    :attr DNSZoneIdentity zone: The DNS zone to associate with this load balancer.
          The specified zone may be in a different region or account, subject to IAM
          policies.
    """

    def __init__(
        self,
        instance: 'DNSInstanceIdentity',
        zone: 'DNSZoneIdentity',
    ) -> None:
        """
        Initialize a LoadBalancerDNSPrototype object.

        :param DNSInstanceIdentity instance: The DNS instance to associate with
               this load balancer.
               The specified instance may be in a different region or account, subject to
               IAM
               policies.
        :param DNSZoneIdentity zone: The DNS zone to associate with this load
               balancer.
               The specified zone may be in a different region or account, subject to IAM
               policies.
        """
        self.instance = instance
        self.zone = zone

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerDNSPrototype':
        """Initialize a LoadBalancerDNSPrototype object from a json dictionary."""
        args = {}
        if 'instance' in _dict:
            args['instance'] = _dict.get('instance')
        else:
            raise ValueError('Required property \'instance\' not present in LoadBalancerDNSPrototype JSON')
        if 'zone' in _dict:
            args['zone'] = _dict.get('zone')
        else:
            raise ValueError('Required property \'zone\' not present in LoadBalancerDNSPrototype JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerDNSPrototype object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'instance') and self.instance is not None:
            if isinstance(self.instance, dict):
                _dict['instance'] = self.instance
            else:
                _dict['instance'] = self.instance.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 LoadBalancerDNSPrototype object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerDNSPrototype') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerDNSPrototype') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class LoadBalancerIdentity:
    """
    Identifies a load balancer by a unique property.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a LoadBalancerIdentity object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['LoadBalancerIdentityById', 'LoadBalancerIdentityByCRN', 'LoadBalancerIdentityByHref'])
        )
        raise Exception(msg)


class LoadBalancerListener:
    """
    LoadBalancerListener.

    :attr bool accept_proxy_protocol: If set to `true`, this listener will accept
          and forward PROXY protocol information. Supported by load balancers in the
          `application` family (otherwise always `false`). Additional restrictions:
          - If this listener has `https_redirect` specified, its `accept_proxy_protocol`
          value must
            match the `accept_proxy_protocol` value of the `https_redirect` listener.
          - If this listener is the target of another listener's `https_redirect`, its
            `accept_proxy_protocol` value must match that listener's
          `accept_proxy_protocol` value.
    :attr CertificateInstanceReference certificate_instance: (optional) The
          certificate instance used for SSL termination.
          If absent, this listener is not using a certificate instance.
    :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 for
          this listener. If absent, this listener has no default pool.
    :attr str href: The listener's canonical URL.
    :attr LoadBalancerListenerHTTPSRedirect https_redirect: (optional) If present,
          the target listener that requests are redirected to.
    :attr str id: The unique identifier for this load balancer listener.
    :attr int idle_connection_timeout: (optional) The idle connection timeout of the
          listener in seconds. This property will be present for load balancers in the
          `application` family.
    :attr List[LoadBalancerListenerPolicyReference] policies: (optional) The
          policies for this listener.
    :attr int port: The listener port number, or the inclusive lower bound of the
          port range.
    :attr int port_max: The inclusive upper bound of the range of ports used by this
          listener.
          At present, only load balancers in the `network` family support more than one
          port per listener.
    :attr int port_min: The inclusive lower bound of the range of ports used by this
          listener.
          At present, only load balancers in the `network` family support more than one
          port per listener.
    :attr str protocol: The listener protocol.
          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 listener on which the unexpected
          property value was encountered.
    :attr str provisioning_status: The provisioning status of this listener
          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 listener on which the unexpected
          property value was encountered.
    """

    def __init__(
        self,
        accept_proxy_protocol: bool,
        created_at: datetime,
        href: str,
        id: str,
        port: int,
        port_max: int,
        port_min: int,
        protocol: str,
        provisioning_status: str,
        *,
        certificate_instance: 'CertificateInstanceReference' = None,
        connection_limit: int = None,
        default_pool: 'LoadBalancerPoolReference' = None,
        https_redirect: 'LoadBalancerListenerHTTPSRedirect' = None,
        idle_connection_timeout: int = 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`). Additional
               restrictions:
               - If this listener has `https_redirect` specified, its
               `accept_proxy_protocol` value must
                 match the `accept_proxy_protocol` value of the `https_redirect` listener.
               - If this listener is the target of another listener's `https_redirect`,
               its
                 `accept_proxy_protocol` value must match that listener's
               `accept_proxy_protocol` value.
        :param datetime created_at: The date and time that this listener was
               created.
        :param str href: The listener's canonical URL.
        :param str id: The unique identifier for this load balancer listener.
        :param int port: The listener port number, or the inclusive lower bound of
               the port range.
        :param int port_max: The inclusive upper bound of the range of ports used
               by this listener.
               At present, only load balancers in the `network` family support more than
               one port per listener.
        :param int port_min: The inclusive lower bound of the range of ports used
               by this listener.
               At present, only load balancers in the `network` family support more than
               one port per listener.
        :param str protocol: The listener protocol.
               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 listener on
               which the unexpected property value was encountered.
        :param str provisioning_status: The provisioning status of this listener
               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 listener on
               which the unexpected property value was encountered.
        :param CertificateInstanceReference certificate_instance: (optional) The
               certificate instance used for SSL termination.
               If absent, this listener is not using a certificate instance.
        :param int connection_limit: (optional) The connection limit of the
               listener.
        :param LoadBalancerPoolReference default_pool: (optional) The default pool
               for this listener. If absent, this listener has no default pool.
        :param LoadBalancerListenerHTTPSRedirect https_redirect: (optional) If
               present, the target listener that requests are redirected to.
        :param int idle_connection_timeout: (optional) The idle connection timeout
               of the listener in seconds. This property will be present for load
               balancers in the `application` family.
        :param List[LoadBalancerListenerPolicyReference] policies: (optional) The
               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.https_redirect = https_redirect
        self.id = id
        self.idle_connection_timeout = idle_connection_timeout
        self.policies = policies
        self.port = port
        self.port_max = port_max
        self.port_min = port_min
        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 'https_redirect' in _dict:
            args['https_redirect'] = LoadBalancerListenerHTTPSRedirect.from_dict(_dict.get('https_redirect'))
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in LoadBalancerListener JSON')
        if 'idle_connection_timeout' in _dict:
            args['idle_connection_timeout'] = _dict.get('idle_connection_timeout')
        if 'policies' in _dict:
            args['policies'] = [LoadBalancerListenerPolicyReference.from_dict(v) for v 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 'port_max' in _dict:
            args['port_max'] = _dict.get('port_max')
        else:
            raise ValueError('Required property \'port_max\' not present in LoadBalancerListener JSON')
        if 'port_min' in _dict:
            args['port_min'] = _dict.get('port_min')
        else:
            raise ValueError('Required property \'port_min\' 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:
            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, '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:
            if isinstance(self.default_pool, dict):
                _dict['default_pool'] = self.default_pool
            else:
                _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, 'https_redirect') and self.https_redirect is not None:
            if isinstance(self.https_redirect, dict):
                _dict['https_redirect'] = self.https_redirect
            else:
                _dict['https_redirect'] = self.https_redirect.to_dict()
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'idle_connection_timeout') and self.idle_connection_timeout is not None:
            _dict['idle_connection_timeout'] = self.idle_connection_timeout
        if hasattr(self, 'policies') and self.policies is not None:
            policies_list = []
            for v in self.policies:
                if isinstance(v, dict):
                    policies_list.append(v)
                else:
                    policies_list.append(v.to_dict())
            _dict['policies'] = policies_list
        if hasattr(self, 'port') and self.port is not None:
            _dict['port'] = self.port
        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, '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.
        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 listener on which the unexpected
        property value was encountered.
        """

        HTTP = 'http'
        HTTPS = 'https'
        TCP = 'tcp'
        UDP = 'udp'


    class ProvisioningStatusEnum(str, Enum):
        """
        The provisioning status of this listener
        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 listener on which the unexpected
        property value was encountered.
        """

        ACTIVE = 'active'
        CREATE_PENDING = 'create_pending'
        DELETE_PENDING = 'delete_pending'
        FAILED = 'failed'
        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(v) for v 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:
            listeners_list = []
            for v in self.listeners:
                if isinstance(v, dict):
                    listeners_list.append(v)
                else:
                    listeners_list.append(v.to_dict())
            _dict['listeners'] = listeners_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 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 LoadBalancerListenerHTTPSRedirect:
    """
    LoadBalancerListenerHTTPSRedirect.

    :attr int http_status_code: The HTTP status code for this redirect.
    :attr LoadBalancerListenerReference listener:
    :attr str uri: (optional) The redirect relative target URI.
    """

    def __init__(
        self,
        http_status_code: int,
        listener: 'LoadBalancerListenerReference',
        *,
        uri: str = None,
    ) -> None:
        """
        Initialize a LoadBalancerListenerHTTPSRedirect object.

        :param int http_status_code: The HTTP status code for this redirect.
        :param LoadBalancerListenerReference listener:
        :param str uri: (optional) The redirect relative target URI.
        """
        self.http_status_code = http_status_code
        self.listener = listener
        self.uri = uri

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerListenerHTTPSRedirect':
        """Initialize a LoadBalancerListenerHTTPSRedirect 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 LoadBalancerListenerHTTPSRedirect JSON')
        if 'listener' in _dict:
            args['listener'] = LoadBalancerListenerReference.from_dict(_dict.get('listener'))
        else:
            raise ValueError('Required property \'listener\' not present in LoadBalancerListenerHTTPSRedirect JSON')
        if 'uri' in _dict:
            args['uri'] = _dict.get('uri')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerListenerHTTPSRedirect object from 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, 'listener') and self.listener is not None:
            if isinstance(self.listener, dict):
                _dict['listener'] = self.listener
            else:
                _dict['listener'] = self.listener.to_dict()
        if hasattr(self, 'uri') and self.uri is not None:
            _dict['uri'] = self.uri
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancerListenerHTTPSRedirect object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerListenerHTTPSRedirect') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerListenerHTTPSRedirect') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class LoadBalancerListenerHTTPSRedirectPatch:
    """
    LoadBalancerListenerHTTPSRedirectPatch.

    :attr int http_status_code: (optional) The HTTP status code for this redirect.
    :attr LoadBalancerListenerIdentity listener: (optional) Identifies a load
          balancer listener by a unique property.
    :attr str uri: (optional) The redirect relative target URI.
    """

    def __init__(
        self,
        *,
        http_status_code: int = None,
        listener: 'LoadBalancerListenerIdentity' = None,
        uri: str = None,
    ) -> None:
        """
        Initialize a LoadBalancerListenerHTTPSRedirectPatch object.

        :param int http_status_code: (optional) The HTTP status code for this
               redirect.
        :param LoadBalancerListenerIdentity listener: (optional) Identifies a load
               balancer listener by a unique property.
        :param str uri: (optional) The redirect relative target URI.
        """
        self.http_status_code = http_status_code
        self.listener = listener
        self.uri = uri

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerListenerHTTPSRedirectPatch':
        """Initialize a LoadBalancerListenerHTTPSRedirectPatch object from a json dictionary."""
        args = {}
        if 'http_status_code' in _dict:
            args['http_status_code'] = _dict.get('http_status_code')
        if 'listener' in _dict:
            args['listener'] = _dict.get('listener')
        if 'uri' in _dict:
            args['uri'] = _dict.get('uri')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerListenerHTTPSRedirectPatch object from 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, 'listener') and self.listener is not None:
            if isinstance(self.listener, dict):
                _dict['listener'] = self.listener
            else:
                _dict['listener'] = self.listener.to_dict()
        if hasattr(self, 'uri') and self.uri is not None:
            _dict['uri'] = self.uri
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancerListenerHTTPSRedirectPatch object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerListenerHTTPSRedirectPatch') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerListenerHTTPSRedirectPatch') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class LoadBalancerListenerHTTPSRedirectPrototype:
    """
    LoadBalancerListenerHTTPSRedirectPrototype.

    :attr int http_status_code: The HTTP status code for this redirect.
    :attr LoadBalancerListenerIdentity listener: Identifies a load balancer listener
          by a unique property.
    :attr str uri: (optional) The redirect relative target URI.
    """

    def __init__(
        self,
        http_status_code: int,
        listener: 'LoadBalancerListenerIdentity',
        *,
        uri: str = None,
    ) -> None:
        """
        Initialize a LoadBalancerListenerHTTPSRedirectPrototype object.

        :param int http_status_code: The HTTP status code for this redirect.
        :param LoadBalancerListenerIdentity listener: Identifies a load balancer
               listener by a unique property.
        :param str uri: (optional) The redirect relative target URI.
        """
        self.http_status_code = http_status_code
        self.listener = listener
        self.uri = uri

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerListenerHTTPSRedirectPrototype':
        """Initialize a LoadBalancerListenerHTTPSRedirectPrototype 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 LoadBalancerListenerHTTPSRedirectPrototype JSON')
        if 'listener' in _dict:
            args['listener'] = _dict.get('listener')
        else:
            raise ValueError('Required property \'listener\' not present in LoadBalancerListenerHTTPSRedirectPrototype JSON')
        if 'uri' in _dict:
            args['uri'] = _dict.get('uri')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerListenerHTTPSRedirectPrototype object from 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, 'listener') and self.listener is not None:
            if isinstance(self.listener, dict):
                _dict['listener'] = self.listener
            else:
                _dict['listener'] = self.listener.to_dict()
        if hasattr(self, 'uri') and self.uri is not None:
            _dict['uri'] = self.uri
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancerListenerHTTPSRedirectPrototype object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerListenerHTTPSRedirectPrototype') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerListenerHTTPSRedirectPrototype') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class LoadBalancerListenerIdentity:
    """
    Identifies a load balancer listener by a unique property.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a LoadBalancerListenerIdentity object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['LoadBalancerListenerIdentityById', 'LoadBalancerListenerIdentityByHref'])
        )
        raise Exception(msg)


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`). Additional restrictions:
          - If this listener has `https_redirect` specified, its `accept_proxy_protocol`
          value must
            match the `accept_proxy_protocol` value of the `https_redirect` listener.
          - If this listener is the target of another listener's `https_redirect`, its
            `accept_proxy_protocol` value must match that listener's
          `accept_proxy_protocol` value.
    :attr CertificateInstanceIdentity certificate_instance: (optional) The
          certificate instance to use for SSL termination. The listener must have a
          `protocol` of `https`.
    :attr int connection_limit: (optional) The connection limit of the listener.
    :attr LoadBalancerPoolIdentity default_pool: (optional) The default pool for
          this listener. The specified pool must:
          - Belong to this load balancer
          - Have the same `protocol` as this listener, or have a compatible protocol.
            At present, the compatible protocols are `http` and `https`.
          - Not already be the `default_pool` for another listener
          Specify `null` to remove an existing default pool.
    :attr LoadBalancerListenerHTTPSRedirectPatch https_redirect: (optional) The
          target listener that requests will be redirected to. This listener must have a
          `protocol` of `http`, and the target listener must have a `protocol` of `https`.
          Specify `null` to remove any existing https redirect.
    :attr int idle_connection_timeout: (optional) The idle connection timeout of the
          listener in seconds. Supported for load balancers in the `application` family.
    :attr int port: (optional) The listener port number, or the inclusive lower
          bound of the port range. Each listener in the load balancer must have a unique
          `port` and `protocol` combination.
          Not supported for load balancers operating with route mode enabled.
    :attr int port_max: (optional) The inclusive upper bound of the range of ports
          used by this listener. Must not be less than `port_min`.
          At present, only load balancers operating with route mode enabled, and public
          load balancers in the `network` family support different values for `port_min`
          and
          `port_max`. When route mode is enabled, the value `65535` must be specified.
          The specified port range must not overlap with port ranges used by other
          listeners for this load balancer using the same protocol.
    :attr int port_min: (optional) The inclusive lower bound of the range of ports
          used by this listener. Must not be greater than `port_max`.
          At present, only load balancers operating with route mode enabled, and public
          load balancers in the `network` family support different values for `port_min`
          and
          `port_max`. When route mode is enabled, the value `1` must be specified.
          The specified port range must not overlap with port ranges used by other
          listeners for this load balancer using the same protocol.
    :attr str protocol: (optional) The listener protocol. Each listener in the load
          balancer must have a unique `port` and `protocol` combination.
          Load balancers in the `network` family support `tcp` and `udp` (if
          `udp_supported` is `true`). Load balancers in the `application` family support
          `tcp`, `http` and
          `https`.
          Additional restrictions:
          - If `default_pool` is set, the protocol cannot be changed.
          - If `https_redirect` is set, the protocol must be `http`.
          - If another listener's `https_redirect` targets this listener, the protocol
          must be
          `https`.
    """

    def __init__(
        self,
        *,
        accept_proxy_protocol: bool = None,
        certificate_instance: 'CertificateInstanceIdentity' = None,
        connection_limit: int = None,
        default_pool: 'LoadBalancerPoolIdentity' = None,
        https_redirect: 'LoadBalancerListenerHTTPSRedirectPatch' = None,
        idle_connection_timeout: int = None,
        port: int = None,
        port_max: int = None,
        port_min: 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`).
               Additional restrictions:
               - If this listener has `https_redirect` specified, its
               `accept_proxy_protocol` value must
                 match the `accept_proxy_protocol` value of the `https_redirect` listener.
               - If this listener is the target of another listener's `https_redirect`,
               its
                 `accept_proxy_protocol` value must match that listener's
               `accept_proxy_protocol` value.
        :param CertificateInstanceIdentity certificate_instance: (optional) The
               certificate instance to use for SSL termination. The listener must have a
               `protocol` of `https`.
        :param int connection_limit: (optional) The connection limit of the
               listener.
        :param LoadBalancerPoolIdentity default_pool: (optional) The default pool
               for this listener. The specified pool must:
               - Belong to this load balancer
               - Have the same `protocol` as this listener, or have a compatible protocol.
                 At present, the compatible protocols are `http` and `https`.
               - Not already be the `default_pool` for another listener
               Specify `null` to remove an existing default pool.
        :param LoadBalancerListenerHTTPSRedirectPatch https_redirect: (optional)
               The target listener that requests will be redirected to. This listener must
               have a
               `protocol` of `http`, and the target listener must have a `protocol` of
               `https`.
               Specify `null` to remove any existing https redirect.
        :param int idle_connection_timeout: (optional) The idle connection timeout
               of the listener in seconds. Supported for load balancers in the
               `application` family.
        :param int port: (optional) The listener port number, or the inclusive
               lower bound of the port range. Each listener in the load balancer must have
               a unique `port` and `protocol` combination.
               Not supported for load balancers operating with route mode enabled.
        :param int port_max: (optional) The inclusive upper bound of the range of
               ports used by this listener. Must not be less than `port_min`.
               At present, only load balancers operating with route mode enabled, and
               public load balancers in the `network` family support different values for
               `port_min` and
               `port_max`. When route mode is enabled, the value `65535` must be
               specified.
               The specified port range must not overlap with port ranges used by other
               listeners for this load balancer using the same protocol.
        :param int port_min: (optional) The inclusive lower bound of the range of
               ports used by this listener. Must not be greater than `port_max`.
               At present, only load balancers operating with route mode enabled, and
               public load balancers in the `network` family support different values for
               `port_min` and
               `port_max`. When route mode is enabled, the value `1` must be specified.
               The specified port range must not overlap with port ranges used by other
               listeners for this load balancer using the same protocol.
        :param str protocol: (optional) The listener protocol. Each listener in the
               load balancer must have a unique `port` and `protocol` combination.
               Load balancers in the `network` family support `tcp` and `udp` (if
               `udp_supported` is `true`). Load balancers in the `application` family
               support `tcp`, `http` and
               `https`.
               Additional restrictions:
               - If `default_pool` is set, the protocol cannot be changed.
               - If `https_redirect` is set, the protocol must be `http`.
               - If another listener's `https_redirect` targets this listener, the
               protocol must be
               `https`.
        """
        self.accept_proxy_protocol = accept_proxy_protocol
        self.certificate_instance = certificate_instance
        self.connection_limit = connection_limit
        self.default_pool = default_pool
        self.https_redirect = https_redirect
        self.idle_connection_timeout = idle_connection_timeout
        self.port = port
        self.port_max = port_max
        self.port_min = port_min
        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 'https_redirect' in _dict:
            args['https_redirect'] = LoadBalancerListenerHTTPSRedirectPatch.from_dict(_dict.get('https_redirect'))
        if 'idle_connection_timeout' in _dict:
            args['idle_connection_timeout'] = _dict.get('idle_connection_timeout')
        if 'port' in _dict:
            args['port'] = _dict.get('port')
        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')
        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, 'https_redirect') and self.https_redirect is not None:
            if isinstance(self.https_redirect, dict):
                _dict['https_redirect'] = self.https_redirect
            else:
                _dict['https_redirect'] = self.https_redirect.to_dict()
        if hasattr(self, 'idle_connection_timeout') and self.idle_connection_timeout is not None:
            _dict['idle_connection_timeout'] = self.idle_connection_timeout
        if hasattr(self, 'port') and self.port is not None:
            _dict['port'] = self.port
        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 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. Each listener in the load balancer must have a unique
        `port` and `protocol` combination.
        Load balancers in the `network` family support `tcp` and `udp` (if `udp_supported`
        is `true`). Load balancers in the `application` family support `tcp`, `http` and
        `https`.
        Additional restrictions:
        - If `default_pool` is set, the protocol cannot be changed.
        - If `https_redirect` is set, the protocol must be `http`.
        - If another listener's `https_redirect` targets this listener, the protocol must
        be
        `https`.
        """

        HTTP = 'http'
        HTTPS = 'https'
        TCP = 'tcp'
        UDP = 'udp'



class LoadBalancerListenerPolicy:
    """
    LoadBalancerListenerPolicy.

    :attr str action: The policy action.
          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 policy on which the unexpected
          property value was encountered.
    :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 name for this load balancer listener policy. The name is
          unique across all policies for the load balancer listener.
    :attr int priority: Priority of the policy. Lower value indicates higher
          priority.
    :attr str provisioning_status: The provisioning status of this policy
          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 policy on which the unexpected
          property value was encountered.
    :attr List[LoadBalancerListenerPolicyRuleReference] rules: The rules for this
          policy.
    :attr LoadBalancerListenerPolicyTarget target: (optional) - If `action` is
          `forward`, the response is a `LoadBalancerPoolReference`
          - If `action` is `redirect`, the response is a
          `LoadBalancerListenerPolicyRedirectURL`
          - If `action` is `https_redirect`, the response is a
          `LoadBalancerListenerHTTPSRedirect`.
    """

    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.
               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 policy on
               which the unexpected property value was encountered.
        :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 name for this load balancer listener policy. The name
               is unique across all policies for the load balancer listener.
        :param int priority: Priority of the policy. Lower value indicates higher
               priority.
        :param str provisioning_status: The provisioning status of this policy
               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 policy on
               which the unexpected property value was encountered.
        :param List[LoadBalancerListenerPolicyRuleReference] rules: The rules for
               this policy.
        :param LoadBalancerListenerPolicyTarget target: (optional) - If `action` is
               `forward`, the response is a `LoadBalancerPoolReference`
               - If `action` is `redirect`, the response is a
               `LoadBalancerListenerPolicyRedirectURL`
               - If `action` is `https_redirect`, the response is a
               `LoadBalancerListenerHTTPSRedirect`.
        """
        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(v) for v 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:
            rules_list = []
            for v in self.rules:
                if isinstance(v, dict):
                    rules_list.append(v)
                else:
                    rules_list.append(v.to_dict())
            _dict['rules'] = rules_list
        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.
        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 policy on which the unexpected
        property value was encountered.
        """

        FORWARD = 'forward'
        HTTPS_REDIRECT = 'https_redirect'
        REDIRECT = 'redirect'
        REJECT = 'reject'


    class ProvisioningStatusEnum(str, Enum):
        """
        The provisioning status of this policy
        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 policy on which the unexpected
        property value was encountered.
        """

        ACTIVE = 'active'
        CREATE_PENDING = 'create_pending'
        DELETE_PENDING = 'delete_pending'
        FAILED = 'failed'
        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(v) for v 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:
            policies_list = []
            for v in self.policies:
                if isinstance(v, dict):
                    policies_list.append(v)
                else:
                    policies_list.append(v.to_dict())
            _dict['policies'] = policies_list
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this 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 name for this policy. The name must not be used
          by another policy for the load balancer listener.
    :attr int priority: (optional) Priority of the policy. Lower value indicates
          higher priority.
    :attr LoadBalancerListenerPolicyTargetPatch target: (optional) - If `action` is
          `forward`, specify a `LoadBalancerPoolIdentity`.
          - If `action` is `redirect`, specify a
          `LoadBalancerListenerPolicyRedirectURLPatch`.
          - If `action` is `https_redirect`, specify a
            `LoadBalancerListenerPolicyHTTPSRedirectPatch`.
    """

    def __init__(
        self,
        *,
        name: str = None,
        priority: int = None,
        target: 'LoadBalancerListenerPolicyTargetPatch' = None,
    ) -> None:
        """
        Initialize a LoadBalancerListenerPolicyPatch object.

        :param str name: (optional) The name for this policy. The name must not be
               used by another policy for the load balancer listener.
        :param int priority: (optional) Priority of the policy. Lower value
               indicates higher priority.
        :param LoadBalancerListenerPolicyTargetPatch target: (optional) - If
               `action` is `forward`, specify a `LoadBalancerPoolIdentity`.
               - If `action` is `redirect`, specify a
               `LoadBalancerListenerPolicyRedirectURLPatch`.
               - If `action` is `https_redirect`, specify a
                 `LoadBalancerListenerPolicyHTTPSRedirectPatch`.
        """
        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.
          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 policy on which the unexpected
          property value was encountered.
    :attr str name: (optional) The name for this policy. The name must not be used
          by another policy for the load balancer listener. If unspecified, the name will
          be a hyphenated list of randomly-selected words.
    :attr int priority: Priority of the policy. Lower value indicates higher
          priority.
    :attr List[LoadBalancerListenerPolicyRulePrototype] rules: (optional) The rule
          prototype objects for this policy.
    :attr LoadBalancerListenerPolicyTargetPrototype target: (optional) - If `action`
          is `forward`, specify a `LoadBalancerPoolIdentity`.
          - If `action` is `redirect`, specify a
          `LoadBalancerListenerPolicyRedirectURLPrototype`.
          - If `action` is `https_redirect`, specify a
            `LoadBalancerListenerPolicyHTTPSRedirectPrototype`.
    """

    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.
               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 policy on
               which the unexpected property value was encountered.
        :param int priority: Priority of the policy. Lower value indicates higher
               priority.
        :param str name: (optional) The name for this policy. The name must not be
               used by another policy for the load balancer listener. If unspecified, the
               name will be a hyphenated list of randomly-selected words.
        :param List[LoadBalancerListenerPolicyRulePrototype] rules: (optional) The
               rule prototype objects for this policy.
        :param LoadBalancerListenerPolicyTargetPrototype target: (optional) - If
               `action` is `forward`, specify a `LoadBalancerPoolIdentity`.
               - If `action` is `redirect`, specify a
               `LoadBalancerListenerPolicyRedirectURLPrototype`.
               - If `action` is `https_redirect`, specify a
                 `LoadBalancerListenerPolicyHTTPSRedirectPrototype`.
        """
        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(v) for v 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:
            rules_list = []
            for v in self.rules:
                if isinstance(v, dict):
                    rules_list.append(v)
                else:
                    rules_list.append(v.to_dict())
            _dict['rules'] = rules_list
        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.
        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 policy on which the unexpected
        property value was encountered.
        """

        FORWARD = 'forward'
        HTTPS_REDIRECT = 'https_redirect'
        REDIRECT = 'redirect'
        REJECT = 'reject'



class LoadBalancerListenerPolicyReference:
    """
    LoadBalancerListenerPolicyReference.

    :attr LoadBalancerListenerPolicyReferenceDeleted deleted: (optional) If present,
          this property indicates the referenced resource has been deleted, and provides
          some supplementary information.
    :attr str href: The listener policy's canonical URL.
    :attr str id: The policy's unique identifier.
    :attr object name:
    """

    def __init__(
        self,
        href: str,
        id: str,
        name: object,
        *,
        deleted: 'LoadBalancerListenerPolicyReferenceDeleted' = None,
    ) -> None:
        """
        Initialize a LoadBalancerListenerPolicyReference object.

        :param str href: The listener policy's canonical URL.
        :param str id: The policy's unique identifier.
        :param object name:
        :param LoadBalancerListenerPolicyReferenceDeleted deleted: (optional) If
               present, this property indicates the referenced resource has been deleted,
               and provides
               some supplementary information.
        """
        self.deleted = deleted
        self.href = href
        self.id = id
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerListenerPolicyReference':
        """Initialize a LoadBalancerListenerPolicyReference object from a json dictionary."""
        args = {}
        if 'deleted' in _dict:
            args['deleted'] = LoadBalancerListenerPolicyReferenceDeleted.from_dict(_dict.get('deleted'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in LoadBalancerListenerPolicyReference JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in LoadBalancerListenerPolicyReference JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in LoadBalancerListenerPolicyReference JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerListenerPolicyReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'deleted') and self.deleted is not None:
            if isinstance(self.deleted, dict):
                _dict['deleted'] = self.deleted
            else:
                _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancerListenerPolicyReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerListenerPolicyReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerListenerPolicyReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class LoadBalancerListenerPolicyReferenceDeleted:
    """
    If present, this property indicates the referenced resource has been deleted, and
    provides some supplementary information.

    :attr str more_info: Link to documentation about deleted resources.
    """

    def __init__(
        self,
        more_info: str,
    ) -> None:
        """
        Initialize a LoadBalancerListenerPolicyReferenceDeleted object.

        :param str more_info: Link to documentation about deleted resources.
        """
        self.more_info = more_info

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerListenerPolicyReferenceDeleted':
        """Initialize a LoadBalancerListenerPolicyReferenceDeleted object from a json dictionary."""
        args = {}
        if 'more_info' in _dict:
            args['more_info'] = _dict.get('more_info')
        else:
            raise ValueError('Required property \'more_info\' not present in LoadBalancerListenerPolicyReferenceDeleted JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerListenerPolicyReferenceDeleted object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'more_info') and self.more_info is not None:
            _dict['more_info'] = self.more_info
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancerListenerPolicyReferenceDeleted object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerListenerPolicyReferenceDeleted') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerListenerPolicyReferenceDeleted') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class LoadBalancerListenerPolicyRule:
    """
    LoadBalancerListenerPolicyRule.

    :attr str condition: The condition of the rule.
    :attr datetime created_at: The date and time that this rule was created.
    :attr str field: (optional) The field. This is applicable to `header`, `query`,
          and `body` rule types.
          If the rule type is `header`, this property is required.
          If the rule type is `query`, this is optional. If specified and the rule
          condition is not
          `matches_regex`, the value must be percent-encoded.
          If the rule type is `body`, this is optional.
    :attr str href: The rule's canonical URL.
    :attr str id: The rule's unique identifier.
    :attr str provisioning_status: The provisioning status of this rule
          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 rule on which the unexpected
          property value was encountered.
    :attr str type: The type of the rule.
          Body rules are applied to form-encoded request bodies using the `UTF-8`
          character set.
    :attr str value: Value to be matched for rule condition.
          If the rule type is `query` and the rule condition is not `matches_regex`, the
          value must be percent-encoded.
    """

    def __init__(
        self,
        condition: str,
        created_at: datetime,
        href: str,
        id: str,
        provisioning_status: str,
        type: str,
        value: str,
        *,
        field: str = None,
    ) -> None:
        """
        Initialize a LoadBalancerListenerPolicyRule object.

        :param str condition: The condition of the rule.
        :param datetime created_at: The date and time that this rule was created.
        :param str href: The rule's canonical URL.
        :param str id: The rule's unique identifier.
        :param str provisioning_status: The provisioning status of this rule
               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 rule on
               which the unexpected property value was encountered.
        :param str type: The type of the rule.
               Body rules are applied to form-encoded request bodies using the `UTF-8`
               character set.
        :param str value: Value to be matched for rule condition.
               If the rule type is `query` and the rule condition is not `matches_regex`,
               the value must be percent-encoded.
        :param str field: (optional) The field. This is applicable to `header`,
               `query`, and `body` rule types.
               If the rule type is `header`, this property is required.
               If the rule type is `query`, this is optional. If specified and the rule
               condition is not
               `matches_regex`, the value must be percent-encoded.
               If the rule type is `body`, this is optional.
        """
        self.condition = condition
        self.created_at = created_at
        self.field = field
        self.href = href
        self.id = id
        self.provisioning_status = provisioning_status
        self.type = type
        self.value = value

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerListenerPolicyRule':
        """Initialize a LoadBalancerListenerPolicyRule object from a json dictionary."""
        args = {}
        if 'condition' in _dict:
            args['condition'] = _dict.get('condition')
        else:
            raise ValueError('Required property \'condition\' not present in LoadBalancerListenerPolicyRule JSON')
        if 'created_at' in _dict:
            args['created_at'] = string_to_datetime(_dict.get('created_at'))
        else:
            raise ValueError('Required property \'created_at\' not present in LoadBalancerListenerPolicyRule JSON')
        if 'field' in _dict:
            args['field'] = _dict.get('field')
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in LoadBalancerListenerPolicyRule JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in LoadBalancerListenerPolicyRule JSON')
        if 'provisioning_status' in _dict:
            args['provisioning_status'] = _dict.get('provisioning_status')
        else:
            raise ValueError('Required property \'provisioning_status\' not present in LoadBalancerListenerPolicyRule JSON')
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in LoadBalancerListenerPolicyRule JSON')
        if 'value' in _dict:
            args['value'] = _dict.get('value')
        else:
            raise ValueError('Required property \'value\' not present in LoadBalancerListenerPolicyRule JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerListenerPolicyRule object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'condition') and self.condition is not None:
            _dict['condition'] = self.condition
        if hasattr(self, 'created_at') and self.created_at is not None:
            _dict['created_at'] = datetime_to_string(self.created_at)
        if hasattr(self, 'field') and self.field is not None:
            _dict['field'] = self.field
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'provisioning_status') and self.provisioning_status is not None:
            _dict['provisioning_status'] = self.provisioning_status
        if hasattr(self, 'type') and self.type is not None:
            _dict['type'] = self.type
        if hasattr(self, 'value') and self.value is not None:
            _dict['value'] = self.value
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancerListenerPolicyRule object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerListenerPolicyRule') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerListenerPolicyRule') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ConditionEnum(str, Enum):
        """
        The condition of the rule.
        """

        CONTAINS = 'contains'
        EQUALS = 'equals'
        MATCHES_REGEX = 'matches_regex'


    class ProvisioningStatusEnum(str, Enum):
        """
        The provisioning status of this rule
        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 rule on which the unexpected
        property value was encountered.
        """

        ACTIVE = 'active'
        CREATE_PENDING = 'create_pending'
        DELETE_PENDING = 'delete_pending'
        FAILED = 'failed'
        UPDATE_PENDING = 'update_pending'


    class TypeEnum(str, Enum):
        """
        The type of the rule.
        Body rules are applied to form-encoded request bodies using the `UTF-8` character
        set.
        """

        BODY = 'body'
        HEADER = 'header'
        HOSTNAME = 'hostname'
        PATH = 'path'
        QUERY = 'query'



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(v) for v 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:
            rules_list = []
            for v in self.rules:
                if isinstance(v, dict):
                    rules_list.append(v)
                else:
                    rules_list.append(v.to_dict())
            _dict['rules'] = rules_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 LoadBalancerListenerPolicyRuleCollection object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerListenerPolicyRuleCollection') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerListenerPolicyRuleCollection') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class LoadBalancerListenerPolicyRulePatch:
    """
    LoadBalancerListenerPolicyRulePatch.

    :attr str condition: (optional) The condition of the rule.
    :attr str field: (optional) The field. This is applicable to `header`, `query`,
          and `body` rule types.
          If the rule type is `header`, this property is required.
          If the rule type is `query`, this is optional. If specified and the rule
          condition is not
          `matches_regex`, the value must be percent-encoded.
          If the rule type is `body`, this is optional.
    :attr str type: (optional) The type of the rule.
          Body rules are applied to form-encoded request bodies using the `UTF-8`
          character set.
    :attr str value: (optional) Value to be matched for rule condition.
          If the rule type is `query` and the rule condition is not `matches_regex`, the
          value must be percent-encoded.
    """

    def __init__(
        self,
        *,
        condition: str = None,
        field: str = None,
        type: str = None,
        value: str = None,
    ) -> None:
        """
        Initialize a LoadBalancerListenerPolicyRulePatch object.

        :param str condition: (optional) The condition of the rule.
        :param str field: (optional) The field. This is applicable to `header`,
               `query`, and `body` rule types.
               If the rule type is `header`, this property is required.
               If the rule type is `query`, this is optional. If specified and the rule
               condition is not
               `matches_regex`, the value must be percent-encoded.
               If the rule type is `body`, this is optional.
        :param str type: (optional) The type of the rule.
               Body rules are applied to form-encoded request bodies using the `UTF-8`
               character set.
        :param str value: (optional) Value to be matched for rule condition.
               If the rule type is `query` and the rule condition is not `matches_regex`,
               the value must be percent-encoded.
        """
        self.condition = condition
        self.field = field
        self.type = type
        self.value = value

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerListenerPolicyRulePatch':
        """Initialize a LoadBalancerListenerPolicyRulePatch object from a json dictionary."""
        args = {}
        if 'condition' in _dict:
            args['condition'] = _dict.get('condition')
        if 'field' in _dict:
            args['field'] = _dict.get('field')
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        if 'value' in _dict:
            args['value'] = _dict.get('value')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerListenerPolicyRulePatch object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'condition') and self.condition is not None:
            _dict['condition'] = self.condition
        if hasattr(self, 'field') and self.field is not None:
            _dict['field'] = self.field
        if hasattr(self, 'type') and self.type is not None:
            _dict['type'] = self.type
        if hasattr(self, 'value') and self.value is not None:
            _dict['value'] = self.value
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancerListenerPolicyRulePatch object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerListenerPolicyRulePatch') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerListenerPolicyRulePatch') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ConditionEnum(str, Enum):
        """
        The condition of the rule.
        """

        CONTAINS = 'contains'
        EQUALS = 'equals'
        MATCHES_REGEX = 'matches_regex'


    class TypeEnum(str, Enum):
        """
        The type of the rule.
        Body rules are applied to form-encoded request bodies using the `UTF-8` character
        set.
        """

        BODY = 'body'
        HEADER = 'header'
        HOSTNAME = 'hostname'
        PATH = 'path'
        QUERY = 'query'



class LoadBalancerListenerPolicyRulePrototype:
    """
    LoadBalancerListenerPolicyRulePrototype.

    :attr str condition: The condition of the rule.
    :attr str field: (optional) The field. This is applicable to `header`, `query`,
          and `body` rule types.
          If the rule type is `header`, this property is required.
          If the rule type is `query`, this is optional. If specified and the rule
          condition is not
          `matches_regex`, the value must be percent-encoded.
          If the rule type is `body`, this is optional.
    :attr str type: The type of the rule.
          Body rules are applied to form-encoded request bodies using the `UTF-8`
          character set.
    :attr str value: Value to be matched for rule condition.
          If the rule type is `query` and the rule condition is not `matches_regex`, the
          value must be percent-encoded.
    """

    def __init__(
        self,
        condition: str,
        type: str,
        value: str,
        *,
        field: str = None,
    ) -> None:
        """
        Initialize a LoadBalancerListenerPolicyRulePrototype object.

        :param str condition: The condition of the rule.
        :param str type: The type of the rule.
               Body rules are applied to form-encoded request bodies using the `UTF-8`
               character set.
        :param str value: Value to be matched for rule condition.
               If the rule type is `query` and the rule condition is not `matches_regex`,
               the value must be percent-encoded.
        :param str field: (optional) The field. This is applicable to `header`,
               `query`, and `body` rule types.
               If the rule type is `header`, this property is required.
               If the rule type is `query`, this is optional. If specified and the rule
               condition is not
               `matches_regex`, the value must be percent-encoded.
               If the rule type is `body`, this is optional.
        """
        self.condition = condition
        self.field = field
        self.type = type
        self.value = value

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerListenerPolicyRulePrototype':
        """Initialize a LoadBalancerListenerPolicyRulePrototype object from a json dictionary."""
        args = {}
        if 'condition' in _dict:
            args['condition'] = _dict.get('condition')
        else:
            raise ValueError('Required property \'condition\' not present in LoadBalancerListenerPolicyRulePrototype JSON')
        if 'field' in _dict:
            args['field'] = _dict.get('field')
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in LoadBalancerListenerPolicyRulePrototype JSON')
        if 'value' in _dict:
            args['value'] = _dict.get('value')
        else:
            raise ValueError('Required property \'value\' not present in LoadBalancerListenerPolicyRulePrototype JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerListenerPolicyRulePrototype object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'condition') and self.condition is not None:
            _dict['condition'] = self.condition
        if hasattr(self, 'field') and self.field is not None:
            _dict['field'] = self.field
        if hasattr(self, 'type') and self.type is not None:
            _dict['type'] = self.type
        if hasattr(self, 'value') and self.value is not None:
            _dict['value'] = self.value
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancerListenerPolicyRulePrototype object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerListenerPolicyRulePrototype') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerListenerPolicyRulePrototype') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ConditionEnum(str, Enum):
        """
        The condition of the rule.
        """

        CONTAINS = 'contains'
        EQUALS = 'equals'
        MATCHES_REGEX = 'matches_regex'


    class TypeEnum(str, Enum):
        """
        The type of the rule.
        Body rules are applied to form-encoded request bodies using the `UTF-8` character
        set.
        """

        BODY = 'body'
        HEADER = 'header'
        HOSTNAME = 'hostname'
        PATH = 'path'
        QUERY = 'query'



class LoadBalancerListenerPolicyRuleReference:
    """
    LoadBalancerListenerPolicyRuleReference.

    :attr LoadBalancerListenerPolicyRuleReferenceDeleted deleted: (optional) If
          present, this property indicates the referenced resource has been deleted, and
          provides
          some supplementary information.
    :attr str href: The rule's canonical URL.
    :attr str id: The rule's unique identifier.
    """

    def __init__(
        self,
        href: str,
        id: str,
        *,
        deleted: 'LoadBalancerListenerPolicyRuleReferenceDeleted' = None,
    ) -> None:
        """
        Initialize a LoadBalancerListenerPolicyRuleReference object.

        :param str href: The rule's canonical URL.
        :param str id: The rule's unique identifier.
        :param LoadBalancerListenerPolicyRuleReferenceDeleted deleted: (optional)
               If present, this property indicates the referenced resource has been
               deleted, and provides
               some supplementary information.
        """
        self.deleted = deleted
        self.href = href
        self.id = id

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerListenerPolicyRuleReference':
        """Initialize a LoadBalancerListenerPolicyRuleReference object from a json dictionary."""
        args = {}
        if 'deleted' in _dict:
            args['deleted'] = LoadBalancerListenerPolicyRuleReferenceDeleted.from_dict(_dict.get('deleted'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in LoadBalancerListenerPolicyRuleReference JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in LoadBalancerListenerPolicyRuleReference JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerListenerPolicyRuleReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'deleted') and self.deleted is not None:
            if isinstance(self.deleted, dict):
                _dict['deleted'] = self.deleted
            else:
                _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancerListenerPolicyRuleReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerListenerPolicyRuleReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerListenerPolicyRuleReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class LoadBalancerListenerPolicyRuleReferenceDeleted:
    """
    If present, this property indicates the referenced resource has been deleted, and
    provides some supplementary information.

    :attr str more_info: Link to documentation about deleted resources.
    """

    def __init__(
        self,
        more_info: str,
    ) -> None:
        """
        Initialize a LoadBalancerListenerPolicyRuleReferenceDeleted object.

        :param str more_info: Link to documentation about deleted resources.
        """
        self.more_info = more_info

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerListenerPolicyRuleReferenceDeleted':
        """Initialize a LoadBalancerListenerPolicyRuleReferenceDeleted object from a json dictionary."""
        args = {}
        if 'more_info' in _dict:
            args['more_info'] = _dict.get('more_info')
        else:
            raise ValueError('Required property \'more_info\' not present in LoadBalancerListenerPolicyRuleReferenceDeleted JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerListenerPolicyRuleReferenceDeleted object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'more_info') and self.more_info is not None:
            _dict['more_info'] = self.more_info
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancerListenerPolicyRuleReferenceDeleted object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerListenerPolicyRuleReferenceDeleted') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerListenerPolicyRuleReferenceDeleted') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class LoadBalancerListenerPolicyTarget:
    """
    - If `action` is `forward`, the response is a `LoadBalancerPoolReference`
    - If `action` is `redirect`, the response is a `LoadBalancerListenerPolicyRedirectURL`
    - If `action` is `https_redirect`, the response is a
    `LoadBalancerListenerHTTPSRedirect`.

    """

    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', 'LoadBalancerListenerPolicyTargetLoadBalancerListenerHTTPSRedirect'])
        )
        raise Exception(msg)


class LoadBalancerListenerPolicyTargetPatch:
    """
    - If `action` is `forward`, specify a `LoadBalancerPoolIdentity`.
    - If `action` is `redirect`, specify a `LoadBalancerListenerPolicyRedirectURLPatch`.
    - If `action` is `https_redirect`, specify a
      `LoadBalancerListenerPolicyHTTPSRedirectPatch`.

    """

    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', 'LoadBalancerListenerPolicyTargetPatchLoadBalancerListenerHTTPSRedirectPatch'])
        )
        raise Exception(msg)


class LoadBalancerListenerPolicyTargetPrototype:
    """
    - If `action` is `forward`, specify a `LoadBalancerPoolIdentity`.
    - If `action` is `redirect`, specify a
    `LoadBalancerListenerPolicyRedirectURLPrototype`.
    - If `action` is `https_redirect`, specify a
      `LoadBalancerListenerPolicyHTTPSRedirectPrototype`.

    """

    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', 'LoadBalancerListenerPolicyTargetPrototypeLoadBalancerListenerHTTPSRedirectPrototype'])
        )
        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`). Additional restrictions:
          - If this listener has `https_redirect` specified, its `accept_proxy_protocol`
          value must
            match the `accept_proxy_protocol` value of the `https_redirect` listener.
          - If this listener is the target of another listener's `https_redirect`, its
            `accept_proxy_protocol` value must match that listener's
          `accept_proxy_protocol` value.
    :attr CertificateInstanceIdentity certificate_instance: (optional) The
          certificate instance to use for SSL termination. The listener must have a
          `protocol` of `https`.
    :attr int connection_limit: (optional) The connection limit of the listener.
    :attr LoadBalancerPoolIdentityByName default_pool: (optional) The default pool
          for this listener. If specified, the pool must:
            - Belong to this load balancer.
            - Have the same `protocol` as this listener, or have a compatible protocol.
              At present, the compatible protocols are `http` and `https`.
            - Not already be the `default_pool` for another listener.
          If unspecified, this listener will be created with no default pool, but one may
          be
          subsequently set.
    :attr LoadBalancerListenerHTTPSRedirectPrototype https_redirect: (optional) The
          target listener that requests will be redirected to. This listener must have a
          `protocol` of `http`, and the target listener must have a `protocol` of `https`.
    :attr int idle_connection_timeout: (optional) The idle connection timeout of the
          listener in seconds. Supported for load balancers in the `application` family.
    :attr int port: (optional) The listener port number, or the inclusive lower
          bound of the port range. Each listener in the load balancer must have a unique
          `port` and `protocol` combination.
          Not supported for load balancers operating with route mode enabled.
    :attr int port_max: (optional) The inclusive upper bound of the range of ports
          used by this listener. Must not be less than `port_min`.
          At present, only load balancers operating with route mode enabled, and public
          load balancers in the `network` family support different values for `port_min`
          and
          `port_max`. When route mode is enabled, the value `65535` must be specified.
          The specified port range must not overlap with port ranges used by other
          listeners for this load balancer using the same protocol.
    :attr int port_min: (optional) The inclusive lower bound of the range of ports
          used by this listener. Must not be greater than `port_max`.
          At present, only load balancers operating with route mode enabled, and public
          load balancers in the `network` family support different values for `port_min`
          and
          `port_max`. When route mode is enabled, the value `1` must be specified.
          The specified port range must not overlap with port ranges used by other
          listeners for this load balancer using the same protocol.
    :attr str protocol: The listener protocol. Each listener in the load balancer
          must have a unique `port` and `protocol` combination.
          Load balancers in the `network` family support `tcp` and `udp` (if
          `udp_supported` is `true`). Load balancers in the `application` family support
          `tcp`, `http` and
          `https`.
          Additional restrictions:
          - If `default_pool` is set, the pool's protocol must match, or be compatible
          with
            the listener's protocol. At present, the compatible protocols are `http` and
            `https`.
          - If `https_redirect` is set, the protocol must be `http`.
    """

    def __init__(
        self,
        protocol: str,
        *,
        accept_proxy_protocol: bool = None,
        certificate_instance: 'CertificateInstanceIdentity' = None,
        connection_limit: int = None,
        default_pool: 'LoadBalancerPoolIdentityByName' = None,
        https_redirect: 'LoadBalancerListenerHTTPSRedirectPrototype' = None,
        idle_connection_timeout: int = None,
        port: int = None,
        port_max: int = None,
        port_min: int = None,
    ) -> None:
        """
        Initialize a LoadBalancerListenerPrototypeLoadBalancerContext object.

        :param str protocol: The listener protocol. Each listener in the load
               balancer must have a unique `port` and `protocol` combination.
               Load balancers in the `network` family support `tcp` and `udp` (if
               `udp_supported` is `true`). Load balancers in the `application` family
               support `tcp`, `http` and
               `https`.
               Additional restrictions:
               - If `default_pool` is set, the pool's protocol must match, or be
               compatible with
                 the listener's protocol. At present, the compatible protocols are `http`
               and
                 `https`.
               - If `https_redirect` is set, the protocol must be `http`.
        :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`).
               Additional restrictions:
               - If this listener has `https_redirect` specified, its
               `accept_proxy_protocol` value must
                 match the `accept_proxy_protocol` value of the `https_redirect` listener.
               - If this listener is the target of another listener's `https_redirect`,
               its
                 `accept_proxy_protocol` value must match that listener's
               `accept_proxy_protocol` value.
        :param CertificateInstanceIdentity certificate_instance: (optional) The
               certificate instance to use for SSL termination. The listener must have a
               `protocol` of `https`.
        :param int connection_limit: (optional) The connection limit of the
               listener.
        :param LoadBalancerPoolIdentityByName default_pool: (optional) The default
               pool for this listener. If specified, the pool must:
                 - Belong to this load balancer.
                 - Have the same `protocol` as this listener, or have a compatible
               protocol.
                   At present, the compatible protocols are `http` and `https`.
                 - Not already be the `default_pool` for another listener.
               If unspecified, this listener will be created with no default pool, but one
               may be
               subsequently set.
        :param LoadBalancerListenerHTTPSRedirectPrototype https_redirect:
               (optional) The target listener that requests will be redirected to. This
               listener must have a
               `protocol` of `http`, and the target listener must have a `protocol` of
               `https`.
        :param int idle_connection_timeout: (optional) The idle connection timeout
               of the listener in seconds. Supported for load balancers in the
               `application` family.
        :param int port: (optional) The listener port number, or the inclusive
               lower bound of the port range. Each listener in the load balancer must have
               a unique `port` and `protocol` combination.
               Not supported for load balancers operating with route mode enabled.
        :param int port_max: (optional) The inclusive upper bound of the range of
               ports used by this listener. Must not be less than `port_min`.
               At present, only load balancers operating with route mode enabled, and
               public load balancers in the `network` family support different values for
               `port_min` and
               `port_max`. When route mode is enabled, the value `65535` must be
               specified.
               The specified port range must not overlap with port ranges used by other
               listeners for this load balancer using the same protocol.
        :param int port_min: (optional) The inclusive lower bound of the range of
               ports used by this listener. Must not be greater than `port_max`.
               At present, only load balancers operating with route mode enabled, and
               public load balancers in the `network` family support different values for
               `port_min` and
               `port_max`. When route mode is enabled, the value `1` must be specified.
               The specified port range must not overlap with port ranges used by other
               listeners for this load balancer using the same protocol.
        """
        self.accept_proxy_protocol = accept_proxy_protocol
        self.certificate_instance = certificate_instance
        self.connection_limit = connection_limit
        self.default_pool = default_pool
        self.https_redirect = https_redirect
        self.idle_connection_timeout = idle_connection_timeout
        self.port = port
        self.port_max = port_max
        self.port_min = port_min
        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 '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'] = LoadBalancerPoolIdentityByName.from_dict(_dict.get('default_pool'))
        if 'https_redirect' in _dict:
            args['https_redirect'] = LoadBalancerListenerHTTPSRedirectPrototype.from_dict(_dict.get('https_redirect'))
        if 'idle_connection_timeout' in _dict:
            args['idle_connection_timeout'] = _dict.get('idle_connection_timeout')
        if 'port' in _dict:
            args['port'] = _dict.get('port')
        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 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, '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, 'https_redirect') and self.https_redirect is not None:
            if isinstance(self.https_redirect, dict):
                _dict['https_redirect'] = self.https_redirect
            else:
                _dict['https_redirect'] = self.https_redirect.to_dict()
        if hasattr(self, 'idle_connection_timeout') and self.idle_connection_timeout is not None:
            _dict['idle_connection_timeout'] = self.idle_connection_timeout
        if hasattr(self, 'port') and self.port is not None:
            _dict['port'] = self.port
        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 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. Each listener in the load balancer must have a unique
        `port` and `protocol` combination.
        Load balancers in the `network` family support `tcp` and `udp` (if `udp_supported`
        is `true`). Load balancers in the `application` family support `tcp`, `http` and
        `https`.
        Additional restrictions:
        - If `default_pool` is set, the pool's protocol must match, or be compatible with
          the listener's protocol. At present, the compatible protocols are `http` and
          `https`.
        - If `https_redirect` is set, the protocol must be `http`.
        """

        HTTP = 'http'
        HTTPS = 'https'
        TCP = 'tcp'
        UDP = 'udp'



class LoadBalancerListenerReference:
    """
    LoadBalancerListenerReference.

    :attr LoadBalancerListenerReferenceDeleted deleted: (optional) If present, this
          property indicates the referenced resource has been deleted, and provides
          some supplementary information.
    :attr str href: The listener's canonical URL.
    :attr str id: The unique identifier for this load balancer listener.
    """

    def __init__(
        self,
        href: str,
        id: str,
        *,
        deleted: 'LoadBalancerListenerReferenceDeleted' = None,
    ) -> None:
        """
        Initialize a LoadBalancerListenerReference object.

        :param str href: The listener's canonical URL.
        :param str id: The unique identifier for this load balancer listener.
        :param LoadBalancerListenerReferenceDeleted deleted: (optional) If present,
               this property indicates the referenced resource has been deleted, and
               provides
               some supplementary information.
        """
        self.deleted = deleted
        self.href = href
        self.id = id

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerListenerReference':
        """Initialize a LoadBalancerListenerReference object from a json dictionary."""
        args = {}
        if 'deleted' in _dict:
            args['deleted'] = LoadBalancerListenerReferenceDeleted.from_dict(_dict.get('deleted'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in LoadBalancerListenerReference JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in LoadBalancerListenerReference JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerListenerReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'deleted') and self.deleted is not None:
            if isinstance(self.deleted, dict):
                _dict['deleted'] = self.deleted
            else:
                _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancerListenerReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerListenerReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerListenerReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class LoadBalancerListenerReferenceDeleted:
    """
    If present, this property indicates the referenced resource has been deleted, and
    provides some supplementary information.

    :attr str more_info: Link to documentation about deleted resources.
    """

    def __init__(
        self,
        more_info: str,
    ) -> None:
        """
        Initialize a LoadBalancerListenerReferenceDeleted object.

        :param str more_info: Link to documentation about deleted resources.
        """
        self.more_info = more_info

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerListenerReferenceDeleted':
        """Initialize a LoadBalancerListenerReferenceDeleted object from a json dictionary."""
        args = {}
        if 'more_info' in _dict:
            args['more_info'] = _dict.get('more_info')
        else:
            raise ValueError('Required property \'more_info\' not present in LoadBalancerListenerReferenceDeleted JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerListenerReferenceDeleted object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'more_info') and self.more_info is not None:
            _dict['more_info'] = self.more_info
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancerListenerReferenceDeleted object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerListenerReferenceDeleted') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerListenerReferenceDeleted') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class LoadBalancerLogging:
    """
    LoadBalancerLogging.

    :attr LoadBalancerLoggingDatapath datapath: The datapath logging configuration
          for this load balancer.
    """

    def __init__(
        self,
        datapath: 'LoadBalancerLoggingDatapath',
    ) -> None:
        """
        Initialize a LoadBalancerLogging object.

        :param LoadBalancerLoggingDatapath datapath: 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'))
        else:
            raise ValueError('Required property \'datapath\' not present in LoadBalancerLogging JSON')
        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:
            if isinstance(self.datapath, dict):
                _dict['datapath'] = self.datapath
            else:
                _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: Indicates whether datapath logging is active for this load
          balancer.
    """

    def __init__(
        self,
        active: bool,
    ) -> None:
        """
        Initialize a LoadBalancerLoggingDatapath object.

        :param bool active: Indicates whether 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 LoadBalancerLoggingDatapathPatch:
    """
    The datapath logging configuration for this load balancer.

    :attr bool active: (optional) Indicates whether datapath logging will be active
          for this load balancer.
    """

    def __init__(
        self,
        *,
        active: bool = None,
    ) -> None:
        """
        Initialize a LoadBalancerLoggingDatapathPatch object.

        :param bool active: (optional) Indicates whether datapath logging will be
               active for this load balancer.
        """
        self.active = active

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerLoggingDatapathPatch':
        """Initialize a LoadBalancerLoggingDatapathPatch object from a json dictionary."""
        args = {}
        if 'active' in _dict:
            args['active'] = _dict.get('active')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerLoggingDatapathPatch object from 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 LoadBalancerLoggingDatapathPatch object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerLoggingDatapathPatch') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerLoggingDatapathPatch') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class LoadBalancerLoggingDatapathPrototype:
    """
    The datapath logging configuration for this load balancer.

    :attr bool active: (optional) Indicates whether datapath logging will be active
          for this load balancer.
    """

    def __init__(
        self,
        *,
        active: bool = None,
    ) -> None:
        """
        Initialize a LoadBalancerLoggingDatapathPrototype object.

        :param bool active: (optional) Indicates whether datapath logging will be
               active for this load balancer.
        """
        self.active = active

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerLoggingDatapathPrototype':
        """Initialize a LoadBalancerLoggingDatapathPrototype object from a json dictionary."""
        args = {}
        if 'active' in _dict:
            args['active'] = _dict.get('active')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerLoggingDatapathPrototype object from 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 LoadBalancerLoggingDatapathPrototype object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerLoggingDatapathPrototype') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerLoggingDatapathPrototype') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class LoadBalancerLoggingPatch:
    """
    LoadBalancerLoggingPatch.

    :attr LoadBalancerLoggingDatapathPatch datapath: (optional) The datapath logging
          configuration for this load balancer.
    """

    def __init__(
        self,
        *,
        datapath: 'LoadBalancerLoggingDatapathPatch' = None,
    ) -> None:
        """
        Initialize a LoadBalancerLoggingPatch object.

        :param LoadBalancerLoggingDatapathPatch datapath: (optional) The datapath
               logging configuration for this load balancer.
        """
        self.datapath = datapath

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerLoggingPatch':
        """Initialize a LoadBalancerLoggingPatch object from a json dictionary."""
        args = {}
        if 'datapath' in _dict:
            args['datapath'] = LoadBalancerLoggingDatapathPatch.from_dict(_dict.get('datapath'))
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerLoggingPatch object from 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:
            if isinstance(self.datapath, dict):
                _dict['datapath'] = self.datapath
            else:
                _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 LoadBalancerLoggingPatch object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerLoggingPatch') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerLoggingPatch') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class LoadBalancerLoggingPrototype:
    """
    LoadBalancerLoggingPrototype.

    :attr LoadBalancerLoggingDatapathPrototype datapath: (optional) The datapath
          logging configuration for this load balancer.
    """

    def __init__(
        self,
        *,
        datapath: 'LoadBalancerLoggingDatapathPrototype' = None,
    ) -> None:
        """
        Initialize a LoadBalancerLoggingPrototype object.

        :param LoadBalancerLoggingDatapathPrototype datapath: (optional) The
               datapath logging configuration for this load balancer.
        """
        self.datapath = datapath

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerLoggingPrototype':
        """Initialize a LoadBalancerLoggingPrototype object from a json dictionary."""
        args = {}
        if 'datapath' in _dict:
            args['datapath'] = LoadBalancerLoggingDatapathPrototype.from_dict(_dict.get('datapath'))
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerLoggingPrototype object from 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:
            if isinstance(self.datapath, dict):
                _dict['datapath'] = self.datapath
            else:
                _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 LoadBalancerLoggingPrototype object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerLoggingPrototype') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerLoggingPrototype') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class LoadBalancerPatch:
    """
    LoadBalancerPatch.

    :attr LoadBalancerDNSPatch dns: (optional) The DNS configuration for this load
          balancer.
          Specify `null` to remove the existing DNS configuration, which will remove all
          DNS `A`
          records for this load balancer that had been added to `zone`, and add equivalent
          `A`
          records to the public DNS zone `lb.appdomain.cloud`.
    :attr LoadBalancerLoggingPatch 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 name for this load balancer. The name must not be
          used by another load balancer in the VPC.
    :attr List[SubnetIdentity] subnets: (optional) The subnets to provision this
          load balancer in. The load balancer's availability will depend on the
          availability of the zones that the subnets reside in.
          The specified subnets must be in the same VPC as the existing subnets, and will
          completely replace the existing subnets.
          The load balancer must be in the `application` family.
    """

    def __init__(
        self,
        *,
        dns: 'LoadBalancerDNSPatch' = None,
        logging: 'LoadBalancerLoggingPatch' = None,
        name: str = None,
        subnets: List['SubnetIdentity'] = None,
    ) -> None:
        """
        Initialize a LoadBalancerPatch object.

        :param LoadBalancerDNSPatch dns: (optional) The DNS configuration for this
               load balancer.
               Specify `null` to remove the existing DNS configuration, which will remove
               all DNS `A`
               records for this load balancer that had been added to `zone`, and add
               equivalent `A`
               records to the public DNS zone `lb.appdomain.cloud`.
        :param LoadBalancerLoggingPatch 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 name for this load balancer. The name must
               not be used by another load balancer in the VPC.
        :param List[SubnetIdentity] subnets: (optional) The subnets to provision
               this load balancer in. The load balancer's availability will depend on the
               availability of the zones that the subnets reside in.
               The specified subnets must be in the same VPC as the existing subnets, and
               will completely replace the existing subnets.
               The load balancer must be in the `application` family.
        """
        self.dns = dns
        self.logging = logging
        self.name = name
        self.subnets = subnets

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerPatch':
        """Initialize a LoadBalancerPatch object from a json dictionary."""
        args = {}
        if 'dns' in _dict:
            args['dns'] = LoadBalancerDNSPatch.from_dict(_dict.get('dns'))
        if 'logging' in _dict:
            args['logging'] = LoadBalancerLoggingPatch.from_dict(_dict.get('logging'))
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        if 'subnets' in _dict:
            args['subnets'] = _dict.get('subnets')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a 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, 'dns') and self.dns is not None:
            if isinstance(self.dns, dict):
                _dict['dns'] = self.dns
            else:
                _dict['dns'] = self.dns.to_dict()
        if hasattr(self, 'logging') and self.logging is not None:
            if isinstance(self.logging, dict):
                _dict['logging'] = self.logging
            else:
                _dict['logging'] = self.logging.to_dict()
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'subnets') and self.subnets is not None:
            subnets_list = []
            for v in self.subnets:
                if isinstance(v, dict):
                    subnets_list.append(v)
                else:
                    subnets_list.append(v.to_dict())
            _dict['subnets'] = subnets_list
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancerPatch object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerPatch') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerPatch') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class LoadBalancerPool:
    """
    LoadBalancerPool.

    :attr str algorithm: The load balancing algorithm.
    :attr datetime created_at: The date and time that this pool was created.
    :attr LoadBalancerPoolHealthMonitor health_monitor: The health monitor of this
          pool.
    :attr str href: The pool's canonical URL.
    :attr str id: The unique identifier for this load balancer pool.
    :attr InstanceGroupReference instance_group: (optional) The instance group that
          is managing this pool.
    :attr List[LoadBalancerPoolMemberReference] members: (optional) The backend
          server members of the pool.
    :attr str name: The name for this load balancer pool. The name is unique across
          all pools for the load balancer.
    :attr str protocol: The protocol 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
          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: The PROXY protocol setting for this pool:
          - `v1`: Enabled with version 1 (human-readable header format)
          - `v2`: Enabled with version 2 (binary header format)
          - `disabled`: Disabled
          Supported by load balancers in the `application` family (otherwise always
          `disabled`).
    :attr LoadBalancerPoolSessionPersistence session_persistence: (optional) The
          session persistence of this pool.
          The enumerated values for this property are expected to expand in the future.
          When
          processing this property, check for and log unknown values. Optionally halt
          processing and surface the error, or bypass the pool on which the unexpected
          property value was encountered.
    """

    def __init__(
        self,
        algorithm: str,
        created_at: datetime,
        health_monitor: 'LoadBalancerPoolHealthMonitor',
        href: str,
        id: str,
        name: str,
        protocol: str,
        provisioning_status: str,
        proxy_protocol: str,
        *,
        instance_group: 'InstanceGroupReference' = None,
        members: List['LoadBalancerPoolMemberReference'] = None,
        session_persistence: 'LoadBalancerPoolSessionPersistence' = None,
    ) -> None:
        """
        Initialize a LoadBalancerPool object.

        :param str algorithm: The load balancing algorithm.
        :param datetime created_at: The date and time that this pool was created.
        :param LoadBalancerPoolHealthMonitor health_monitor: The health monitor of
               this pool.
        :param str href: The pool's canonical URL.
        :param str id: The unique identifier for this load balancer pool.
        :param str name: The name for this load balancer pool. The name is unique
               across all pools for the load balancer.
        :param str protocol: The protocol 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
               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: The PROXY protocol setting for this pool:
               - `v1`: Enabled with version 1 (human-readable header format)
               - `v2`: Enabled with version 2 (binary header format)
               - `disabled`: Disabled
               Supported by load balancers in the `application` family (otherwise always
               `disabled`).
        :param InstanceGroupReference instance_group: (optional) The instance group
               that is managing this pool.
        :param List[LoadBalancerPoolMemberReference] members: (optional) The
               backend server members of the pool.
        :param LoadBalancerPoolSessionPersistence session_persistence: (optional)
               The session persistence of this pool.
               The enumerated values for this property are expected to expand in the
               future. When
               processing this property, check for and log unknown values. Optionally halt
               processing and surface the error, or bypass the pool on which the
               unexpected
               property value was encountered.
        """
        self.algorithm = algorithm
        self.created_at = created_at
        self.health_monitor = health_monitor
        self.href = href
        self.id = id
        self.instance_group = instance_group
        self.members = members
        self.name = name
        self.protocol = protocol
        self.provisioning_status = provisioning_status
        self.proxy_protocol = proxy_protocol
        self.session_persistence = session_persistence

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerPool':
        """Initialize a LoadBalancerPool object from a json dictionary."""
        args = {}
        if 'algorithm' in _dict:
            args['algorithm'] = _dict.get('algorithm')
        else:
            raise ValueError('Required property \'algorithm\' not present in LoadBalancerPool JSON')
        if 'created_at' in _dict:
            args['created_at'] = string_to_datetime(_dict.get('created_at'))
        else:
            raise ValueError('Required property \'created_at\' not present in LoadBalancerPool JSON')
        if 'health_monitor' in _dict:
            args['health_monitor'] = LoadBalancerPoolHealthMonitor.from_dict(_dict.get('health_monitor'))
        else:
            raise ValueError('Required property \'health_monitor\' not present in LoadBalancerPool JSON')
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in LoadBalancerPool JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in LoadBalancerPool JSON')
        if 'instance_group' in _dict:
            args['instance_group'] = InstanceGroupReference.from_dict(_dict.get('instance_group'))
        if 'members' in _dict:
            args['members'] = [LoadBalancerPoolMemberReference.from_dict(v) for v 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:
            if isinstance(self.health_monitor, dict):
                _dict['health_monitor'] = self.health_monitor
            else:
                _dict['health_monitor'] = self.health_monitor.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'instance_group') and self.instance_group is not None:
            if isinstance(self.instance_group, dict):
                _dict['instance_group'] = self.instance_group
            else:
                _dict['instance_group'] = self.instance_group.to_dict()
        if hasattr(self, 'members') and self.members is not None:
            members_list = []
            for v in self.members:
                if isinstance(v, dict):
                    members_list.append(v)
                else:
                    members_list.append(v.to_dict())
            _dict['members'] = members_list
        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:
            if isinstance(self.session_persistence, dict):
                _dict['session_persistence'] = self.session_persistence
            else:
                _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 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'
        HTTPS = 'https'
        TCP = 'tcp'
        UDP = 'udp'


    class ProvisioningStatusEnum(str, Enum):
        """
        The provisioning status of this pool
        The enumerated values for this property are expected to expand in the future. When
        processing this property, check for and log unknown values. Optionally halt
        processing and surface the error, or bypass the pool on which the unexpected
        property value was encountered.
        """

        ACTIVE = 'active'
        CREATE_PENDING = 'create_pending'
        DELETE_PENDING = 'delete_pending'
        FAILED = 'failed'
        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(v) for v 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:
            pools_list = []
            for v in self.pools:
                if isinstance(v, dict):
                    pools_list.append(v)
                else:
                    pools_list.append(v.to_dict())
            _dict['pools'] = pools_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 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 seconds to wait between health checks.
    :attr int max_retries: The health check max retries.
    :attr int port: (optional) The health check port.
          If present, this overrides the pool member port values.
    :attr int timeout: The seconds to wait for a response to a health check.
    :attr str type: The protocol type to use for health checks.
          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 when `type`
          is `http` or `https`.
          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 seconds to wait between health checks.
        :param int max_retries: The health check max retries.
        :param int timeout: The seconds to wait for a response to a health check.
        :param str type: The protocol type to use for health checks.
               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.
               If present, this overrides the pool member port values.
        :param str url_path: (optional) The health check URL path. Applicable when
               `type` is `http` or `https`.
               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 to use for health checks.
        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'
        HTTPS = 'https'
        TCP = 'tcp'



class LoadBalancerPoolHealthMonitorPatch:
    """
    LoadBalancerPoolHealthMonitorPatch.

    :attr int delay: The seconds to wait between health checks.  Must be greater
          than `timeout`.
    :attr int max_retries: The health check max retries.
    :attr int port: (optional) The health check port.
          If set, this overrides the pool member port values.
          Specify `null` to remove an existing health check port.
    :attr int timeout: The seconds to wait for a response to a health check.  Must
          be less than `delay`.
    :attr str type: The protocol type to use for health checks.
    :attr str url_path: (optional) The health check URL path. Applicable when `type`
          is `http` or `https`.
          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 seconds to wait between health checks.  Must be
               greater than `timeout`.
        :param int max_retries: The health check max retries.
        :param int timeout: The seconds to wait for a response to a health check.
               Must be less than `delay`.
        :param str type: The protocol type to use for health checks.
        :param int port: (optional) The health check port.
               If set, this overrides the pool member port values.
               Specify `null` to remove an existing health check port.
        :param str url_path: (optional) The health check URL path. Applicable when
               `type` is `http` or `https`.
               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 to use for health checks.
        """

        HTTP = 'http'
        HTTPS = 'https'
        TCP = 'tcp'



class LoadBalancerPoolHealthMonitorPrototype:
    """
    LoadBalancerPoolHealthMonitorPrototype.

    :attr int delay: The seconds to wait between health checks.  Must be greater
          than `timeout`.
    :attr int max_retries: The health check max retries.
    :attr int port: (optional) The health check port.
          If specified, this overrides the pool member port values.
    :attr int timeout: The seconds to wait for a response to a health check.  Must
          be less than `delay`.
    :attr str type: The protocol type to use for health checks.
    :attr str url_path: (optional) The health check URL path. Applicable when `type`
          is `http` or `https`.
          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 seconds to wait between health checks.  Must be
               greater than `timeout`.
        :param int max_retries: The health check max retries.
        :param int timeout: The seconds to wait for a response to a health check.
               Must be less than `delay`.
        :param str type: The protocol type to use for health checks.
        :param int port: (optional) The health check port.
               If specified, this overrides the pool member port values.
        :param str url_path: (optional) The health check URL path. Applicable when
               `type` is `http` or `https`.
               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 to use for health checks.
        """

        HTTP = 'http'
        HTTPS = 'https'
        TCP = 'tcp'



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 name for this load balancer pool. The name is unique across
          all pools for the load balancer.
    """

    def __init__(
        self,
        name: str,
    ) -> None:
        """
        Initialize a LoadBalancerPoolIdentityByName object.

        :param str name: The name for this load balancer pool. The name is unique
               across all pools for the load balancer.
        """
        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 the member will receive load balancer traffic on.
          Applies only to load balancer traffic received on a listener with a single port.
          (If the traffic is received on a listener with a port range, the member will
          receive the traffic on the same port the listener received it on.)
          This port will also be used for health checks unless the `port` property of
          `health_monitor` property is specified.
    :attr str provisioning_status: The provisioning status of this member
          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 member on which the
          unexpected property value was encountered.
    :attr LoadBalancerPoolMemberTarget target: The pool member target. Load
          balancers in the `network` family support virtual server
          instances. Load balancers in the `application` family support IP addresses. If
          the load
          balancer has route mode enabled, the member must be in a zone the load balancer
          has a
          subnet in.
    :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 the member will receive load balancer traffic on.
               Applies only to load balancer traffic received on a listener with a single
               port. (If the traffic is received on a listener with a port range, the
               member will receive the traffic on the same port the listener received it
               on.)
               This port will also be used for health checks unless the `port` property of
               `health_monitor` property is specified.
        :param str provisioning_status: The provisioning status of this member
               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 member
               on which the unexpected property value was encountered.
        :param LoadBalancerPoolMemberTarget target: The pool member target. Load
               balancers in the `network` family support virtual server
               instances. Load balancers in the `application` family support IP addresses.
               If the load
               balancer has route mode enabled, the member must be in a zone the load
               balancer has a
               subnet in.
        :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
        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 member on which the
        unexpected property value was encountered.
        """

        ACTIVE = 'active'
        CREATE_PENDING = 'create_pending'
        DELETE_PENDING = 'delete_pending'
        FAILED = 'failed'
        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(v) for v 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:
            members_list = []
            for v in self.members:
                if isinstance(v, dict):
                    members_list.append(v)
                else:
                    members_list.append(v.to_dict())
            _dict['members'] = members_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 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 the member will receive load balancer
          traffic on. Applies only to load balancer traffic received on a listener with a
          single port. (If the traffic is received on a listener with a port range, the
          member will receive the traffic on the same port the listener received it on.)
          This port will also be used for health checks unless the `port` property of
          `health_monitor` property is specified.
          The port must be unique across all members for all pools associated with this
          pool's listener.
    :attr LoadBalancerPoolMemberTargetPrototype target: (optional) The pool member
          target. Load balancers in the `network` family support virtual server
          instances. Load balancers in the `application` family support IP addresses. If
          the load
          balancer has route mode enabled, the member must be in a zone the load balancer
          has a
          subnet in.
    :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 the member will receive load balancer
               traffic on. Applies only to load balancer traffic received on a listener
               with a single port. (If the traffic is received on a listener with a port
               range, the member will receive the traffic on the same port the listener
               received it on.)
               This port will also be used for health checks unless the `port` property of
               `health_monitor` property is specified.
               The port must be unique across all members for all pools associated with
               this pool's listener.
        :param LoadBalancerPoolMemberTargetPrototype target: (optional) The pool
               member target. Load balancers in the `network` family support virtual
               server
               instances. Load balancers in the `application` family support IP addresses.
               If the load
               balancer has route mode enabled, the member must be in a zone the load
               balancer has a
               subnet in.
        :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 the member will receive load balancer traffic on.
          Applies only to load balancer traffic received on a listener with a single port.
          (If the traffic is received on a listener with a port range, the member will
          receive the traffic on the same port the listener received it on.)
          This port will also be used for health checks unless the `port` property of
          `health_monitor` property is specified.
          The port must be unique across all members for all pools associated with this
          pool's listener.
    :attr LoadBalancerPoolMemberTargetPrototype target: The pool member target. Load
          balancers in the `network` family support virtual server
          instances. Load balancers in the `application` family support IP addresses. If
          the load
          balancer has route mode enabled, the member must be in a zone the load balancer
          has a
          subnet in.
    :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 the member will receive load balancer traffic on.
               Applies only to load balancer traffic received on a listener with a single
               port. (If the traffic is received on a listener with a port range, the
               member will receive the traffic on the same port the listener received it
               on.)
               This port will also be used for health checks unless the `port` property of
               `health_monitor` property is specified.
               The port must be unique across all members for all pools associated with
               this pool's listener.
        :param LoadBalancerPoolMemberTargetPrototype target: The pool member
               target. Load balancers in the `network` family support virtual server
               instances. Load balancers in the `application` family support IP addresses.
               If the load
               balancer has route mode enabled, the member must be in a zone the load
               balancer has a
               subnet in.
        :param int weight: (optional) Weight of the server member. Applicable only
               if the pool algorithm is
               `weighted_round_robin`.
        """
        self.port = port
        self.target = target
        self.weight = weight

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerPoolMemberPrototype':
        """Initialize a LoadBalancerPoolMemberPrototype object from a json dictionary."""
        args = {}
        if 'port' in _dict:
            args['port'] = _dict.get('port')
        else:
            raise ValueError('Required property \'port\' not present in LoadBalancerPoolMemberPrototype JSON')
        if 'target' in _dict:
            args['target'] = _dict.get('target')
        else:
            raise ValueError('Required property \'target\' not present in LoadBalancerPoolMemberPrototype JSON')
        if 'weight' in _dict:
            args['weight'] = _dict.get('weight')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerPoolMemberPrototype object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'port') and self.port is not None:
            _dict['port'] = self.port
        if hasattr(self, 'target') and self.target is not None:
            if isinstance(self.target, dict):
                _dict['target'] = self.target
            else:
                _dict['target'] = self.target.to_dict()
        if hasattr(self, 'weight') and self.weight is not None:
            _dict['weight'] = self.weight
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancerPoolMemberPrototype object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerPoolMemberPrototype') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerPoolMemberPrototype') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class LoadBalancerPoolMemberReference:
    """
    LoadBalancerPoolMemberReference.

    :attr LoadBalancerPoolMemberReferenceDeleted deleted: (optional) If present,
          this property indicates the referenced resource has been deleted, and provides
          some supplementary information.
    :attr str href: The member's canonical URL.
    :attr str id: The unique identifier for this load balancer pool member.
    """

    def __init__(
        self,
        href: str,
        id: str,
        *,
        deleted: 'LoadBalancerPoolMemberReferenceDeleted' = None,
    ) -> None:
        """
        Initialize a LoadBalancerPoolMemberReference object.

        :param str href: The member's canonical URL.
        :param str id: The unique identifier for this load balancer pool member.
        :param LoadBalancerPoolMemberReferenceDeleted deleted: (optional) If
               present, this property indicates the referenced resource has been deleted,
               and provides
               some supplementary information.
        """
        self.deleted = deleted
        self.href = href
        self.id = id

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerPoolMemberReference':
        """Initialize a LoadBalancerPoolMemberReference object from a json dictionary."""
        args = {}
        if 'deleted' in _dict:
            args['deleted'] = LoadBalancerPoolMemberReferenceDeleted.from_dict(_dict.get('deleted'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in LoadBalancerPoolMemberReference JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in LoadBalancerPoolMemberReference JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerPoolMemberReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'deleted') and self.deleted is not None:
            if isinstance(self.deleted, dict):
                _dict['deleted'] = self.deleted
            else:
                _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancerPoolMemberReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerPoolMemberReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerPoolMemberReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class LoadBalancerPoolMemberReferenceDeleted:
    """
    If present, this property indicates the referenced resource has been deleted, and
    provides some supplementary information.

    :attr str more_info: Link to documentation about deleted resources.
    """

    def __init__(
        self,
        more_info: str,
    ) -> None:
        """
        Initialize a LoadBalancerPoolMemberReferenceDeleted object.

        :param str more_info: Link to documentation about deleted resources.
        """
        self.more_info = more_info

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerPoolMemberReferenceDeleted':
        """Initialize a LoadBalancerPoolMemberReferenceDeleted object from a json dictionary."""
        args = {}
        if 'more_info' in _dict:
            args['more_info'] = _dict.get('more_info')
        else:
            raise ValueError('Required property \'more_info\' not present in LoadBalancerPoolMemberReferenceDeleted JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerPoolMemberReferenceDeleted object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'more_info') and self.more_info is not None:
            _dict['more_info'] = self.more_info
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancerPoolMemberReferenceDeleted object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerPoolMemberReferenceDeleted') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerPoolMemberReferenceDeleted') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class LoadBalancerPoolMemberTarget:
    """
    The pool member target. Load balancers in the `network` family support virtual server
    instances. Load balancers in the `application` family support IP addresses. If the
    load balancer has route mode enabled, the member must be in a zone the load balancer
    has a subnet in.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a LoadBalancerPoolMemberTarget object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['LoadBalancerPoolMemberTargetInstanceReference', 'LoadBalancerPoolMemberTargetIP'])
        )
        raise Exception(msg)


class LoadBalancerPoolMemberTargetPrototype:
    """
    The pool member target. Load balancers in the `network` family support virtual server
    instances. Load balancers in the `application` family support IP addresses. If the
    load balancer has route mode enabled, the member must be in a zone the load balancer
    has a subnet in.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a LoadBalancerPoolMemberTargetPrototype object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['LoadBalancerPoolMemberTargetPrototypeInstanceIdentity', 'LoadBalancerPoolMemberTargetPrototypeIP'])
        )
        raise Exception(msg)


class LoadBalancerPoolPatch:
    """
    LoadBalancerPoolPatch.

    :attr str algorithm: (optional) The load balancing algorithm.
    :attr LoadBalancerPoolHealthMonitorPatch health_monitor: (optional) The health
          monitor of this pool.
    :attr str name: (optional) The name for this load balancer pool. The name must
          not be used by another pool for the load balancer.
    :attr str protocol: (optional) The protocol for this load balancer pool.
          Load balancers in the `network` family support `tcp` and `udp` (if
          `udp_supported` is `true`). Load balancers in the `application` family support
          `tcp`, `http` and
          `https`.
          If this pool is associated with a load balancer listener, the specified protocol
          must match, or be compatible with the listener's protocol. At present, the
          compatible protocols are `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 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 name for this load balancer pool. The name
               must not be used by another pool for the load balancer.
        :param str protocol: (optional) The protocol for this load balancer pool.
               Load balancers in the `network` family support `tcp` and `udp` (if
               `udp_supported` is `true`). Load balancers in the `application` family
               support `tcp`, `http` and
               `https`.
               If this pool is associated with a load balancer listener, the specified
               protocol must match, or be compatible with the listener's protocol. At
               present, the compatible protocols are `http` and `https`.
        :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:
            if isinstance(self.health_monitor, dict):
                _dict['health_monitor'] = self.health_monitor
            else:
                _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:
            if isinstance(self.session_persistence, dict):
                _dict['session_persistence'] = self.session_persistence
            else:
                _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 for this load balancer pool.
        Load balancers in the `network` family support `tcp` and `udp` (if `udp_supported`
        is `true`). Load balancers in the `application` family support `tcp`, `http` and
        `https`.
        If this pool is associated with a load balancer listener, the specified protocol
        must match, or be compatible with the listener's protocol. At present, the
        compatible protocols are `http` and `https`.
        """

        HTTP = 'http'
        HTTPS = 'https'
        TCP = 'tcp'
        UDP = 'udp'


    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 name for this load balancer pool. The name must
          not be used by another pool for the load balancer. 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` and `udp` (if `udp_supported` is
          `true`). 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` and `udp` (if
               `udp_supported` is `true`). 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 name for this load balancer pool. The name
               must not be used by another pool for the load balancer. 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(v) for v 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:
            if isinstance(self.health_monitor, dict):
                _dict['health_monitor'] = self.health_monitor
            else:
                _dict['health_monitor'] = self.health_monitor.to_dict()
        if hasattr(self, 'members') and self.members is not None:
            members_list = []
            for v in self.members:
                if isinstance(v, dict):
                    members_list.append(v)
                else:
                    members_list.append(v.to_dict())
            _dict['members'] = members_list
        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:
            if isinstance(self.session_persistence, dict):
                _dict['session_persistence'] = self.session_persistence
            else:
                _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` and `udp` (if `udp_supported` is `true`). Load balancers in
        the
        `application` family support `tcp`, `http`, and `https`.
        """

        HTTP = 'http'
        HTTPS = 'https'
        TCP = 'tcp'
        UDP = 'udp'


    class ProxyProtocolEnum(str, Enum):
        """
        The PROXY protocol setting for this pool:
        - `v1`: Enabled with version 1 (human-readable header format)
        - `v2`: Enabled with version 2 (binary header format)
        - `disabled`: Disabled
        Supported by load balancers in the `application` family (otherwise always
        `disabled`).
        """

        DISABLED = 'disabled'
        V1 = 'v1'
        V2 = 'v2'



class LoadBalancerPoolReference:
    """
    LoadBalancerPoolReference.

    :attr LoadBalancerPoolReferenceDeleted deleted: (optional) If present, this
          property indicates the referenced resource has been deleted, and provides
          some supplementary information.
    :attr str href: The pool's canonical URL.
    :attr str id: The unique identifier for this load balancer pool.
    :attr str name: The name for this load balancer pool. The name is unique across
          all pools for the load balancer.
    """

    def __init__(
        self,
        href: str,
        id: str,
        name: str,
        *,
        deleted: 'LoadBalancerPoolReferenceDeleted' = None,
    ) -> None:
        """
        Initialize a LoadBalancerPoolReference object.

        :param str href: The pool's canonical URL.
        :param str id: The unique identifier for this load balancer pool.
        :param str name: The name for this load balancer pool. The name is unique
               across all pools for the load balancer.
        :param LoadBalancerPoolReferenceDeleted deleted: (optional) If present,
               this property indicates the referenced resource has been deleted, and
               provides
               some supplementary information.
        """
        self.deleted = deleted
        self.href = href
        self.id = id
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerPoolReference':
        """Initialize a LoadBalancerPoolReference object from a json dictionary."""
        args = {}
        if 'deleted' in _dict:
            args['deleted'] = LoadBalancerPoolReferenceDeleted.from_dict(_dict.get('deleted'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in LoadBalancerPoolReference JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in LoadBalancerPoolReference JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in LoadBalancerPoolReference JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerPoolReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'deleted') and self.deleted is not None:
            if isinstance(self.deleted, dict):
                _dict['deleted'] = self.deleted
            else:
                _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancerPoolReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerPoolReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerPoolReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class LoadBalancerPoolReferenceDeleted:
    """
    If present, this property indicates the referenced resource has been deleted, and
    provides some supplementary information.

    :attr str more_info: Link to documentation about deleted resources.
    """

    def __init__(
        self,
        more_info: str,
    ) -> None:
        """
        Initialize a LoadBalancerPoolReferenceDeleted object.

        :param str more_info: Link to documentation about deleted resources.
        """
        self.more_info = more_info

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerPoolReferenceDeleted':
        """Initialize a LoadBalancerPoolReferenceDeleted object from a json dictionary."""
        args = {}
        if 'more_info' in _dict:
            args['more_info'] = _dict.get('more_info')
        else:
            raise ValueError('Required property \'more_info\' not present in LoadBalancerPoolReferenceDeleted JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerPoolReferenceDeleted object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'more_info') and self.more_info is not None:
            _dict['more_info'] = self.more_info
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancerPoolReferenceDeleted object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerPoolReferenceDeleted') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerPoolReferenceDeleted') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class LoadBalancerPoolSessionPersistence:
    """
    LoadBalancerPoolSessionPersistence.

    :attr str cookie_name: (optional) The session persistence cookie name.
          Applicable only for type `app_cookie`. Names starting with `IBM` are not
          allowed.
    :attr str type: The session persistence type. The `http_cookie` and `app_cookie`
          types are applicable only to the `http` and `https` protocols.
    """

    def __init__(
        self,
        type: str,
        *,
        cookie_name: str = None,
    ) -> None:
        """
        Initialize a LoadBalancerPoolSessionPersistence object.

        :param str type: The session persistence type. The `http_cookie` and
               `app_cookie` types are applicable only to the `http` and `https` protocols.
        :param str cookie_name: (optional) The session persistence cookie name.
               Applicable only for type `app_cookie`. Names starting with `IBM` are not
               allowed.
        """
        self.cookie_name = cookie_name
        self.type = type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerPoolSessionPersistence':
        """Initialize a LoadBalancerPoolSessionPersistence object from a json dictionary."""
        args = {}
        if 'cookie_name' in _dict:
            args['cookie_name'] = _dict.get('cookie_name')
        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, 'cookie_name') and self.cookie_name is not None:
            _dict['cookie_name'] = self.cookie_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 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. The `http_cookie` and `app_cookie` types are
        applicable only to the `http` and `https` protocols.
        """

        APP_COOKIE = 'app_cookie'
        HTTP_COOKIE = 'http_cookie'
        SOURCE_IP = 'source_ip'



class LoadBalancerPoolSessionPersistencePatch:
    """
    The session persistence configuration. Specify `null` to remove any existing session
    persistence configuration.

    :attr str cookie_name: (optional) The session persistence cookie name.
          Applicable only for type `app_cookie`. Names starting with `IBM` are not
          allowed.
    :attr str type: (optional) The session persistence type. The `http_cookie` and
          `app_cookie` types are applicable only to the `http` and `https` protocols.
    """

    def __init__(
        self,
        *,
        cookie_name: str = None,
        type: str = None,
    ) -> None:
        """
        Initialize a LoadBalancerPoolSessionPersistencePatch object.

        :param str cookie_name: (optional) The session persistence cookie name.
               Applicable only for type `app_cookie`. Names starting with `IBM` are not
               allowed.
        :param str type: (optional) The session persistence type. The `http_cookie`
               and `app_cookie` types are applicable only to the `http` and `https`
               protocols.
        """
        self.cookie_name = cookie_name
        self.type = type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerPoolSessionPersistencePatch':
        """Initialize a LoadBalancerPoolSessionPersistencePatch object from a json dictionary."""
        args = {}
        if 'cookie_name' in _dict:
            args['cookie_name'] = _dict.get('cookie_name')
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        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, 'cookie_name') and self.cookie_name is not None:
            _dict['cookie_name'] = self.cookie_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 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. The `http_cookie` and `app_cookie` types are
        applicable only to the `http` and `https` protocols.
        """

        APP_COOKIE = 'app_cookie'
        HTTP_COOKIE = 'http_cookie'
        SOURCE_IP = 'source_ip'



class LoadBalancerPoolSessionPersistencePrototype:
    """
    LoadBalancerPoolSessionPersistencePrototype.

    :attr str cookie_name: (optional) The session persistence cookie name.
          Applicable only for type `app_cookie`. Names starting with `IBM` are not
          allowed.
    :attr str type: The session persistence type. The `http_cookie` and `app_cookie`
          types are applicable only to the `http` and `https` protocols.
    """

    def __init__(
        self,
        type: str,
        *,
        cookie_name: str = None,
    ) -> None:
        """
        Initialize a LoadBalancerPoolSessionPersistencePrototype object.

        :param str type: The session persistence type. The `http_cookie` and
               `app_cookie` types are applicable only to the `http` and `https` protocols.
        :param str cookie_name: (optional) The session persistence cookie name.
               Applicable only for type `app_cookie`. Names starting with `IBM` are not
               allowed.
        """
        self.cookie_name = cookie_name
        self.type = type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerPoolSessionPersistencePrototype':
        """Initialize a LoadBalancerPoolSessionPersistencePrototype object from a json dictionary."""
        args = {}
        if 'cookie_name' in _dict:
            args['cookie_name'] = _dict.get('cookie_name')
        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, 'cookie_name') and self.cookie_name is not None:
            _dict['cookie_name'] = self.cookie_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 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. The `http_cookie` and `app_cookie` types are
        applicable only to the `http` and `https` protocols.
        """

        APP_COOKIE = 'app_cookie'
        HTTP_COOKIE = 'http_cookie'
        SOURCE_IP = 'source_ip'



class LoadBalancerPrivateIpsItem:
    """
    LoadBalancerPrivateIpsItem.

    :attr str address: The IP address.
          If the address has not yet been selected, the value will be `0.0.0.0`.
          This property may add support for IPv6 addresses in the future. When processing
          a value in this property, verify that the address is in an expected format. If
          it is not, log an error. Optionally halt processing and surface the error, or
          bypass the resource on which the unexpected IP address format was encountered.
    :attr ReservedIPReferenceDeleted deleted: (optional) If present, this property
          indicates the referenced resource has been deleted, and provides
          some supplementary information.
    :attr str href: The URL for this reserved IP.
    :attr str id: The unique identifier for this reserved IP.
    :attr str name: The name for this reserved IP. The name is unique across all
          reserved IPs in a subnet.
    :attr str resource_type: The resource type.
    """

    def __init__(
        self,
        address: str,
        href: str,
        id: str,
        name: str,
        resource_type: str,
        *,
        deleted: 'ReservedIPReferenceDeleted' = None,
    ) -> None:
        """
        Initialize a LoadBalancerPrivateIpsItem object.

        :param str address: The IP address.
               If the address has not yet been selected, the value will be `0.0.0.0`.
               This property may add support for IPv6 addresses in the future. When
               processing a value in this property, verify that the address is in an
               expected format. If it is not, log an error. Optionally halt processing and
               surface the error, or bypass the resource on which the unexpected IP
               address format was encountered.
        :param str href: The URL for this reserved IP.
        :param str id: The unique identifier for this reserved IP.
        :param str name: The name for this reserved IP. The name is unique across
               all reserved IPs in a subnet.
        :param str resource_type: The resource type.
        :param ReservedIPReferenceDeleted deleted: (optional) If present, this
               property indicates the referenced resource has been deleted, and provides
               some supplementary information.
        """
        self.address = address
        self.deleted = deleted
        self.href = href
        self.id = id
        self.name = name
        self.resource_type = resource_type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerPrivateIpsItem':
        """Initialize a LoadBalancerPrivateIpsItem object from a json dictionary."""
        args = {}
        if 'address' in _dict:
            args['address'] = _dict.get('address')
        else:
            raise ValueError('Required property \'address\' not present in LoadBalancerPrivateIpsItem JSON')
        if 'deleted' in _dict:
            args['deleted'] = ReservedIPReferenceDeleted.from_dict(_dict.get('deleted'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in LoadBalancerPrivateIpsItem JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in LoadBalancerPrivateIpsItem JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in LoadBalancerPrivateIpsItem JSON')
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError('Required property \'resource_type\' not present in LoadBalancerPrivateIpsItem JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerPrivateIpsItem object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'address') and self.address is not None:
            _dict['address'] = self.address
        if hasattr(self, 'deleted') and self.deleted is not None:
            if isinstance(self.deleted, dict):
                _dict['deleted'] = self.deleted
            else:
                _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'resource_type') and self.resource_type is not None:
            _dict['resource_type'] = self.resource_type
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancerPrivateIpsItem object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerPrivateIpsItem') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerPrivateIpsItem') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        SUBNET_RESERVED_IP = 'subnet_reserved_ip'



class LoadBalancerProfile:
    """
    LoadBalancerProfile.

    :attr str family: The product family this load balancer profile belongs to.
    :attr str href: The URL for this load balancer profile.
    :attr LoadBalancerProfileInstanceGroupsSupported instance_groups_supported:
    :attr LoadBalancerProfileLoggingSupported logging_supported: Indicates which
          logging type(s) are supported for a load balancer with this profile.
    :attr str name: The globally unique name for this load balancer profile.
    :attr LoadBalancerProfileRouteModeSupported route_mode_supported:
    :attr LoadBalancerProfileSecurityGroupsSupported security_groups_supported:
    :attr LoadBalancerProfileUDPSupported udp_supported:
    """

    def __init__(
        self,
        family: str,
        href: str,
        instance_groups_supported: 'LoadBalancerProfileInstanceGroupsSupported',
        logging_supported: 'LoadBalancerProfileLoggingSupported',
        name: str,
        route_mode_supported: 'LoadBalancerProfileRouteModeSupported',
        security_groups_supported: 'LoadBalancerProfileSecurityGroupsSupported',
        udp_supported: 'LoadBalancerProfileUDPSupported',
    ) -> None:
        """
        Initialize a LoadBalancerProfile object.

        :param str family: The product family this load balancer profile belongs
               to.
        :param str href: The URL for this load balancer profile.
        :param LoadBalancerProfileInstanceGroupsSupported
               instance_groups_supported:
        :param LoadBalancerProfileLoggingSupported logging_supported: Indicates
               which logging type(s) are supported for a load balancer with this profile.
        :param str name: The globally unique name for this load balancer profile.
        :param LoadBalancerProfileRouteModeSupported route_mode_supported:
        :param LoadBalancerProfileSecurityGroupsSupported
               security_groups_supported:
        :param LoadBalancerProfileUDPSupported udp_supported:
        """
        self.family = family
        self.href = href
        self.instance_groups_supported = instance_groups_supported
        self.logging_supported = logging_supported
        self.name = name
        self.route_mode_supported = route_mode_supported
        self.security_groups_supported = security_groups_supported
        self.udp_supported = udp_supported

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerProfile':
        """Initialize a LoadBalancerProfile object from a json dictionary."""
        args = {}
        if 'family' in _dict:
            args['family'] = _dict.get('family')
        else:
            raise ValueError('Required property \'family\' not present in LoadBalancerProfile JSON')
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in LoadBalancerProfile JSON')
        if 'instance_groups_supported' in _dict:
            args['instance_groups_supported'] = _dict.get('instance_groups_supported')
        else:
            raise ValueError('Required property \'instance_groups_supported\' not present in LoadBalancerProfile JSON')
        if 'logging_supported' in _dict:
            args['logging_supported'] = LoadBalancerProfileLoggingSupported.from_dict(_dict.get('logging_supported'))
        else:
            raise ValueError('Required property \'logging_supported\' not present in LoadBalancerProfile JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in LoadBalancerProfile JSON')
        if 'route_mode_supported' in _dict:
            args['route_mode_supported'] = _dict.get('route_mode_supported')
        else:
            raise ValueError('Required property \'route_mode_supported\' not present in LoadBalancerProfile JSON')
        if 'security_groups_supported' in _dict:
            args['security_groups_supported'] = _dict.get('security_groups_supported')
        else:
            raise ValueError('Required property \'security_groups_supported\' not present in LoadBalancerProfile JSON')
        if 'udp_supported' in _dict:
            args['udp_supported'] = _dict.get('udp_supported')
        else:
            raise ValueError('Required property \'udp_supported\' not present in LoadBalancerProfile JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerProfile object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'family') and self.family is not None:
            _dict['family'] = self.family
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'instance_groups_supported') and self.instance_groups_supported is not None:
            if isinstance(self.instance_groups_supported, dict):
                _dict['instance_groups_supported'] = self.instance_groups_supported
            else:
                _dict['instance_groups_supported'] = self.instance_groups_supported.to_dict()
        if hasattr(self, 'logging_supported') and self.logging_supported is not None:
            if isinstance(self.logging_supported, dict):
                _dict['logging_supported'] = self.logging_supported
            else:
                _dict['logging_supported'] = self.logging_supported.to_dict()
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'route_mode_supported') and self.route_mode_supported is not None:
            if isinstance(self.route_mode_supported, dict):
                _dict['route_mode_supported'] = self.route_mode_supported
            else:
                _dict['route_mode_supported'] = self.route_mode_supported.to_dict()
        if hasattr(self, 'security_groups_supported') and self.security_groups_supported is not None:
            if isinstance(self.security_groups_supported, dict):
                _dict['security_groups_supported'] = self.security_groups_supported
            else:
                _dict['security_groups_supported'] = self.security_groups_supported.to_dict()
        if hasattr(self, 'udp_supported') and self.udp_supported is not None:
            if isinstance(self.udp_supported, dict):
                _dict['udp_supported'] = self.udp_supported
            else:
                _dict['udp_supported'] = self.udp_supported.to_dict()
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancerProfile object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerProfile') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerProfile') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class LoadBalancerProfileCollection:
    """
    LoadBalancerProfileCollection.

    :attr LoadBalancerProfileCollectionFirst first: A link to the first page of
          resources.
    :attr int limit: The maximum number of resources that can be returned by the
          request.
    :attr LoadBalancerProfileCollectionNext next: (optional) A link to the next page
          of resources. This property is present for all pages
          except the last page.
    :attr List[LoadBalancerProfile] profiles: Collection of load balancer profiles.
    :attr int total_count: The total number of resources across all pages.
    """

    def __init__(
        self,
        first: 'LoadBalancerProfileCollectionFirst',
        limit: int,
        profiles: List['LoadBalancerProfile'],
        total_count: int,
        *,
        next: 'LoadBalancerProfileCollectionNext' = None,
    ) -> None:
        """
        Initialize a LoadBalancerProfileCollection object.

        :param LoadBalancerProfileCollectionFirst first: A link to the first page
               of resources.
        :param int limit: The maximum number of resources that can be returned by
               the request.
        :param List[LoadBalancerProfile] profiles: Collection of load balancer
               profiles.
        :param int total_count: The total number of resources across all pages.
        :param LoadBalancerProfileCollectionNext next: (optional) A link to the
               next page of resources. This property is present for all pages
               except the last page.
        """
        self.first = first
        self.limit = limit
        self.next = next
        self.profiles = profiles
        self.total_count = total_count

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerProfileCollection':
        """Initialize a LoadBalancerProfileCollection object from a json dictionary."""
        args = {}
        if 'first' in _dict:
            args['first'] = LoadBalancerProfileCollectionFirst.from_dict(_dict.get('first'))
        else:
            raise ValueError('Required property \'first\' not present in LoadBalancerProfileCollection JSON')
        if 'limit' in _dict:
            args['limit'] = _dict.get('limit')
        else:
            raise ValueError('Required property \'limit\' not present in LoadBalancerProfileCollection JSON')
        if 'next' in _dict:
            args['next'] = LoadBalancerProfileCollectionNext.from_dict(_dict.get('next'))
        if 'profiles' in _dict:
            args['profiles'] = [LoadBalancerProfile.from_dict(v) for v in _dict.get('profiles')]
        else:
            raise ValueError('Required property \'profiles\' not present in LoadBalancerProfileCollection JSON')
        if 'total_count' in _dict:
            args['total_count'] = _dict.get('total_count')
        else:
            raise ValueError('Required property \'total_count\' not present in LoadBalancerProfileCollection JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerProfileCollection object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'first') and self.first is not None:
            if isinstance(self.first, dict):
                _dict['first'] = self.first
            else:
                _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:
            if isinstance(self.next, dict):
                _dict['next'] = self.next
            else:
                _dict['next'] = self.next.to_dict()
        if hasattr(self, 'profiles') and self.profiles is not None:
            profiles_list = []
            for v in self.profiles:
                if isinstance(v, dict):
                    profiles_list.append(v)
                else:
                    profiles_list.append(v.to_dict())
            _dict['profiles'] = profiles_list
        if hasattr(self, 'total_count') and self.total_count is not None:
            _dict['total_count'] = self.total_count
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancerProfileCollection object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerProfileCollection') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerProfileCollection') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class LoadBalancerProfileCollectionFirst:
    """
    A link to the first page of resources.

    :attr str href: The URL for a page of resources.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a LoadBalancerProfileCollectionFirst object.

        :param str href: The URL for a page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerProfileCollectionFirst':
        """Initialize a LoadBalancerProfileCollectionFirst object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in LoadBalancerProfileCollectionFirst JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerProfileCollectionFirst object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancerProfileCollectionFirst object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerProfileCollectionFirst') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerProfileCollectionFirst') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class LoadBalancerProfileCollectionNext:
    """
    A link to the next page of resources. This property is present for all pages except
    the last page.

    :attr str href: The URL for a page of resources.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a LoadBalancerProfileCollectionNext object.

        :param str href: The URL for a page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerProfileCollectionNext':
        """Initialize a LoadBalancerProfileCollectionNext object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in LoadBalancerProfileCollectionNext JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerProfileCollectionNext object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancerProfileCollectionNext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerProfileCollectionNext') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerProfileCollectionNext') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class LoadBalancerProfileIdentity:
    """
    Identifies a load balancer profile by a unique property.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a LoadBalancerProfileIdentity object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['LoadBalancerProfileIdentityByName', 'LoadBalancerProfileIdentityByHref'])
        )
        raise Exception(msg)


class LoadBalancerProfileInstanceGroupsSupported:
    """
    LoadBalancerProfileInstanceGroupsSupported.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a LoadBalancerProfileInstanceGroupsSupported object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['LoadBalancerProfileInstanceGroupsSupportedFixed', 'LoadBalancerProfileInstanceGroupsSupportedDependent'])
        )
        raise Exception(msg)


class LoadBalancerProfileLoggingSupported:
    """
    Indicates which logging type(s) are supported for a load balancer with this profile.

    :attr str type: The type for this profile field.
    :attr List[str] value: The supported logging type(s) for a load balancer with
          this profile.
    """

    def __init__(
        self,
        type: str,
        value: List[str],
    ) -> None:
        """
        Initialize a LoadBalancerProfileLoggingSupported object.

        :param str type: The type for this profile field.
        :param List[str] value: The supported logging type(s) for a load balancer
               with this profile.
        """
        self.type = type
        self.value = value

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerProfileLoggingSupported':
        """Initialize a LoadBalancerProfileLoggingSupported object from a json dictionary."""
        args = {}
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in LoadBalancerProfileLoggingSupported JSON')
        if 'value' in _dict:
            args['value'] = _dict.get('value')
        else:
            raise ValueError('Required property \'value\' not present in LoadBalancerProfileLoggingSupported JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerProfileLoggingSupported object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'type') and self.type is not None:
            _dict['type'] = self.type
        if hasattr(self, 'value') and self.value is not None:
            _dict['value'] = self.value
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancerProfileLoggingSupported object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerProfileLoggingSupported') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerProfileLoggingSupported') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class TypeEnum(str, Enum):
        """
        The type for this profile field.
        """

        FIXED = 'fixed'



class LoadBalancerProfileReference:
    """
    LoadBalancerProfileReference.

    :attr str family: The product family this load balancer profile belongs to.
    :attr str href: The URL for this load balancer profile.
    :attr str name: The globally unique name for this load balancer profile.
    """

    def __init__(
        self,
        family: str,
        href: str,
        name: str,
    ) -> None:
        """
        Initialize a LoadBalancerProfileReference object.

        :param str family: The product family this load balancer profile belongs
               to.
        :param str href: The URL for this load balancer profile.
        :param str name: The globally unique name for this load balancer profile.
        """
        self.family = family
        self.href = href
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerProfileReference':
        """Initialize a LoadBalancerProfileReference object from a json dictionary."""
        args = {}
        if 'family' in _dict:
            args['family'] = _dict.get('family')
        else:
            raise ValueError('Required property \'family\' not present in LoadBalancerProfileReference JSON')
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in LoadBalancerProfileReference JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in LoadBalancerProfileReference JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerProfileReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'family') and self.family is not None:
            _dict['family'] = self.family
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancerProfileReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerProfileReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerProfileReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class LoadBalancerProfileRouteModeSupported:
    """
    LoadBalancerProfileRouteModeSupported.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a LoadBalancerProfileRouteModeSupported object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['LoadBalancerProfileRouteModeSupportedFixed', 'LoadBalancerProfileRouteModeSupportedDependent'])
        )
        raise Exception(msg)


class LoadBalancerProfileSecurityGroupsSupported:
    """
    LoadBalancerProfileSecurityGroupsSupported.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a LoadBalancerProfileSecurityGroupsSupported object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['LoadBalancerProfileSecurityGroupsSupportedFixed', 'LoadBalancerProfileSecurityGroupsSupportedDependent'])
        )
        raise Exception(msg)


class LoadBalancerProfileUDPSupported:
    """
    LoadBalancerProfileUDPSupported.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a LoadBalancerProfileUDPSupported object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['LoadBalancerProfileUDPSupportedFixed', 'LoadBalancerProfileUDPSupportedDependent'])
        )
        raise Exception(msg)


class LoadBalancerReferenceDeleted:
    """
    If present, this property indicates the referenced resource has been deleted, and
    provides some supplementary information.

    :attr str more_info: Link to documentation about deleted resources.
    """

    def __init__(
        self,
        more_info: str,
    ) -> None:
        """
        Initialize a LoadBalancerReferenceDeleted object.

        :param str more_info: Link to documentation about deleted resources.
        """
        self.more_info = more_info

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerReferenceDeleted':
        """Initialize a LoadBalancerReferenceDeleted object from a json dictionary."""
        args = {}
        if 'more_info' in _dict:
            args['more_info'] = _dict.get('more_info')
        else:
            raise ValueError('Required property \'more_info\' not present in LoadBalancerReferenceDeleted JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerReferenceDeleted object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'more_info') and self.more_info is not None:
            _dict['more_info'] = self.more_info
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancerReferenceDeleted object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerReferenceDeleted') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerReferenceDeleted') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class LoadBalancerStatistics:
    """
    LoadBalancerStatistics.

    :attr int active_connections: Number of active connections of this load
          balancer.
    :attr float connection_rate: Current connection rate (connections per second) of
          this load balancer.
    :attr int data_processed_this_month: Total number of data processed (bytes) of
          this load balancer within current calendar month.
    :attr float throughput: Current throughput (Mbps) of this load balancer.
    """

    def __init__(
        self,
        active_connections: int,
        connection_rate: float,
        data_processed_this_month: int,
        throughput: float,
    ) -> None:
        """
        Initialize a LoadBalancerStatistics object.

        :param int active_connections: Number of active connections of this load
               balancer.
        :param float connection_rate: Current connection rate (connections per
               second) of this load balancer.
        :param int data_processed_this_month: Total number of data processed
               (bytes) of this load balancer within current calendar month.
        :param float throughput: Current throughput (Mbps) of this load balancer.
        """
        self.active_connections = active_connections
        self.connection_rate = connection_rate
        self.data_processed_this_month = data_processed_this_month
        self.throughput = throughput

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerStatistics':
        """Initialize a LoadBalancerStatistics object from a json dictionary."""
        args = {}
        if 'active_connections' in _dict:
            args['active_connections'] = _dict.get('active_connections')
        else:
            raise ValueError('Required property \'active_connections\' not present in LoadBalancerStatistics JSON')
        if 'connection_rate' in _dict:
            args['connection_rate'] = _dict.get('connection_rate')
        else:
            raise ValueError('Required property \'connection_rate\' not present in LoadBalancerStatistics JSON')
        if 'data_processed_this_month' in _dict:
            args['data_processed_this_month'] = _dict.get('data_processed_this_month')
        else:
            raise ValueError('Required property \'data_processed_this_month\' not present in LoadBalancerStatistics JSON')
        if 'throughput' in _dict:
            args['throughput'] = _dict.get('throughput')
        else:
            raise ValueError('Required property \'throughput\' not present in LoadBalancerStatistics JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerStatistics object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'active_connections') and self.active_connections is not None:
            _dict['active_connections'] = self.active_connections
        if hasattr(self, 'connection_rate') and self.connection_rate is not None:
            _dict['connection_rate'] = self.connection_rate
        if hasattr(self, 'data_processed_this_month') and self.data_processed_this_month is not None:
            _dict['data_processed_this_month'] = self.data_processed_this_month
        if hasattr(self, 'throughput') and self.throughput is not None:
            _dict['throughput'] = self.throughput
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancerStatistics object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerStatistics') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerStatistics') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class NetworkACL:
    """
    NetworkACL.

    :attr datetime created_at: The date and time that the network ACL was created.
    :attr str crn: The CRN for this network ACL.
    :attr str href: The URL for this network ACL.
    :attr str id: The unique identifier for this network ACL.
    :attr str name: The name for this network ACL. The name is unique across all
          network ACLs for the VPC.
    :attr ResourceGroupReference resource_group: The resource group for this network
          ACL.
    :attr List[NetworkACLRuleItem] rules: The ordered rules for this network ACL. If
          no rules exist, all traffic will be denied.
    :attr List[SubnetReference] subnets: The subnets to which this network ACL is
          attached.
    :attr VPCReference vpc: The VPC this network ACL resides in.
    """

    def __init__(
        self,
        created_at: datetime,
        crn: str,
        href: str,
        id: str,
        name: str,
        resource_group: 'ResourceGroupReference',
        rules: List['NetworkACLRuleItem'],
        subnets: List['SubnetReference'],
        vpc: 'VPCReference',
    ) -> None:
        """
        Initialize a NetworkACL object.

        :param datetime created_at: The date and time that the network ACL was
               created.
        :param str crn: The CRN for this network ACL.
        :param str href: The URL for this network ACL.
        :param str id: The unique identifier for this network ACL.
        :param str name: The name for this network ACL. The name is unique across
               all network ACLs for the VPC.
        :param ResourceGroupReference resource_group: The resource group for this
               network ACL.
        :param List[NetworkACLRuleItem] rules: The ordered rules for this network
               ACL. If no rules exist, all traffic will be denied.
        :param List[SubnetReference] subnets: The subnets to which this network ACL
               is attached.
        :param VPCReference vpc: The VPC this network ACL resides in.
        """
        self.created_at = created_at
        self.crn = crn
        self.href = href
        self.id = id
        self.name = name
        self.resource_group = resource_group
        self.rules = rules
        self.subnets = subnets
        self.vpc = vpc

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'NetworkACL':
        """Initialize a NetworkACL object from a json dictionary."""
        args = {}
        if 'created_at' in _dict:
            args['created_at'] = string_to_datetime(_dict.get('created_at'))
        else:
            raise ValueError('Required property \'created_at\' not present in NetworkACL JSON')
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError('Required property \'crn\' not present in NetworkACL JSON')
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in NetworkACL JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in NetworkACL JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in NetworkACL JSON')
        if 'resource_group' in _dict:
            args['resource_group'] = ResourceGroupReference.from_dict(_dict.get('resource_group'))
        else:
            raise ValueError('Required property \'resource_group\' not present in NetworkACL JSON')
        if 'rules' in _dict:
            args['rules'] = [NetworkACLRuleItem.from_dict(v) for v in _dict.get('rules')]
        else:
            raise ValueError('Required property \'rules\' not present in NetworkACL JSON')
        if 'subnets' in _dict:
            args['subnets'] = [SubnetReference.from_dict(v) for v in _dict.get('subnets')]
        else:
            raise ValueError('Required property \'subnets\' not present in NetworkACL JSON')
        if 'vpc' in _dict:
            args['vpc'] = VPCReference.from_dict(_dict.get('vpc'))
        else:
            raise ValueError('Required property \'vpc\' not present in NetworkACL JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a NetworkACL object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'created_at') and self.created_at is not None:
            _dict['created_at'] = datetime_to_string(self.created_at)
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'resource_group') and self.resource_group is not None:
            if isinstance(self.resource_group, dict):
                _dict['resource_group'] = self.resource_group
            else:
                _dict['resource_group'] = self.resource_group.to_dict()
        if hasattr(self, 'rules') and self.rules is not None:
            rules_list = []
            for v in self.rules:
                if isinstance(v, dict):
                    rules_list.append(v)
                else:
                    rules_list.append(v.to_dict())
            _dict['rules'] = rules_list
        if hasattr(self, 'subnets') and self.subnets is not None:
            subnets_list = []
            for v in self.subnets:
                if isinstance(v, dict):
                    subnets_list.append(v)
                else:
                    subnets_list.append(v.to_dict())
            _dict['subnets'] = subnets_list
        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()
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this NetworkACL object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'NetworkACL') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'NetworkACL') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class NetworkACLCollection:
    """
    NetworkACLCollection.

    :attr NetworkACLCollectionFirst first: A link to the first page of resources.
    :attr int limit: The maximum number of resources that can be returned by the
          request.
    :attr List[NetworkACL] network_acls: Collection of network ACLs.
    :attr NetworkACLCollectionNext next: (optional) A link to the next page of
          resources. This property is present for all pages
          except the last page.
    :attr int total_count: The total number of resources across all pages.
    """

    def __init__(
        self,
        first: 'NetworkACLCollectionFirst',
        limit: int,
        network_acls: List['NetworkACL'],
        total_count: int,
        *,
        next: 'NetworkACLCollectionNext' = None,
    ) -> None:
        """
        Initialize a NetworkACLCollection object.

        :param NetworkACLCollectionFirst first: A link to the first page of
               resources.
        :param int limit: The maximum number of resources that can be returned by
               the request.
        :param List[NetworkACL] network_acls: Collection of network ACLs.
        :param int total_count: The total number of resources across all pages.
        :param NetworkACLCollectionNext next: (optional) A link to the next page of
               resources. This property is present for all pages
               except the last page.
        """
        self.first = first
        self.limit = limit
        self.network_acls = network_acls
        self.next = next
        self.total_count = total_count

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'NetworkACLCollection':
        """Initialize a NetworkACLCollection object from a json dictionary."""
        args = {}
        if 'first' in _dict:
            args['first'] = NetworkACLCollectionFirst.from_dict(_dict.get('first'))
        else:
            raise ValueError('Required property \'first\' not present in NetworkACLCollection JSON')
        if 'limit' in _dict:
            args['limit'] = _dict.get('limit')
        else:
            raise ValueError('Required property \'limit\' not present in NetworkACLCollection JSON')
        if 'network_acls' in _dict:
            args['network_acls'] = [NetworkACL.from_dict(v) for v in _dict.get('network_acls')]
        else:
            raise ValueError('Required property \'network_acls\' not present in NetworkACLCollection JSON')
        if 'next' in _dict:
            args['next'] = NetworkACLCollectionNext.from_dict(_dict.get('next'))
        if 'total_count' in _dict:
            args['total_count'] = _dict.get('total_count')
        else:
            raise ValueError('Required property \'total_count\' not present in NetworkACLCollection JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a NetworkACLCollection object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'first') and self.first is not None:
            if isinstance(self.first, dict):
                _dict['first'] = self.first
            else:
                _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:
            network_acls_list = []
            for v in self.network_acls:
                if isinstance(v, dict):
                    network_acls_list.append(v)
                else:
                    network_acls_list.append(v.to_dict())
            _dict['network_acls'] = network_acls_list
        if hasattr(self, 'next') and self.next is not None:
            if isinstance(self.next, dict):
                _dict['next'] = self.next
            else:
                _dict['next'] = self.next.to_dict()
        if hasattr(self, 'total_count') and self.total_count is not None:
            _dict['total_count'] = self.total_count
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this NetworkACLCollection object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'NetworkACLCollection') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'NetworkACLCollection') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class NetworkACLCollectionFirst:
    """
    A link to the first page of resources.

    :attr str href: The URL for a page of resources.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a NetworkACLCollectionFirst object.

        :param str href: The URL for a page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'NetworkACLCollectionFirst':
        """Initialize a NetworkACLCollectionFirst object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in NetworkACLCollectionFirst JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a NetworkACLCollectionFirst object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this NetworkACLCollectionFirst object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'NetworkACLCollectionFirst') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'NetworkACLCollectionFirst') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class NetworkACLCollectionNext:
    """
    A link to the next page of resources. This property is present for all pages except
    the last page.

    :attr str href: The URL for a page of resources.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a NetworkACLCollectionNext object.

        :param str href: The URL for a page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'NetworkACLCollectionNext':
        """Initialize a NetworkACLCollectionNext object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in NetworkACLCollectionNext JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a NetworkACLCollectionNext object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this NetworkACLCollectionNext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'NetworkACLCollectionNext') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'NetworkACLCollectionNext') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class NetworkACLIdentity:
    """
    Identifies a network ACL by a unique property.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a NetworkACLIdentity object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['NetworkACLIdentityById', 'NetworkACLIdentityByCRN', 'NetworkACLIdentityByHref'])
        )
        raise Exception(msg)


class NetworkACLPatch:
    """
    NetworkACLPatch.

    :attr str name: (optional) The name for this network ACL. The name must not be
          used by another network ACL for the VPC.
    """

    def __init__(
        self,
        *,
        name: str = None,
    ) -> None:
        """
        Initialize a NetworkACLPatch object.

        :param str name: (optional) The name for this network ACL. The name must
               not be used by another network ACL for the VPC.
        """
        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 name for this network ACL. The name must not be
          used by another network ACL for the VPC. 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) will be
          used.
    :attr VPCIdentity vpc: The VPC this network ACL will reside in.
    """

    def __init__(
        self,
        vpc: 'VPCIdentity',
        *,
        name: str = None,
        resource_group: 'ResourceGroupIdentity' = None,
    ) -> None:
        """
        Initialize a NetworkACLPrototype object.

        :param VPCIdentity vpc: The VPC this network ACL will reside in.
        :param str name: (optional) The name for this network ACL. The name must
               not be used by another network ACL for the 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) will be
               used.
        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['NetworkACLPrototypeNetworkACLByRules', 'NetworkACLPrototypeNetworkACLBySourceNetworkACL'])
        )
        raise Exception(msg)


class NetworkACLReference:
    """
    NetworkACLReference.

    :attr str crn: The CRN for this network ACL.
    :attr NetworkACLReferenceDeleted deleted: (optional) If present, this property
          indicates the referenced resource has been deleted, and provides
          some supplementary information.
    :attr str href: The URL for this network ACL.
    :attr str id: The unique identifier for this network ACL.
    :attr str name: The name for this network ACL. The name is unique across all
          network ACLs for the VPC.
    """

    def __init__(
        self,
        crn: str,
        href: str,
        id: str,
        name: str,
        *,
        deleted: 'NetworkACLReferenceDeleted' = None,
    ) -> None:
        """
        Initialize a NetworkACLReference object.

        :param str crn: The CRN for this network ACL.
        :param str href: The URL for this network ACL.
        :param str id: The unique identifier for this network ACL.
        :param str name: The name for this network ACL. The name is unique across
               all network ACLs for the VPC.
        :param NetworkACLReferenceDeleted deleted: (optional) If present, this
               property indicates the referenced resource has been deleted, and provides
               some supplementary information.
        """
        self.crn = crn
        self.deleted = deleted
        self.href = href
        self.id = id
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'NetworkACLReference':
        """Initialize a NetworkACLReference object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError('Required property \'crn\' not present in NetworkACLReference JSON')
        if 'deleted' in _dict:
            args['deleted'] = NetworkACLReferenceDeleted.from_dict(_dict.get('deleted'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in NetworkACLReference JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in NetworkACLReference JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in NetworkACLReference JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a NetworkACLReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'deleted') and self.deleted is not None:
            if isinstance(self.deleted, dict):
                _dict['deleted'] = self.deleted
            else:
                _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this NetworkACLReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'NetworkACLReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'NetworkACLReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class NetworkACLReferenceDeleted:
    """
    If present, this property indicates the referenced resource has been deleted, and
    provides some supplementary information.

    :attr str more_info: Link to documentation about deleted resources.
    """

    def __init__(
        self,
        more_info: str,
    ) -> None:
        """
        Initialize a NetworkACLReferenceDeleted object.

        :param str more_info: Link to documentation about deleted resources.
        """
        self.more_info = more_info

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'NetworkACLReferenceDeleted':
        """Initialize a NetworkACLReferenceDeleted object from a json dictionary."""
        args = {}
        if 'more_info' in _dict:
            args['more_info'] = _dict.get('more_info')
        else:
            raise ValueError('Required property \'more_info\' not present in NetworkACLReferenceDeleted JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a NetworkACLReferenceDeleted object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'more_info') and self.more_info is not None:
            _dict['more_info'] = self.more_info
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this NetworkACLReferenceDeleted object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'NetworkACLReferenceDeleted') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'NetworkACLReferenceDeleted') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class NetworkACLRule:
    """
    NetworkACLRule.

    :attr str action: The action to perform for a packet matching the rule.
    :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 IP address or CIDR block to match. The
          CIDR block `0.0.0.0/0` matches all destination addresses.
    :attr str direction: The direction of traffic to match.
    :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 name for this network ACL rule. The name is unique across
          all rules for the network ACL.
    :attr str protocol: The protocol to enforce.
    :attr str source: The source IP address or CIDR block to match. The CIDR block
          `0.0.0.0/0` matches all source 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: The action to perform for a packet matching the rule.
        :param datetime created_at: The date and time that the rule was created.
        :param str destination: The destination IP address or CIDR block to match.
               The CIDR block `0.0.0.0/0` matches all destination addresses.
        :param str direction: The direction of traffic to match.
        :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 name for this network ACL rule. The name is unique
               across all rules for the network ACL.
        :param str protocol: The protocol to enforce.
        :param str source: The source IP address or CIDR block to match. The CIDR
               block `0.0.0.0/0` matches all source 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):
        """
        The action to perform for a packet matching the rule.
        """

        ALLOW = 'allow'
        DENY = 'deny'


    class DirectionEnum(str, Enum):
        """
        The direction of traffic to match.
        """

        INBOUND = 'inbound'
        OUTBOUND = 'outbound'


    class IpVersionEnum(str, Enum):
        """
        The IP version for this rule.
        """

        IPV4 = 'ipv4'


    class ProtocolEnum(str, Enum):
        """
        The protocol to enforce.
        """

        ALL = 'all'
        ICMP = 'icmp'
        TCP = 'tcp'
        UDP = 'udp'



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 unspecified, this rule will be inserted after all existing rules.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a NetworkACLRuleBeforePrototype object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['NetworkACLRuleBeforePrototypeNetworkACLRuleIdentityById', 'NetworkACLRuleBeforePrototypeNetworkACLRuleIdentityByHref'])
        )
        raise Exception(msg)


class NetworkACLRuleCollection:
    """
    NetworkACLRuleCollection.

    :attr NetworkACLRuleCollectionFirst first: A link to the first page of
          resources.
    :attr int limit: The maximum number of resources that can be returned by the
          request.
    :attr NetworkACLRuleCollectionNext next: (optional) A link to the next page of
          resources. This property is present for all pages
          except the last page.
    :attr List[NetworkACLRuleItem] rules: Ordered collection of network ACL rules.
    :attr int total_count: The total number of resources across all pages.
    """

    def __init__(
        self,
        first: 'NetworkACLRuleCollectionFirst',
        limit: int,
        rules: List['NetworkACLRuleItem'],
        total_count: int,
        *,
        next: 'NetworkACLRuleCollectionNext' = None,
    ) -> None:
        """
        Initialize a NetworkACLRuleCollection object.

        :param NetworkACLRuleCollectionFirst first: A link to the first page of
               resources.
        :param int limit: The maximum number of resources that can be returned by
               the request.
        :param List[NetworkACLRuleItem] rules: Ordered collection of network ACL
               rules.
        :param int total_count: The total number of resources across all pages.
        :param NetworkACLRuleCollectionNext next: (optional) A link to the next
               page of resources. This property is present for all pages
               except the last page.
        """
        self.first = first
        self.limit = limit
        self.next = next
        self.rules = rules
        self.total_count = total_count

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'NetworkACLRuleCollection':
        """Initialize a NetworkACLRuleCollection object from a json dictionary."""
        args = {}
        if 'first' in _dict:
            args['first'] = NetworkACLRuleCollectionFirst.from_dict(_dict.get('first'))
        else:
            raise ValueError('Required property \'first\' not present in NetworkACLRuleCollection JSON')
        if 'limit' in _dict:
            args['limit'] = _dict.get('limit')
        else:
            raise ValueError('Required property \'limit\' not present in NetworkACLRuleCollection JSON')
        if 'next' in _dict:
            args['next'] = NetworkACLRuleCollectionNext.from_dict(_dict.get('next'))
        if 'rules' in _dict:
            args['rules'] = [NetworkACLRuleItem.from_dict(v) for v in _dict.get('rules')]
        else:
            raise ValueError('Required property \'rules\' not present in NetworkACLRuleCollection JSON')
        if 'total_count' in _dict:
            args['total_count'] = _dict.get('total_count')
        else:
            raise ValueError('Required property \'total_count\' not present in NetworkACLRuleCollection JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a NetworkACLRuleCollection object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'first') and self.first is not None:
            if isinstance(self.first, dict):
                _dict['first'] = self.first
            else:
                _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:
            if isinstance(self.next, dict):
                _dict['next'] = self.next
            else:
                _dict['next'] = self.next.to_dict()
        if hasattr(self, 'rules') and self.rules is not None:
            rules_list = []
            for v in self.rules:
                if isinstance(v, dict):
                    rules_list.append(v)
                else:
                    rules_list.append(v.to_dict())
            _dict['rules'] = rules_list
        if hasattr(self, 'total_count') and self.total_count is not None:
            _dict['total_count'] = self.total_count
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this 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: The action to perform for a packet matching the rule.
    :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 IP address or CIDR block to match. The
          CIDR block `0.0.0.0/0` matches all destination addresses.
    :attr str direction: The direction of traffic to match.
    :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 name for this network ACL rule. The name is unique across
          all rules for the network ACL.
    :attr str protocol: The protocol to enforce.
    :attr str source: The source IP address or CIDR block to match. The CIDR block
          `0.0.0.0/0` matches all source 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: The action to perform for a packet matching the rule.
        :param datetime created_at: The date and time that the rule was created.
        :param str destination: The destination IP address or CIDR block to match.
               The CIDR block `0.0.0.0/0` matches all destination addresses.
        :param str direction: The direction of traffic to match.
        :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 name for this network ACL rule. The name is unique
               across all rules for the network ACL.
        :param str protocol: The protocol to enforce.
        :param str source: The source IP address or CIDR block to match. The CIDR
               block `0.0.0.0/0` matches all source 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):
        """
        The action to perform for a packet matching the rule.
        """

        ALLOW = 'allow'
        DENY = 'deny'


    class DirectionEnum(str, Enum):
        """
        The direction of traffic to match.
        """

        INBOUND = 'inbound'
        OUTBOUND = 'outbound'


    class IpVersionEnum(str, Enum):
        """
        The IP version for this rule.
        """

        IPV4 = 'ipv4'


    class ProtocolEnum(str, Enum):
        """
        The protocol to enforce.
        """

        ALL = 'all'
        ICMP = 'icmp'
        TCP = 'tcp'
        UDP = 'udp'



class NetworkACLRulePatch:
    """
    NetworkACLRulePatch.

    :attr str action: (optional) The action to perform for a packet matching the
          rule.
    :attr NetworkACLRuleBeforePatch before: (optional) The rule to move this rule
          immediately before.
          Specify `null` to move this rule after all existing rules.
    :attr int code: (optional) The ICMP traffic code to match. If set, `type` must
          also be set.
          Specify `null` to remove an existing ICMP traffic code.
    :attr str destination: (optional) The destination IP address or CIDR block to
          match. The CIDR block `0.0.0.0/0` matches all destination addresses.
    :attr int destination_port_max: (optional) The inclusive upper bound of TCP/UDP
          destination port range.
    :attr int destination_port_min: (optional) The inclusive lower bound of TCP/UDP
          destination port range.
    :attr str direction: (optional) The direction of traffic to match.
    :attr str name: (optional) The name for this network ACL rule. The name must not
          be used by another rule for the network ACL.
    :attr str protocol: (optional) The protocol to enforce.
    :attr str source: (optional) The source IP address or CIDR block to match. The
          CIDR block `0.0.0.0/0` matches all source addresses.
    :attr int source_port_max: (optional) The inclusive upper bound of TCP/UDP
          source port range.
    :attr int source_port_min: (optional) The inclusive lower bound of TCP/UDP
          source port range.
    :attr int type: (optional) The ICMP traffic type to match.
          Specify `null` to remove an existing ICMP traffic type value.
    """

    def __init__(
        self,
        *,
        action: str = None,
        before: 'NetworkACLRuleBeforePatch' = None,
        code: int = None,
        destination: str = None,
        destination_port_max: int = None,
        destination_port_min: int = None,
        direction: str = None,
        name: str = None,
        protocol: str = None,
        source: str = None,
        source_port_max: int = None,
        source_port_min: int = None,
        type: int = None,
    ) -> None:
        """
        Initialize a NetworkACLRulePatch object.

        :param str action: (optional) The action to perform for a packet matching
               the rule.
        :param NetworkACLRuleBeforePatch before: (optional) The rule to move this
               rule immediately before.
               Specify `null` to move this rule after all existing rules.
        :param int code: (optional) The ICMP traffic code to match. If set, `type`
               must also be set.
               Specify `null` to remove an existing ICMP traffic code.
        :param str destination: (optional) The destination IP address or CIDR block
               to match. The CIDR block `0.0.0.0/0` matches all destination addresses.
        :param int destination_port_max: (optional) The inclusive upper bound of
               TCP/UDP destination port range.
        :param int destination_port_min: (optional) The inclusive lower bound of
               TCP/UDP destination port range.
        :param str direction: (optional) The direction of traffic to match.
        :param str name: (optional) The name for this network ACL rule. The name
               must not be used by another rule for the network ACL.
        :param str protocol: (optional) The protocol to enforce.
        :param str source: (optional) The source IP address or CIDR block to match.
               The CIDR block `0.0.0.0/0` matches all source addresses.
        :param int source_port_max: (optional) The inclusive upper bound of TCP/UDP
               source port range.
        :param int source_port_min: (optional) The inclusive lower bound of TCP/UDP
               source port range.
        :param int type: (optional) The ICMP traffic type to match.
               Specify `null` to remove an existing ICMP traffic type value.
        """
        self.action = action
        self.before = before
        self.code = code
        self.destination = destination
        self.destination_port_max = destination_port_max
        self.destination_port_min = destination_port_min
        self.direction = direction
        self.name = name
        self.protocol = protocol
        self.source = source
        self.source_port_max = source_port_max
        self.source_port_min = source_port_min
        self.type = type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'NetworkACLRulePatch':
        """Initialize a NetworkACLRulePatch object from a json dictionary."""
        args = {}
        if 'action' in _dict:
            args['action'] = _dict.get('action')
        if 'before' in _dict:
            args['before'] = _dict.get('before')
        if 'code' in _dict:
            args['code'] = _dict.get('code')
        if 'destination' in _dict:
            args['destination'] = _dict.get('destination')
        if 'destination_port_max' in _dict:
            args['destination_port_max'] = _dict.get('destination_port_max')
        if 'destination_port_min' in _dict:
            args['destination_port_min'] = _dict.get('destination_port_min')
        if 'direction' in _dict:
            args['direction'] = _dict.get('direction')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        if 'protocol' in _dict:
            args['protocol'] = _dict.get('protocol')
        if 'source' in _dict:
            args['source'] = _dict.get('source')
        if 'source_port_max' in _dict:
            args['source_port_max'] = _dict.get('source_port_max')
        if 'source_port_min' in _dict:
            args['source_port_min'] = _dict.get('source_port_min')
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a NetworkACLRulePatch object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'action') and self.action is not None:
            _dict['action'] = self.action
        if hasattr(self, 'before') and self.before is not None:
            if isinstance(self.before, dict):
                _dict['before'] = self.before
            else:
                _dict['before'] = self.before.to_dict()
        if hasattr(self, 'code') and self.code is not None:
            _dict['code'] = self.code
        if hasattr(self, 'destination') and self.destination is not None:
            _dict['destination'] = self.destination
        if hasattr(self, 'destination_port_max') and self.destination_port_max is not None:
            _dict['destination_port_max'] = self.destination_port_max
        if hasattr(self, 'destination_port_min') and self.destination_port_min is not None:
            _dict['destination_port_min'] = self.destination_port_min
        if hasattr(self, 'direction') and self.direction is not None:
            _dict['direction'] = self.direction
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'protocol') and self.protocol is not None:
            _dict['protocol'] = self.protocol
        if hasattr(self, 'source') and self.source is not None:
            _dict['source'] = self.source
        if hasattr(self, 'source_port_max') and self.source_port_max is not None:
            _dict['source_port_max'] = self.source_port_max
        if hasattr(self, 'source_port_min') and self.source_port_min is not None:
            _dict['source_port_min'] = self.source_port_min
        if hasattr(self, 'type') and self.type is not None:
            _dict['type'] = self.type
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this NetworkACLRulePatch object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'NetworkACLRulePatch') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'NetworkACLRulePatch') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ActionEnum(str, Enum):
        """
        The action to perform for a packet matching the rule.
        """

        ALLOW = 'allow'
        DENY = 'deny'


    class DirectionEnum(str, Enum):
        """
        The direction of traffic to match.
        """

        INBOUND = 'inbound'
        OUTBOUND = 'outbound'


    class ProtocolEnum(str, Enum):
        """
        The protocol to enforce.
        """

        ALL = 'all'
        ICMP = 'icmp'
        TCP = 'tcp'
        UDP = 'udp'



class NetworkACLRulePrototype:
    """
    NetworkACLRulePrototype.

    :attr str action: The action to perform for a packet matching the rule.
    :attr NetworkACLRuleBeforePrototype before: (optional) The rule to insert this
          rule immediately before.
          If unspecified, this rule will be inserted after all existing rules.
    :attr str destination: The destination IP address or CIDR block to match. The
          CIDR block `0.0.0.0/0` matches all destination addresses.
    :attr str direction: The direction of traffic to match.
    :attr str ip_version: (optional) The IP version for this rule.
    :attr str name: (optional) The name for this network ACL rule. The name must not
          be used by another rule for the network ACL. 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 to match. The CIDR block
          `0.0.0.0/0` matches all source addresses.
    """

    def __init__(
        self,
        action: str,
        destination: str,
        direction: str,
        protocol: str,
        source: str,
        *,
        before: 'NetworkACLRuleBeforePrototype' = None,
        ip_version: str = None,
        name: str = None,
    ) -> None:
        """
        Initialize a NetworkACLRulePrototype object.

        :param str action: The action to perform for a packet matching the rule.
        :param str destination: The destination IP address or CIDR block to match.
               The CIDR block `0.0.0.0/0` matches all destination addresses.
        :param str direction: The direction of traffic to match.
        :param str protocol: The protocol to enforce.
        :param str source: The source IP address or CIDR block to match. The CIDR
               block `0.0.0.0/0` matches all source addresses.
        :param NetworkACLRuleBeforePrototype before: (optional) The rule to insert
               this rule immediately before.
               If unspecified, this rule will be inserted after all existing rules.
        :param str ip_version: (optional) The IP version for this rule.
        :param str name: (optional) The name for this network ACL rule. The name
               must not be used by another rule for the 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(['NetworkACLRulePrototypeNetworkACLRuleProtocolTCPUDPPrototype', 'NetworkACLRulePrototypeNetworkACLRuleProtocolICMPPrototype', 'NetworkACLRulePrototypeNetworkACLRuleProtocolAllPrototype'])
        )
        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(['NetworkACLRulePrototypeNetworkACLRuleProtocolTCPUDPPrototype', 'NetworkACLRulePrototypeNetworkACLRuleProtocolICMPPrototype', 'NetworkACLRulePrototypeNetworkACLRuleProtocolAllPrototype'])
        )
        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'] = 'NetworkACLRulePrototypeNetworkACLRuleProtocolAllPrototype'
        mapping['icmp'] = 'NetworkACLRulePrototypeNetworkACLRuleProtocolICMPPrototype'
        mapping['tcp'] = 'NetworkACLRulePrototypeNetworkACLRuleProtocolTCPUDPPrototype'
        mapping['udp'] = 'NetworkACLRulePrototypeNetworkACLRuleProtocolTCPUDPPrototype'
        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):
        """
        The action to perform for a packet matching the rule.
        """

        ALLOW = 'allow'
        DENY = 'deny'


    class DirectionEnum(str, Enum):
        """
        The direction of traffic to match.
        """

        INBOUND = 'inbound'
        OUTBOUND = 'outbound'


    class IpVersionEnum(str, Enum):
        """
        The IP version for this rule.
        """

        IPV4 = 'ipv4'


    class ProtocolEnum(str, Enum):
        """
        The protocol to enforce.
        """

        ALL = 'all'
        ICMP = 'icmp'
        TCP = 'tcp'
        UDP = 'udp'



class NetworkACLRulePrototypeNetworkACLContext:
    """
    NetworkACLRulePrototypeNetworkACLContext.

    :attr str action: The action to perform for a packet matching the rule.
    :attr str destination: The destination IP address or CIDR block to match. The
          CIDR block `0.0.0.0/0` matches all destination addresses.
    :attr str direction: The direction of traffic to match.
    :attr str ip_version: (optional) The IP version for this rule.
    :attr str name: (optional) The name for this network ACL rule. The name must not
          be used by another rule for the network ACL. 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 to match. The CIDR block
          `0.0.0.0/0` matches all source addresses.
    """

    def __init__(
        self,
        action: str,
        destination: str,
        direction: str,
        protocol: str,
        source: str,
        *,
        ip_version: str = None,
        name: str = None,
    ) -> None:
        """
        Initialize a NetworkACLRulePrototypeNetworkACLContext object.

        :param str action: The action to perform for a packet matching the rule.
        :param str destination: The destination IP address or CIDR block to match.
               The CIDR block `0.0.0.0/0` matches all destination addresses.
        :param str direction: The direction of traffic to match.
        :param str protocol: The protocol to enforce.
        :param str source: The source IP address or CIDR block to match. The CIDR
               block `0.0.0.0/0` matches all source addresses.
        :param str ip_version: (optional) The IP version for this rule.
        :param str name: (optional) The name for this network ACL rule. The name
               must not be used by another rule for the 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(['NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolTCPUDPPrototype', 'NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolICMPPrototype', 'NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolAllPrototype'])
        )
        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(['NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolTCPUDPPrototype', 'NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolICMPPrototype', 'NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolAllPrototype'])
        )
        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'] = 'NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolAllPrototype'
        mapping['icmp'] = 'NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolICMPPrototype'
        mapping['tcp'] = 'NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolTCPUDPPrototype'
        mapping['udp'] = 'NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolTCPUDPPrototype'
        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):
        """
        The action to perform for a packet matching the rule.
        """

        ALLOW = 'allow'
        DENY = 'deny'


    class DirectionEnum(str, Enum):
        """
        The direction of traffic to match.
        """

        INBOUND = 'inbound'
        OUTBOUND = 'outbound'


    class IpVersionEnum(str, Enum):
        """
        The IP version for this rule.
        """

        IPV4 = 'ipv4'


    class ProtocolEnum(str, Enum):
        """
        The protocol to enforce.
        """

        ALL = 'all'
        ICMP = 'icmp'
        TCP = 'tcp'
        UDP = 'udp'



class NetworkACLRuleReference:
    """
    NetworkACLRuleReference.

    :attr NetworkACLRuleReferenceDeleted deleted: (optional) If present, this
          property indicates the referenced resource has been deleted, and provides
          some supplementary information.
    :attr str href: The URL for this network ACL rule.
    :attr str id: The unique identifier for this network ACL rule.
    :attr str name: The name for this network ACL rule. The name is unique across
          all rules for the network ACL.
    """

    def __init__(
        self,
        href: str,
        id: str,
        name: str,
        *,
        deleted: 'NetworkACLRuleReferenceDeleted' = None,
    ) -> None:
        """
        Initialize a NetworkACLRuleReference object.

        :param str href: The URL for this network ACL rule.
        :param str id: The unique identifier for this network ACL rule.
        :param str name: The name for this network ACL rule. The name is unique
               across all rules for the network ACL.
        :param NetworkACLRuleReferenceDeleted deleted: (optional) If present, this
               property indicates the referenced resource has been deleted, and provides
               some supplementary information.
        """
        self.deleted = deleted
        self.href = href
        self.id = id
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'NetworkACLRuleReference':
        """Initialize a NetworkACLRuleReference object from a json dictionary."""
        args = {}
        if 'deleted' in _dict:
            args['deleted'] = NetworkACLRuleReferenceDeleted.from_dict(_dict.get('deleted'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in NetworkACLRuleReference JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in NetworkACLRuleReference JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in NetworkACLRuleReference JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a NetworkACLRuleReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'deleted') and self.deleted is not None:
            if isinstance(self.deleted, dict):
                _dict['deleted'] = self.deleted
            else:
                _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this NetworkACLRuleReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'NetworkACLRuleReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'NetworkACLRuleReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class NetworkACLRuleReferenceDeleted:
    """
    If present, this property indicates the referenced resource has been deleted, and
    provides some supplementary information.

    :attr str more_info: Link to documentation about deleted resources.
    """

    def __init__(
        self,
        more_info: str,
    ) -> None:
        """
        Initialize a NetworkACLRuleReferenceDeleted object.

        :param str more_info: Link to documentation about deleted resources.
        """
        self.more_info = more_info

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'NetworkACLRuleReferenceDeleted':
        """Initialize a NetworkACLRuleReferenceDeleted object from a json dictionary."""
        args = {}
        if 'more_info' in _dict:
            args['more_info'] = _dict.get('more_info')
        else:
            raise ValueError('Required property \'more_info\' not present in NetworkACLRuleReferenceDeleted JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a NetworkACLRuleReferenceDeleted object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'more_info') and self.more_info is not None:
            _dict['more_info'] = self.more_info
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this NetworkACLRuleReferenceDeleted object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'NetworkACLRuleReferenceDeleted') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'NetworkACLRuleReferenceDeleted') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class NetworkInterface:
    """
    NetworkInterface.

    :attr bool allow_ip_spoofing: Indicates whether source IP spoofing is allowed on
          this instance network interface.
    :attr datetime created_at: The date and time that the instance network interface
          was created.
    :attr List[FloatingIPReference] floating_ips: The floating IPs associated with
          this instance network interface.
    :attr str href: The URL for this instance network interface.
    :attr str id: The unique identifier for this instance network interface.
    :attr str name: The name for this instance network interface.
    :attr int port_speed: The instance network interface port speed in Mbps.
    :attr ReservedIPReference primary_ip:
    :attr str resource_type: The resource type.
    :attr List[SecurityGroupReference] security_groups: The security groups
          targeting this instance network interface.
    :attr str status: The status of the instance network interface.
    :attr SubnetReference subnet: The associated subnet.
    :attr str type: The instance network interface type.
    """

    def __init__(
        self,
        allow_ip_spoofing: bool,
        created_at: datetime,
        floating_ips: List['FloatingIPReference'],
        href: str,
        id: str,
        name: str,
        port_speed: int,
        primary_ip: 'ReservedIPReference',
        resource_type: str,
        security_groups: List['SecurityGroupReference'],
        status: str,
        subnet: 'SubnetReference',
        type: str,
    ) -> None:
        """
        Initialize a NetworkInterface object.

        :param bool allow_ip_spoofing: Indicates whether source IP spoofing is
               allowed on this instance network interface.
        :param datetime created_at: The date and time that the instance network
               interface was created.
        :param List[FloatingIPReference] floating_ips: The floating IPs associated
               with this instance network interface.
        :param str href: The URL for this instance network interface.
        :param str id: The unique identifier for this instance network interface.
        :param str name: The name for this instance network interface.
        :param int port_speed: The instance network interface port speed in Mbps.
        :param ReservedIPReference primary_ip:
        :param str resource_type: The resource type.
        :param List[SecurityGroupReference] security_groups: The security groups
               targeting this instance network interface.
        :param str status: The status of the instance network interface.
        :param SubnetReference subnet: The associated subnet.
        :param str type: The instance network interface type.
        """
        self.allow_ip_spoofing = allow_ip_spoofing
        self.created_at = created_at
        self.floating_ips = floating_ips
        self.href = href
        self.id = id
        self.name = name
        self.port_speed = port_speed
        self.primary_ip = primary_ip
        self.resource_type = resource_type
        self.security_groups = security_groups
        self.status = status
        self.subnet = subnet
        self.type = type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'NetworkInterface':
        """Initialize a NetworkInterface object from a json dictionary."""
        args = {}
        if 'allow_ip_spoofing' in _dict:
            args['allow_ip_spoofing'] = _dict.get('allow_ip_spoofing')
        else:
            raise ValueError('Required property \'allow_ip_spoofing\' not present in NetworkInterface JSON')
        if 'created_at' in _dict:
            args['created_at'] = string_to_datetime(_dict.get('created_at'))
        else:
            raise ValueError('Required property \'created_at\' not present in NetworkInterface JSON')
        if 'floating_ips' in _dict:
            args['floating_ips'] = [FloatingIPReference.from_dict(v) for v in _dict.get('floating_ips')]
        else:
            raise ValueError('Required property \'floating_ips\' not present in NetworkInterface JSON')
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in NetworkInterface JSON')
        if '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_ip' in _dict:
            args['primary_ip'] = ReservedIPReference.from_dict(_dict.get('primary_ip'))
        else:
            raise ValueError('Required property \'primary_ip\' 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(v) for v in _dict.get('security_groups')]
        else:
            raise ValueError('Required property \'security_groups\' not present in NetworkInterface JSON')
        if 'status' in _dict:
            args['status'] = _dict.get('status')
        else:
            raise ValueError('Required property \'status\' not present in NetworkInterface JSON')
        if 'subnet' in _dict:
            args['subnet'] = SubnetReference.from_dict(_dict.get('subnet'))
        else:
            raise ValueError('Required property \'subnet\' not present in NetworkInterface JSON')
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in NetworkInterface JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a NetworkInterface object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'allow_ip_spoofing') and self.allow_ip_spoofing is not None:
            _dict['allow_ip_spoofing'] = self.allow_ip_spoofing
        if hasattr(self, 'created_at') and self.created_at is not None:
            _dict['created_at'] = datetime_to_string(self.created_at)
        if hasattr(self, 'floating_ips') and self.floating_ips is not None:
            floating_ips_list = []
            for v in self.floating_ips:
                if isinstance(v, dict):
                    floating_ips_list.append(v)
                else:
                    floating_ips_list.append(v.to_dict())
            _dict['floating_ips'] = floating_ips_list
        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_ip') and self.primary_ip is not None:
            if isinstance(self.primary_ip, dict):
                _dict['primary_ip'] = self.primary_ip
            else:
                _dict['primary_ip'] = self.primary_ip.to_dict()
        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:
            security_groups_list = []
            for v in self.security_groups:
                if isinstance(v, dict):
                    security_groups_list.append(v)
                else:
                    security_groups_list.append(v.to_dict())
            _dict['security_groups'] = security_groups_list
        if hasattr(self, 'status') and self.status is not None:
            _dict['status'] = self.status
        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, '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 instance network interface.
        """

        AVAILABLE = 'available'
        DELETING = 'deleting'
        FAILED = 'failed'
        PENDING = 'pending'


    class TypeEnum(str, Enum):
        """
        The instance network interface type.
        """

        PRIMARY = 'primary'
        SECONDARY = 'secondary'



class NetworkInterfaceBareMetalServerContextReference:
    """
    NetworkInterfaceBareMetalServerContextReference.

    :attr NetworkInterfaceBareMetalServerContextReferenceDeleted deleted: (optional)
          If present, this property indicates the referenced resource has been deleted,
          and provides
          some supplementary information.
    :attr str href: The URL for this bare metal server network interface.
    :attr str id: The unique identifier for this bare metal server network
          interface.
    :attr str name: The name for this bare metal server network interface.
    :attr ReservedIPReference primary_ip:
    :attr str resource_type: The resource type.
    :attr SubnetReference subnet: The associated subnet.
    """

    def __init__(
        self,
        href: str,
        id: str,
        name: str,
        primary_ip: 'ReservedIPReference',
        resource_type: str,
        subnet: 'SubnetReference',
        *,
        deleted: 'NetworkInterfaceBareMetalServerContextReferenceDeleted' = None,
    ) -> None:
        """
        Initialize a NetworkInterfaceBareMetalServerContextReference object.

        :param str href: The URL for this bare metal server network interface.
        :param str id: The unique identifier for this bare metal server network
               interface.
        :param str name: The name for this bare metal server network interface.
        :param ReservedIPReference primary_ip:
        :param str resource_type: The resource type.
        :param SubnetReference subnet: The associated subnet.
        :param NetworkInterfaceBareMetalServerContextReferenceDeleted deleted:
               (optional) If present, this property indicates the referenced resource has
               been deleted, and provides
               some supplementary information.
        """
        self.deleted = deleted
        self.href = href
        self.id = id
        self.name = name
        self.primary_ip = primary_ip
        self.resource_type = resource_type
        self.subnet = subnet

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'NetworkInterfaceBareMetalServerContextReference':
        """Initialize a NetworkInterfaceBareMetalServerContextReference object from a json dictionary."""
        args = {}
        if 'deleted' in _dict:
            args['deleted'] = NetworkInterfaceBareMetalServerContextReferenceDeleted.from_dict(_dict.get('deleted'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in NetworkInterfaceBareMetalServerContextReference JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in NetworkInterfaceBareMetalServerContextReference JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in NetworkInterfaceBareMetalServerContextReference JSON')
        if 'primary_ip' in _dict:
            args['primary_ip'] = ReservedIPReference.from_dict(_dict.get('primary_ip'))
        else:
            raise ValueError('Required property \'primary_ip\' not present in NetworkInterfaceBareMetalServerContextReference JSON')
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError('Required property \'resource_type\' not present in NetworkInterfaceBareMetalServerContextReference JSON')
        if 'subnet' in _dict:
            args['subnet'] = SubnetReference.from_dict(_dict.get('subnet'))
        else:
            raise ValueError('Required property \'subnet\' not present in NetworkInterfaceBareMetalServerContextReference JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a NetworkInterfaceBareMetalServerContextReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'deleted') and self.deleted is not None:
            if isinstance(self.deleted, dict):
                _dict['deleted'] = self.deleted
            else:
                _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'primary_ip') and self.primary_ip is not None:
            if isinstance(self.primary_ip, dict):
                _dict['primary_ip'] = self.primary_ip
            else:
                _dict['primary_ip'] = self.primary_ip.to_dict()
        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:
            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 NetworkInterfaceBareMetalServerContextReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'NetworkInterfaceBareMetalServerContextReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'NetworkInterfaceBareMetalServerContextReference') -> 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 NetworkInterfaceBareMetalServerContextReferenceDeleted:
    """
    If present, this property indicates the referenced resource has been deleted, and
    provides some supplementary information.

    :attr str more_info: Link to documentation about deleted resources.
    """

    def __init__(
        self,
        more_info: str,
    ) -> None:
        """
        Initialize a NetworkInterfaceBareMetalServerContextReferenceDeleted object.

        :param str more_info: Link to documentation about deleted resources.
        """
        self.more_info = more_info

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'NetworkInterfaceBareMetalServerContextReferenceDeleted':
        """Initialize a NetworkInterfaceBareMetalServerContextReferenceDeleted object from a json dictionary."""
        args = {}
        if 'more_info' in _dict:
            args['more_info'] = _dict.get('more_info')
        else:
            raise ValueError('Required property \'more_info\' not present in NetworkInterfaceBareMetalServerContextReferenceDeleted JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a NetworkInterfaceBareMetalServerContextReferenceDeleted object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'more_info') and self.more_info is not None:
            _dict['more_info'] = self.more_info
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this NetworkInterfaceBareMetalServerContextReferenceDeleted object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'NetworkInterfaceBareMetalServerContextReferenceDeleted') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'NetworkInterfaceBareMetalServerContextReferenceDeleted') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class NetworkInterfaceIPPrototype:
    """
    NetworkInterfaceIPPrototype.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a NetworkInterfaceIPPrototype object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['NetworkInterfaceIPPrototypeReservedIPIdentity', 'NetworkInterfaceIPPrototypeReservedIPPrototypeNetworkInterfaceContext'])
        )
        raise Exception(msg)


class NetworkInterfaceInstanceContextReference:
    """
    NetworkInterfaceInstanceContextReference.

    :attr NetworkInterfaceInstanceContextReferenceDeleted deleted: (optional) If
          present, this property indicates the referenced resource has been deleted, and
          provides
          some supplementary information.
    :attr str href: The URL for this instance network interface.
    :attr str id: The unique identifier for this instance network interface.
    :attr str name: The name for this instance network interface.
    :attr ReservedIPReference primary_ip:
    :attr str resource_type: The resource type.
    :attr SubnetReference subnet: The associated subnet.
    """

    def __init__(
        self,
        href: str,
        id: str,
        name: str,
        primary_ip: 'ReservedIPReference',
        resource_type: str,
        subnet: 'SubnetReference',
        *,
        deleted: 'NetworkInterfaceInstanceContextReferenceDeleted' = None,
    ) -> None:
        """
        Initialize a NetworkInterfaceInstanceContextReference object.

        :param str href: The URL for this instance network interface.
        :param str id: The unique identifier for this instance network interface.
        :param str name: The name for this instance network interface.
        :param ReservedIPReference primary_ip:
        :param str resource_type: The resource type.
        :param SubnetReference subnet: The associated subnet.
        :param NetworkInterfaceInstanceContextReferenceDeleted deleted: (optional)
               If present, this property indicates the referenced resource has been
               deleted, and provides
               some supplementary information.
        """
        self.deleted = deleted
        self.href = href
        self.id = id
        self.name = name
        self.primary_ip = primary_ip
        self.resource_type = resource_type
        self.subnet = subnet

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'NetworkInterfaceInstanceContextReference':
        """Initialize a NetworkInterfaceInstanceContextReference object from a json dictionary."""
        args = {}
        if 'deleted' in _dict:
            args['deleted'] = NetworkInterfaceInstanceContextReferenceDeleted.from_dict(_dict.get('deleted'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in NetworkInterfaceInstanceContextReference JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in NetworkInterfaceInstanceContextReference JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in NetworkInterfaceInstanceContextReference JSON')
        if 'primary_ip' in _dict:
            args['primary_ip'] = ReservedIPReference.from_dict(_dict.get('primary_ip'))
        else:
            raise ValueError('Required property \'primary_ip\' not present in NetworkInterfaceInstanceContextReference JSON')
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError('Required property \'resource_type\' not present in NetworkInterfaceInstanceContextReference JSON')
        if 'subnet' in _dict:
            args['subnet'] = SubnetReference.from_dict(_dict.get('subnet'))
        else:
            raise ValueError('Required property \'subnet\' not present in NetworkInterfaceInstanceContextReference JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a NetworkInterfaceInstanceContextReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'deleted') and self.deleted is not None:
            if isinstance(self.deleted, dict):
                _dict['deleted'] = self.deleted
            else:
                _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'primary_ip') and self.primary_ip is not None:
            if isinstance(self.primary_ip, dict):
                _dict['primary_ip'] = self.primary_ip
            else:
                _dict['primary_ip'] = self.primary_ip.to_dict()
        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:
            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 NetworkInterfaceInstanceContextReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'NetworkInterfaceInstanceContextReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'NetworkInterfaceInstanceContextReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        NETWORK_INTERFACE = 'network_interface'



class NetworkInterfaceInstanceContextReferenceDeleted:
    """
    If present, this property indicates the referenced resource has been deleted, and
    provides some supplementary information.

    :attr str more_info: Link to documentation about deleted resources.
    """

    def __init__(
        self,
        more_info: str,
    ) -> None:
        """
        Initialize a NetworkInterfaceInstanceContextReferenceDeleted object.

        :param str more_info: Link to documentation about deleted resources.
        """
        self.more_info = more_info

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'NetworkInterfaceInstanceContextReferenceDeleted':
        """Initialize a NetworkInterfaceInstanceContextReferenceDeleted object from a json dictionary."""
        args = {}
        if 'more_info' in _dict:
            args['more_info'] = _dict.get('more_info')
        else:
            raise ValueError('Required property \'more_info\' not present in NetworkInterfaceInstanceContextReferenceDeleted JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a NetworkInterfaceInstanceContextReferenceDeleted object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'more_info') and self.more_info is not None:
            _dict['more_info'] = self.more_info
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this NetworkInterfaceInstanceContextReferenceDeleted object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'NetworkInterfaceInstanceContextReferenceDeleted') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'NetworkInterfaceInstanceContextReferenceDeleted') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class NetworkInterfacePatch:
    """
    NetworkInterfacePatch.

    :attr bool allow_ip_spoofing: (optional) Indicates whether source IP spoofing is
          allowed on this instance network interface.
    :attr str name: (optional) The name for the instance network interface. The name
          must not be used by another network interface on the virtual server instance.
    """

    def __init__(
        self,
        *,
        allow_ip_spoofing: bool = None,
        name: str = None,
    ) -> None:
        """
        Initialize a NetworkInterfacePatch object.

        :param bool allow_ip_spoofing: (optional) Indicates whether source IP
               spoofing is allowed on this instance network interface.
        :param str name: (optional) The name for the instance network interface.
               The name must not be used by another network interface on the virtual
               server instance.
        """
        self.allow_ip_spoofing = allow_ip_spoofing
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'NetworkInterfacePatch':
        """Initialize a NetworkInterfacePatch object from a json dictionary."""
        args = {}
        if 'allow_ip_spoofing' in _dict:
            args['allow_ip_spoofing'] = _dict.get('allow_ip_spoofing')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a NetworkInterfacePatch object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'allow_ip_spoofing') and self.allow_ip_spoofing is not None:
            _dict['allow_ip_spoofing'] = self.allow_ip_spoofing
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this NetworkInterfacePatch object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'NetworkInterfacePatch') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'NetworkInterfacePatch') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class NetworkInterfacePrototype:
    """
    NetworkInterfacePrototype.

    :attr bool allow_ip_spoofing: (optional) Indicates whether source IP spoofing is
          allowed on this instance network interface.
    :attr str name: (optional) The name for the instance network interface. The name
          must not be used by another network interface on the virtual server instance. If
          unspecified, the name will be a hyphenated list of randomly-selected words.
    :attr NetworkInterfaceIPPrototype primary_ip: (optional) The primary IP address
          to bind to the instance network interface. This can be
          specified using an existing reserved IP, or a prototype object for a new
          reserved IP.
          If an existing reserved IP or a prototype object with an address is specified,
          it must
          be available on the instance network interface's subnet. Otherwise, an
          available address on the subnet will be automatically selected and reserved.
    :attr List[SecurityGroupIdentity] security_groups: (optional) The security
          groups to use for this instance network interface. If unspecified, the VPC's
          default security group is used.
    :attr SubnetIdentity subnet: The associated subnet.
    """

    def __init__(
        self,
        subnet: 'SubnetIdentity',
        *,
        allow_ip_spoofing: bool = None,
        name: str = None,
        primary_ip: 'NetworkInterfaceIPPrototype' = None,
        security_groups: List['SecurityGroupIdentity'] = None,
    ) -> None:
        """
        Initialize a NetworkInterfacePrototype object.

        :param SubnetIdentity subnet: The associated subnet.
        :param bool allow_ip_spoofing: (optional) Indicates whether source IP
               spoofing is allowed on this instance network interface.
        :param str name: (optional) The name for the instance network interface.
               The name must not be used by another network interface on the virtual
               server instance. If unspecified, the name will be a hyphenated list of
               randomly-selected words.
        :param NetworkInterfaceIPPrototype primary_ip: (optional) The primary IP
               address to bind to the instance network interface. This can be
               specified using an existing reserved IP, or a prototype object for a new
               reserved IP.
               If an existing reserved IP or a prototype object with an address is
               specified, it must
               be available on the instance network interface's subnet. Otherwise, an
               available address on the subnet will be automatically selected and
               reserved.
        :param List[SecurityGroupIdentity] security_groups: (optional) The security
               groups to use for this instance network interface. If unspecified, the
               VPC's default security group is used.
        """
        self.allow_ip_spoofing = allow_ip_spoofing
        self.name = name
        self.primary_ip = primary_ip
        self.security_groups = security_groups
        self.subnet = subnet

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'NetworkInterfacePrototype':
        """Initialize a NetworkInterfacePrototype object from a json dictionary."""
        args = {}
        if 'allow_ip_spoofing' in _dict:
            args['allow_ip_spoofing'] = _dict.get('allow_ip_spoofing')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        if 'primary_ip' in _dict:
            args['primary_ip'] = _dict.get('primary_ip')
        if 'security_groups' in _dict:
            args['security_groups'] = _dict.get('security_groups')
        if 'subnet' in _dict:
            args['subnet'] = _dict.get('subnet')
        else:
            raise ValueError('Required property \'subnet\' not present in NetworkInterfacePrototype JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a NetworkInterfacePrototype object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'allow_ip_spoofing') and self.allow_ip_spoofing is not None:
            _dict['allow_ip_spoofing'] = self.allow_ip_spoofing
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'primary_ip') and self.primary_ip is not None:
            if isinstance(self.primary_ip, dict):
                _dict['primary_ip'] = self.primary_ip
            else:
                _dict['primary_ip'] = self.primary_ip.to_dict()
        if hasattr(self, 'security_groups') and self.security_groups is not None:
            security_groups_list = []
            for v in self.security_groups:
                if isinstance(v, dict):
                    security_groups_list.append(v)
                else:
                    security_groups_list.append(v.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 NetworkInterfaceReferenceDeleted:
    """
    If present, this property indicates the referenced resource has been deleted, and
    provides some supplementary information.

    :attr str more_info: Link to documentation about deleted resources.
    """

    def __init__(
        self,
        more_info: str,
    ) -> None:
        """
        Initialize a NetworkInterfaceReferenceDeleted object.

        :param str more_info: Link to documentation about deleted resources.
        """
        self.more_info = more_info

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'NetworkInterfaceReferenceDeleted':
        """Initialize a NetworkInterfaceReferenceDeleted object from a json dictionary."""
        args = {}
        if 'more_info' in _dict:
            args['more_info'] = _dict.get('more_info')
        else:
            raise ValueError('Required property \'more_info\' not present in NetworkInterfaceReferenceDeleted JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a NetworkInterfaceReferenceDeleted object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'more_info') and self.more_info is not None:
            _dict['more_info'] = self.more_info
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this NetworkInterfaceReferenceDeleted object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'NetworkInterfaceReferenceDeleted') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'NetworkInterfaceReferenceDeleted') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class NetworkInterfaceReferenceTargetContextDeleted:
    """
    If present, this property indicates the referenced resource has been deleted, and
    provides some supplementary information.

    :attr str more_info: Link to documentation about deleted resources.
    """

    def __init__(
        self,
        more_info: str,
    ) -> None:
        """
        Initialize a NetworkInterfaceReferenceTargetContextDeleted object.

        :param str more_info: Link to documentation about deleted resources.
        """
        self.more_info = more_info

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'NetworkInterfaceReferenceTargetContextDeleted':
        """Initialize a NetworkInterfaceReferenceTargetContextDeleted object from a json dictionary."""
        args = {}
        if 'more_info' in _dict:
            args['more_info'] = _dict.get('more_info')
        else:
            raise ValueError('Required property \'more_info\' not present in NetworkInterfaceReferenceTargetContextDeleted JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a NetworkInterfaceReferenceTargetContextDeleted object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'more_info') and self.more_info is not None:
            _dict['more_info'] = self.more_info
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this NetworkInterfaceReferenceTargetContextDeleted object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'NetworkInterfaceReferenceTargetContextDeleted') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'NetworkInterfaceReferenceTargetContextDeleted') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class NetworkInterfaceUnpaginatedCollection:
    """
    NetworkInterfaceUnpaginatedCollection.

    :attr List[NetworkInterface] network_interfaces: Collection of instance network
          interfaces.
    """

    def __init__(
        self,
        network_interfaces: List['NetworkInterface'],
    ) -> None:
        """
        Initialize a NetworkInterfaceUnpaginatedCollection object.

        :param List[NetworkInterface] network_interfaces: Collection of instance
               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(v) for v 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:
            network_interfaces_list = []
            for v in self.network_interfaces:
                if isinstance(v, dict):
                    network_interfaces_list.append(v)
                else:
                    network_interfaces_list.append(v.to_dict())
            _dict['network_interfaces'] = network_interfaces_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 NetworkInterfaceUnpaginatedCollection object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'NetworkInterfaceUnpaginatedCollection') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'NetworkInterfaceUnpaginatedCollection') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class OperatingSystem:
    """
    OperatingSystem.

    :attr str architecture: The operating system architecture.
    :attr bool dedicated_host_only: Images with this operating system can only be
          used on dedicated hosts or dedicated host groups.
    :attr str display_name: A unique, display-friendly name for the operating
          system.
    :attr str family: The software family for this operating system.
    :attr str href: The URL for this operating system.
    :attr str name: The globally unique name for this operating system.
    :attr str vendor: The vendor of the operating system.
    :attr str version: The major release version of this operating system.
    """

    def __init__(
        self,
        architecture: str,
        dedicated_host_only: bool,
        display_name: str,
        family: str,
        href: str,
        name: str,
        vendor: str,
        version: str,
    ) -> None:
        """
        Initialize a OperatingSystem object.

        :param str architecture: The operating system architecture.
        :param bool dedicated_host_only: Images with this operating system can only
               be used on dedicated hosts or dedicated host groups.
        :param str display_name: A unique, display-friendly name for the operating
               system.
        :param str family: The software family for this operating system.
        :param str href: The URL for this operating system.
        :param str name: The globally unique name for this operating system.
        :param str vendor: The vendor of the operating system.
        :param str version: The major release version of this operating system.
        """
        self.architecture = architecture
        self.dedicated_host_only = dedicated_host_only
        self.display_name = display_name
        self.family = family
        self.href = href
        self.name = name
        self.vendor = vendor
        self.version = version

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'OperatingSystem':
        """Initialize a OperatingSystem object from a json dictionary."""
        args = {}
        if 'architecture' in _dict:
            args['architecture'] = _dict.get('architecture')
        else:
            raise ValueError('Required property \'architecture\' not present in OperatingSystem JSON')
        if 'dedicated_host_only' in _dict:
            args['dedicated_host_only'] = _dict.get('dedicated_host_only')
        else:
            raise ValueError('Required property \'dedicated_host_only\' not present in OperatingSystem JSON')
        if 'display_name' in _dict:
            args['display_name'] = _dict.get('display_name')
        else:
            raise ValueError('Required property \'display_name\' not present in OperatingSystem JSON')
        if 'family' in _dict:
            args['family'] = _dict.get('family')
        else:
            raise ValueError('Required property \'family\' not present in OperatingSystem JSON')
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in OperatingSystem JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in OperatingSystem JSON')
        if 'vendor' in _dict:
            args['vendor'] = _dict.get('vendor')
        else:
            raise ValueError('Required property \'vendor\' not present in OperatingSystem JSON')
        if 'version' in _dict:
            args['version'] = _dict.get('version')
        else:
            raise ValueError('Required property \'version\' not present in OperatingSystem JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a OperatingSystem object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'architecture') and self.architecture is not None:
            _dict['architecture'] = self.architecture
        if hasattr(self, 'dedicated_host_only') and self.dedicated_host_only is not None:
            _dict['dedicated_host_only'] = self.dedicated_host_only
        if hasattr(self, 'display_name') and self.display_name is not None:
            _dict['display_name'] = self.display_name
        if hasattr(self, 'family') and self.family is not None:
            _dict['family'] = self.family
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'vendor') and self.vendor is not None:
            _dict['vendor'] = self.vendor
        if hasattr(self, 'version') and self.version is not None:
            _dict['version'] = self.version
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this OperatingSystem object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'OperatingSystem') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'OperatingSystem') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class OperatingSystemCollection:
    """
    OperatingSystemCollection.

    :attr OperatingSystemCollectionFirst first: A link to the first page of
          resources.
    :attr int limit: The maximum number of resources that can be returned by the
          request.
    :attr OperatingSystemCollectionNext next: (optional) A link to the next page of
          resources. This property is present for all pages
          except the last page.
    :attr List[OperatingSystem] operating_systems: Collection of operating systems.
    :attr int total_count: The total number of resources across all pages.
    """

    def __init__(
        self,
        first: 'OperatingSystemCollectionFirst',
        limit: int,
        operating_systems: List['OperatingSystem'],
        total_count: int,
        *,
        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 int total_count: The total number of resources across all pages.
        :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
        self.total_count = total_count

    @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(v) for v in _dict.get('operating_systems')]
        else:
            raise ValueError('Required property \'operating_systems\' not present in OperatingSystemCollection JSON')
        if 'total_count' in _dict:
            args['total_count'] = _dict.get('total_count')
        else:
            raise ValueError('Required property \'total_count\' 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:
            if isinstance(self.first, dict):
                _dict['first'] = self.first
            else:
                _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:
            if isinstance(self.next, dict):
                _dict['next'] = self.next
            else:
                _dict['next'] = self.next.to_dict()
        if hasattr(self, 'operating_systems') and self.operating_systems is not None:
            operating_systems_list = []
            for v in self.operating_systems:
                if isinstance(v, dict):
                    operating_systems_list.append(v)
                else:
                    operating_systems_list.append(v.to_dict())
            _dict['operating_systems'] = operating_systems_list
        if hasattr(self, 'total_count') and self.total_count is not None:
            _dict['total_count'] = self.total_count
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this 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 PlacementGroup:
    """
    PlacementGroup.

    :attr datetime created_at: The date and time that the placement group was
          created.
    :attr str crn: The CRN for this placement group.
    :attr str href: The URL for this placement group.
    :attr str id: The unique identifier for this placement group.
    :attr str lifecycle_state: The lifecycle state of the placement group.
    :attr str name: The name for this placement group. The name is unique across all
          placement groups in the region.
    :attr ResourceGroupReference resource_group: The resource group for this
          placement group.
    :attr str resource_type: The resource type.
    :attr str strategy: The strategy for this placement group
          - `host_spread`: place on different compute hosts
          - `power_spread`: place on compute hosts that use different power sources
          The enumerated values for this property may expand in the future. When
          processing this property, check for and log unknown values. Optionally halt
          processing and surface the error, or bypass the placement group on which the
          unexpected strategy was encountered.
    """

    def __init__(
        self,
        created_at: datetime,
        crn: str,
        href: str,
        id: str,
        lifecycle_state: str,
        name: str,
        resource_group: 'ResourceGroupReference',
        resource_type: str,
        strategy: str,
    ) -> None:
        """
        Initialize a PlacementGroup object.

        :param datetime created_at: The date and time that the placement group was
               created.
        :param str crn: The CRN for this placement group.
        :param str href: The URL for this placement group.
        :param str id: The unique identifier for this placement group.
        :param str lifecycle_state: The lifecycle state of the placement group.
        :param str name: The name for this placement group. The name is unique
               across all placement groups in the region.
        :param ResourceGroupReference resource_group: The resource group for this
               placement group.
        :param str resource_type: The resource type.
        :param str strategy: The strategy for this placement group
               - `host_spread`: place on different compute hosts
               - `power_spread`: place on compute hosts that use different power sources
               The enumerated values for this property may expand in the future. When
               processing this property, check for and log unknown values. Optionally halt
               processing and surface the error, or bypass the placement group on which
               the unexpected strategy was encountered.
        """
        self.created_at = created_at
        self.crn = crn
        self.href = href
        self.id = id
        self.lifecycle_state = lifecycle_state
        self.name = name
        self.resource_group = resource_group
        self.resource_type = resource_type
        self.strategy = strategy

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'PlacementGroup':
        """Initialize a PlacementGroup 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 PlacementGroup JSON')
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError('Required property \'crn\' not present in PlacementGroup JSON')
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in PlacementGroup JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in PlacementGroup JSON')
        if 'lifecycle_state' in _dict:
            args['lifecycle_state'] = _dict.get('lifecycle_state')
        else:
            raise ValueError('Required property \'lifecycle_state\' not present in PlacementGroup JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in PlacementGroup 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 PlacementGroup JSON')
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError('Required property \'resource_type\' not present in PlacementGroup JSON')
        if 'strategy' in _dict:
            args['strategy'] = _dict.get('strategy')
        else:
            raise ValueError('Required property \'strategy\' not present in PlacementGroup JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a PlacementGroup object from 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, 'lifecycle_state') and self.lifecycle_state is not None:
            _dict['lifecycle_state'] = self.lifecycle_state
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'resource_group') and self.resource_group is not None:
            if isinstance(self.resource_group, dict):
                _dict['resource_group'] = self.resource_group
            else:
                _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, 'strategy') and self.strategy is not None:
            _dict['strategy'] = self.strategy
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this PlacementGroup object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'PlacementGroup') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'PlacementGroup') -> 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 placement group.
        """

        DELETING = 'deleting'
        FAILED = 'failed'
        PENDING = 'pending'
        STABLE = 'stable'
        SUSPENDED = 'suspended'
        UPDATING = 'updating'
        WAITING = 'waiting'


    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        PLACEMENT_GROUP = 'placement_group'


    class StrategyEnum(str, Enum):
        """
        The strategy for this placement group
        - `host_spread`: place on different compute hosts
        - `power_spread`: place on compute hosts that use different power sources
        The enumerated values for this property may expand in the future. When processing
        this property, check for and log unknown values. Optionally halt processing and
        surface the error, or bypass the placement group on which the unexpected strategy
        was encountered.
        """

        HOST_SPREAD = 'host_spread'
        POWER_SPREAD = 'power_spread'



class PlacementGroupCollection:
    """
    PlacementGroupCollection.

    :attr PlacementGroupCollectionFirst 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 PlacementGroupCollectionNext next: (optional) A link to the next page of
          resources. This property is present for all pages
          except the last page.
    :attr List[PlacementGroup] placement_groups: Collection of placement groups.
    :attr int total_count: The total number of resources across all pages.
    """

    def __init__(
        self,
        first: 'PlacementGroupCollectionFirst',
        limit: int,
        placement_groups: List['PlacementGroup'],
        total_count: int,
        *,
        next: 'PlacementGroupCollectionNext' = None,
    ) -> None:
        """
        Initialize a PlacementGroupCollection object.

        :param PlacementGroupCollectionFirst 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[PlacementGroup] placement_groups: Collection of placement
               groups.
        :param int total_count: The total number of resources across all pages.
        :param PlacementGroupCollectionNext 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.placement_groups = placement_groups
        self.total_count = total_count

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'PlacementGroupCollection':
        """Initialize a PlacementGroupCollection object from a json dictionary."""
        args = {}
        if 'first' in _dict:
            args['first'] = PlacementGroupCollectionFirst.from_dict(_dict.get('first'))
        else:
            raise ValueError('Required property \'first\' not present in PlacementGroupCollection JSON')
        if 'limit' in _dict:
            args['limit'] = _dict.get('limit')
        else:
            raise ValueError('Required property \'limit\' not present in PlacementGroupCollection JSON')
        if 'next' in _dict:
            args['next'] = PlacementGroupCollectionNext.from_dict(_dict.get('next'))
        if 'placement_groups' in _dict:
            args['placement_groups'] = [PlacementGroup.from_dict(v) for v in _dict.get('placement_groups')]
        else:
            raise ValueError('Required property \'placement_groups\' not present in PlacementGroupCollection JSON')
        if 'total_count' in _dict:
            args['total_count'] = _dict.get('total_count')
        else:
            raise ValueError('Required property \'total_count\' not present in PlacementGroupCollection JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a PlacementGroupCollection object from 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:
            if isinstance(self.first, dict):
                _dict['first'] = self.first
            else:
                _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:
            if isinstance(self.next, dict):
                _dict['next'] = self.next
            else:
                _dict['next'] = self.next.to_dict()
        if hasattr(self, 'placement_groups') and self.placement_groups is not None:
            placement_groups_list = []
            for v in self.placement_groups:
                if isinstance(v, dict):
                    placement_groups_list.append(v)
                else:
                    placement_groups_list.append(v.to_dict())
            _dict['placement_groups'] = placement_groups_list
        if hasattr(self, 'total_count') and self.total_count is not None:
            _dict['total_count'] = self.total_count
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this PlacementGroupCollection object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'PlacementGroupCollection') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'PlacementGroupCollection') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class PlacementGroupCollectionFirst:
    """
    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 PlacementGroupCollectionFirst object.

        :param str href: The URL for a page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'PlacementGroupCollectionFirst':
        """Initialize a PlacementGroupCollectionFirst object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in PlacementGroupCollectionFirst JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a PlacementGroupCollectionFirst object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(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 PlacementGroupCollectionFirst object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'PlacementGroupCollectionFirst') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'PlacementGroupCollectionFirst') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class PlacementGroupCollectionNext:
    """
    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 PlacementGroupCollectionNext object.

        :param str href: The URL for a page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'PlacementGroupCollectionNext':
        """Initialize a PlacementGroupCollectionNext object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in PlacementGroupCollectionNext JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a PlacementGroupCollectionNext object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(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 PlacementGroupCollectionNext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'PlacementGroupCollectionNext') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'PlacementGroupCollectionNext') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class PlacementGroupPatch:
    """
    PlacementGroupPatch.

    :attr str name: (optional) The name for this placement group. The name must not
          be used by another placement group in the region.
    """

    def __init__(
        self,
        *,
        name: str = None,
    ) -> None:
        """
        Initialize a PlacementGroupPatch object.

        :param str name: (optional) The name for this placement group. The name
               must not be used by another placement group in the region.
        """
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'PlacementGroupPatch':
        """Initialize a PlacementGroupPatch 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 PlacementGroupPatch object from 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 PlacementGroupPatch object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'PlacementGroupPatch') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'PlacementGroupPatch') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class PlacementGroupReferenceDeleted:
    """
    If present, this property indicates the referenced resource has been deleted, and
    provides some supplementary information.

    :attr str more_info: Link to documentation about deleted resources.
    """

    def __init__(
        self,
        more_info: str,
    ) -> None:
        """
        Initialize a PlacementGroupReferenceDeleted object.

        :param str more_info: Link to documentation about deleted resources.
        """
        self.more_info = more_info

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'PlacementGroupReferenceDeleted':
        """Initialize a PlacementGroupReferenceDeleted object from a json dictionary."""
        args = {}
        if 'more_info' in _dict:
            args['more_info'] = _dict.get('more_info')
        else:
            raise ValueError('Required property \'more_info\' not present in PlacementGroupReferenceDeleted JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a PlacementGroupReferenceDeleted object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'more_info') and self.more_info is not None:
            _dict['more_info'] = self.more_info
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this PlacementGroupReferenceDeleted object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'PlacementGroupReferenceDeleted') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'PlacementGroupReferenceDeleted') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


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: The floating IP 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 name for this public gateway. The name is unique across all
          public gateways in the VPC.
    :attr ResourceGroupReference resource_group: The resource group for this public
          gateway.
    :attr str resource_type: The resource type.
    :attr str status: The status of this public gateway.
    :attr VPCReference vpc: The VPC this public gateway resides in.
    :attr ZoneReference zone: The zone this public gateway resides in.
    """

    def __init__(
        self,
        created_at: datetime,
        crn: str,
        floating_ip: 'PublicGatewayFloatingIp',
        href: str,
        id: str,
        name: str,
        resource_group: 'ResourceGroupReference',
        resource_type: str,
        status: str,
        vpc: 'VPCReference',
        zone: 'ZoneReference',
    ) -> None:
        """
        Initialize a PublicGateway object.

        :param datetime created_at: The date and time that the public gateway was
               created.
        :param str crn: The CRN for this public gateway.
        :param PublicGatewayFloatingIp floating_ip: The floating IP 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 name for this public gateway. The name is unique
               across all public gateways in the VPC.
        :param ResourceGroupReference resource_group: The resource group for this
               public gateway.
        :param str resource_type: The resource type.
        :param str status: The status of this public gateway.
        :param VPCReference vpc: The VPC this public gateway resides in.
        :param ZoneReference zone: The zone this public gateway resides in.
        """
        self.created_at = created_at
        self.crn = crn
        self.floating_ip = floating_ip
        self.href = href
        self.id = id
        self.name = name
        self.resource_group = resource_group
        self.resource_type = resource_type
        self.status = status
        self.vpc = vpc
        self.zone = zone

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'PublicGateway':
        """Initialize a PublicGateway object from a json dictionary."""
        args = {}
        if 'created_at' in _dict:
            args['created_at'] = string_to_datetime(_dict.get('created_at'))
        else:
            raise ValueError('Required property \'created_at\' not present in PublicGateway JSON')
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError('Required property \'crn\' not present in PublicGateway JSON')
        if 'floating_ip' in _dict:
            args['floating_ip'] = PublicGatewayFloatingIp.from_dict(_dict.get('floating_ip'))
        else:
            raise ValueError('Required property \'floating_ip\' not present in PublicGateway JSON')
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in PublicGateway JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in PublicGateway JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in PublicGateway JSON')
        if 'resource_group' in _dict:
            args['resource_group'] = ResourceGroupReference.from_dict(_dict.get('resource_group'))
        else:
            raise ValueError('Required property \'resource_group\' not present in PublicGateway JSON')
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError('Required property \'resource_type\' not present in PublicGateway JSON')
        if 'status' in _dict:
            args['status'] = _dict.get('status')
        else:
            raise ValueError('Required property \'status\' not present in PublicGateway JSON')
        if 'vpc' in _dict:
            args['vpc'] = VPCReference.from_dict(_dict.get('vpc'))
        else:
            raise ValueError('Required property \'vpc\' not present in PublicGateway JSON')
        if 'zone' in _dict:
            args['zone'] = ZoneReference.from_dict(_dict.get('zone'))
        else:
            raise ValueError('Required property \'zone\' not present in PublicGateway JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a PublicGateway object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'created_at') and self.created_at is not None:
            _dict['created_at'] = datetime_to_string(self.created_at)
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'floating_ip') and self.floating_ip is not None:
            if isinstance(self.floating_ip, dict):
                _dict['floating_ip'] = self.floating_ip
            else:
                _dict['floating_ip'] = self.floating_ip.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'resource_group') and self.resource_group is not None:
            if isinstance(self.resource_group, dict):
                _dict['resource_group'] = self.resource_group
            else:
                _dict['resource_group'] = self.resource_group.to_dict()
        if hasattr(self, 'resource_type') and self.resource_type is not None:
            _dict['resource_type'] = self.resource_type
        if hasattr(self, 'status') and self.status is not None:
            _dict['status'] = self.status
        if hasattr(self, 'vpc') and self.vpc is not None:
            if isinstance(self.vpc, dict):
                _dict['vpc'] = self.vpc
            else:
                _dict['vpc'] = self.vpc.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 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 this public gateway.
        """

        AVAILABLE = 'available'
        DELETING = 'deleting'
        FAILED = 'failed'
        PENDING = 'pending'



class PublicGatewayCollection:
    """
    PublicGatewayCollection.

    :attr PublicGatewayCollectionFirst first: A link to the first page of resources.
    :attr int limit: The maximum number of resources that can be returned by the
          request.
    :attr PublicGatewayCollectionNext next: (optional) A link to the next page of
          resources. This property is present for all pages
          except the last page.
    :attr List[PublicGateway] public_gateways: Collection of public gateways.
    :attr int total_count: The total number of resources across all pages.
    """

    def __init__(
        self,
        first: 'PublicGatewayCollectionFirst',
        limit: int,
        public_gateways: List['PublicGateway'],
        total_count: int,
        *,
        next: 'PublicGatewayCollectionNext' = None,
    ) -> None:
        """
        Initialize a PublicGatewayCollection object.

        :param PublicGatewayCollectionFirst first: A link to the first page of
               resources.
        :param int limit: The maximum number of resources that can be returned by
               the request.
        :param List[PublicGateway] public_gateways: Collection of public gateways.
        :param int total_count: The total number of resources across all pages.
        :param PublicGatewayCollectionNext next: (optional) A link to the next page
               of resources. This property is present for all pages
               except the last page.
        """
        self.first = first
        self.limit = limit
        self.next = next
        self.public_gateways = public_gateways
        self.total_count = total_count

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'PublicGatewayCollection':
        """Initialize a PublicGatewayCollection object from a json dictionary."""
        args = {}
        if 'first' in _dict:
            args['first'] = PublicGatewayCollectionFirst.from_dict(_dict.get('first'))
        else:
            raise ValueError('Required property \'first\' not present in PublicGatewayCollection JSON')
        if 'limit' in _dict:
            args['limit'] = _dict.get('limit')
        else:
            raise ValueError('Required property \'limit\' not present in PublicGatewayCollection JSON')
        if 'next' in _dict:
            args['next'] = PublicGatewayCollectionNext.from_dict(_dict.get('next'))
        if 'public_gateways' in _dict:
            args['public_gateways'] = [PublicGateway.from_dict(v) for v in _dict.get('public_gateways')]
        else:
            raise ValueError('Required property \'public_gateways\' not present in PublicGatewayCollection JSON')
        if 'total_count' in _dict:
            args['total_count'] = _dict.get('total_count')
        else:
            raise ValueError('Required property \'total_count\' not present in PublicGatewayCollection JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a PublicGatewayCollection object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'first') and self.first is not None:
            if isinstance(self.first, dict):
                _dict['first'] = self.first
            else:
                _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:
            if isinstance(self.next, dict):
                _dict['next'] = self.next
            else:
                _dict['next'] = self.next.to_dict()
        if hasattr(self, 'public_gateways') and self.public_gateways is not None:
            public_gateways_list = []
            for v in self.public_gateways:
                if isinstance(v, dict):
                    public_gateways_list.append(v)
                else:
                    public_gateways_list.append(v.to_dict())
            _dict['public_gateways'] = public_gateways_list
        if hasattr(self, 'total_count') and self.total_count is not None:
            _dict['total_count'] = self.total_count
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this 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:
    """
    The floating IP bound to this public gateway.

    :attr str address: The globally unique IP address.
    :attr str crn: The CRN for this floating IP.
    :attr FloatingIPReferenceDeleted deleted: (optional) If present, this property
          indicates the referenced resource has been deleted, and provides
          some supplementary information.
    :attr str href: The URL for this floating IP.
    :attr str id: The unique identifier for this floating IP.
    :attr str name: The name for this floating IP. The name is unique across all
          floating IPs in the region.
    """

    def __init__(
        self,
        address: str,
        crn: str,
        href: str,
        id: str,
        name: str,
        *,
        deleted: 'FloatingIPReferenceDeleted' = None,
    ) -> None:
        """
        Initialize a PublicGatewayFloatingIp object.

        :param str address: The globally unique IP address.
        :param str crn: The CRN for this floating IP.
        :param str href: The URL for this floating IP.
        :param str id: The unique identifier for this floating IP.
        :param str name: The name for this floating IP. The name is unique across
               all floating IPs in the region.
        :param FloatingIPReferenceDeleted deleted: (optional) If present, this
               property indicates the referenced resource has been deleted, and provides
               some supplementary information.
        """
        self.address = address
        self.crn = crn
        self.deleted = deleted
        self.href = href
        self.id = id
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'PublicGatewayFloatingIp':
        """Initialize a PublicGatewayFloatingIp object from a json dictionary."""
        args = {}
        if 'address' in _dict:
            args['address'] = _dict.get('address')
        else:
            raise ValueError('Required property \'address\' not present in PublicGatewayFloatingIp JSON')
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError('Required property \'crn\' not present in PublicGatewayFloatingIp JSON')
        if 'deleted' in _dict:
            args['deleted'] = FloatingIPReferenceDeleted.from_dict(_dict.get('deleted'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in PublicGatewayFloatingIp JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in PublicGatewayFloatingIp JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in PublicGatewayFloatingIp JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a PublicGatewayFloatingIp object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'address') and self.address is not None:
            _dict['address'] = self.address
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'deleted') and self.deleted is not None:
            if isinstance(self.deleted, dict):
                _dict['deleted'] = self.deleted
            else:
                _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this PublicGatewayFloatingIp object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'PublicGatewayFloatingIp') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'PublicGatewayFloatingIp') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class PublicGatewayIdentity:
    """
    Identifies a public gateway by a unique property.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a PublicGatewayIdentity object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['PublicGatewayIdentityPublicGatewayIdentityById', 'PublicGatewayIdentityPublicGatewayIdentityByCRN', 'PublicGatewayIdentityPublicGatewayIdentityByHref'])
        )
        raise Exception(msg)


class PublicGatewayPatch:
    """
    PublicGatewayPatch.

    :attr str name: (optional) The name for this public gateway. The name must not
          be used by another public gateway in the VPC.
    """

    def __init__(
        self,
        *,
        name: str = None,
    ) -> None:
        """
        Initialize a PublicGatewayPatch object.

        :param str name: (optional) The name for this public gateway. The name must
               not be used by another public gateway in the VPC.
        """
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'PublicGatewayPatch':
        """Initialize a PublicGatewayPatch object from a json dictionary."""
        args = {}
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a PublicGatewayPatch object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this PublicGatewayPatch object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'PublicGatewayPatch') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'PublicGatewayPatch') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class PublicGatewayReference:
    """
    PublicGatewayReference.

    :attr str crn: The CRN for this public gateway.
    :attr PublicGatewayReferenceDeleted deleted: (optional) If present, this
          property indicates the referenced resource has been deleted, and provides
          some supplementary information.
    :attr str href: The URL for this public gateway.
    :attr str id: The unique identifier for this public gateway.
    :attr str name: The name for this public gateway. The name is unique across all
          public gateways in the VPC.
    :attr str resource_type: The resource type.
    """

    def __init__(
        self,
        crn: str,
        href: str,
        id: str,
        name: str,
        resource_type: str,
        *,
        deleted: 'PublicGatewayReferenceDeleted' = None,
    ) -> None:
        """
        Initialize a PublicGatewayReference object.

        :param str crn: The CRN for this public gateway.
        :param str href: The URL for this public gateway.
        :param str id: The unique identifier for this public gateway.
        :param str name: The name for this public gateway. The name is unique
               across all public gateways in the VPC.
        :param str resource_type: The resource type.
        :param PublicGatewayReferenceDeleted deleted: (optional) If present, this
               property indicates the referenced resource has been deleted, and provides
               some supplementary information.
        """
        self.crn = crn
        self.deleted = deleted
        self.href = href
        self.id = id
        self.name = name
        self.resource_type = resource_type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'PublicGatewayReference':
        """Initialize a PublicGatewayReference object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError('Required property \'crn\' not present in PublicGatewayReference JSON')
        if 'deleted' in _dict:
            args['deleted'] = PublicGatewayReferenceDeleted.from_dict(_dict.get('deleted'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in PublicGatewayReference JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in PublicGatewayReference JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in PublicGatewayReference JSON')
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError('Required property \'resource_type\' not present in PublicGatewayReference JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a PublicGatewayReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'deleted') and self.deleted is not None:
            if isinstance(self.deleted, dict):
                _dict['deleted'] = self.deleted
            else:
                _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'resource_type') and self.resource_type is not None:
            _dict['resource_type'] = self.resource_type
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this PublicGatewayReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'PublicGatewayReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'PublicGatewayReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        PUBLIC_GATEWAY = 'public_gateway'



class PublicGatewayReferenceDeleted:
    """
    If present, this property indicates the referenced resource has been deleted, and
    provides some supplementary information.

    :attr str more_info: Link to documentation about deleted resources.
    """

    def __init__(
        self,
        more_info: str,
    ) -> None:
        """
        Initialize a PublicGatewayReferenceDeleted object.

        :param str more_info: Link to documentation about deleted resources.
        """
        self.more_info = more_info

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'PublicGatewayReferenceDeleted':
        """Initialize a PublicGatewayReferenceDeleted object from a json dictionary."""
        args = {}
        if 'more_info' in _dict:
            args['more_info'] = _dict.get('more_info')
        else:
            raise ValueError('Required property \'more_info\' not present in PublicGatewayReferenceDeleted JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a PublicGatewayReferenceDeleted object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'more_info') and self.more_info is not None:
            _dict['more_info'] = self.more_info
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this PublicGatewayReferenceDeleted object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'PublicGatewayReferenceDeleted') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'PublicGatewayReferenceDeleted') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class Region:
    """
    Region.

    :attr str endpoint: The API endpoint for this region.
    :attr str href: The URL for this region.
    :attr str name: The globally unique name for this region.
    :attr str status: The availability status of this region.
    """

    def __init__(
        self,
        endpoint: str,
        href: str,
        name: str,
        status: str,
    ) -> None:
        """
        Initialize a Region object.

        :param str endpoint: The API endpoint for this region.
        :param str href: The URL for this region.
        :param str name: The globally unique name for this region.
        :param str status: The availability status of this region.
        """
        self.endpoint = endpoint
        self.href = href
        self.name = name
        self.status = status

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'Region':
        """Initialize a Region object from a json dictionary."""
        args = {}
        if 'endpoint' in _dict:
            args['endpoint'] = _dict.get('endpoint')
        else:
            raise ValueError('Required property \'endpoint\' not present in Region JSON')
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in Region JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in Region JSON')
        if 'status' in _dict:
            args['status'] = _dict.get('status')
        else:
            raise ValueError('Required property \'status\' not present in Region JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a Region object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'endpoint') and self.endpoint is not None:
            _dict['endpoint'] = self.endpoint
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'status') and self.status is not None:
            _dict['status'] = self.status
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this Region object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'Region') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'Region') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class StatusEnum(str, Enum):
        """
        The availability status of this region.
        """

        AVAILABLE = 'available'
        UNAVAILABLE = 'unavailable'



class RegionCollection:
    """
    RegionCollection.

    :attr List[Region] regions: Collection of regions.
    """

    def __init__(
        self,
        regions: List['Region'],
    ) -> None:
        """
        Initialize a RegionCollection object.

        :param List[Region] regions: Collection of regions.
        """
        self.regions = regions

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'RegionCollection':
        """Initialize a RegionCollection object from a json dictionary."""
        args = {}
        if 'regions' in _dict:
            args['regions'] = [Region.from_dict(v) for v 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:
            regions_list = []
            for v in self.regions:
                if isinstance(v, dict):
                    regions_list.append(v)
                else:
                    regions_list.append(v.to_dict())
            _dict['regions'] = regions_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 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 RegionIdentity:
    """
    Identifies a region by a unique property.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a RegionIdentity object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['RegionIdentityByName', 'RegionIdentityByHref'])
        )
        raise Exception(msg)


class RegionReference:
    """
    RegionReference.

    :attr str href: The URL for this region.
    :attr str name: The globally unique name for this region.
    """

    def __init__(
        self,
        href: str,
        name: str,
    ) -> None:
        """
        Initialize a RegionReference object.

        :param str href: The URL for this region.
        :param str name: The globally unique name for this region.
        """
        self.href = href
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'RegionReference':
        """Initialize a RegionReference object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in RegionReference JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in RegionReference JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a RegionReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this RegionReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'RegionReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'RegionReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class ReservedIP:
    """
    ReservedIP.

    :attr str address: The IP address.
          If the address has not yet been selected, the value will be `0.0.0.0`.
          This property may add support for IPv6 addresses in the future. When processing
          a value in this property, verify that the address is in an expected format. If
          it is not, log an error. Optionally halt processing and surface the error, or
          bypass the resource on which the unexpected IP address format was encountered.
    :attr bool auto_delete: Indicates whether this reserved IP member will be
          automatically deleted when either
          `target` is deleted, or the reserved IP is unbound.
    :attr datetime created_at: The date and time that the reserved IP was created.
    :attr str href: The URL for this reserved IP.
    :attr str id: The unique identifier for this reserved IP.
    :attr str lifecycle_state: The lifecycle state of the reserved IP.
    :attr str name: The name for this reserved IP. The name is unique across all
          reserved IPs in a subnet.
    :attr str owner: The owner of the reserved IP.
    :attr str resource_type: The resource type.
    :attr ReservedIPTarget target: (optional) The target this reserved IP is bound
          to.
          If absent, this reserved IP is provider-owned or unbound.
    """

    def __init__(
        self,
        address: str,
        auto_delete: bool,
        created_at: datetime,
        href: str,
        id: str,
        lifecycle_state: str,
        name: str,
        owner: str,
        resource_type: str,
        *,
        target: 'ReservedIPTarget' = None,
    ) -> None:
        """
        Initialize a ReservedIP object.

        :param str address: The IP address.
               If the address has not yet been selected, the value will be `0.0.0.0`.
               This property may add support for IPv6 addresses in the future. When
               processing a value in this property, verify that the address is in an
               expected format. If it is not, log an error. Optionally halt processing and
               surface the error, or bypass the resource on which the unexpected IP
               address format was encountered.
        :param bool auto_delete: Indicates whether this reserved IP member will be
               automatically deleted when either
               `target` is deleted, or the reserved IP is unbound.
        :param datetime created_at: The date and time that the reserved IP was
               created.
        :param str href: The URL for this reserved IP.
        :param str id: The unique identifier for this reserved IP.
        :param str lifecycle_state: The lifecycle state of the reserved IP.
        :param str name: The name for this reserved IP. The name is unique across
               all reserved IPs in a subnet.
        :param str owner: The owner of the reserved IP.
        :param str resource_type: The resource type.
        :param ReservedIPTarget target: (optional) The target this reserved IP is
               bound to.
               If absent, this reserved IP is provider-owned or unbound.
        """
        self.address = address
        self.auto_delete = auto_delete
        self.created_at = created_at
        self.href = href
        self.id = id
        self.lifecycle_state = lifecycle_state
        self.name = name
        self.owner = owner
        self.resource_type = resource_type
        self.target = target

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ReservedIP':
        """Initialize a ReservedIP object from a json dictionary."""
        args = {}
        if 'address' in _dict:
            args['address'] = _dict.get('address')
        else:
            raise ValueError('Required property \'address\' not present in ReservedIP JSON')
        if 'auto_delete' in _dict:
            args['auto_delete'] = _dict.get('auto_delete')
        else:
            raise ValueError('Required property \'auto_delete\' not present in ReservedIP JSON')
        if 'created_at' in _dict:
            args['created_at'] = string_to_datetime(_dict.get('created_at'))
        else:
            raise ValueError('Required property \'created_at\' not present in ReservedIP JSON')
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in ReservedIP JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in ReservedIP JSON')
        if 'lifecycle_state' in _dict:
            args['lifecycle_state'] = _dict.get('lifecycle_state')
        else:
            raise ValueError('Required property \'lifecycle_state\' not present in ReservedIP JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in ReservedIP JSON')
        if 'owner' in _dict:
            args['owner'] = _dict.get('owner')
        else:
            raise ValueError('Required property \'owner\' not present in ReservedIP JSON')
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError('Required property \'resource_type\' not present in ReservedIP JSON')
        if 'target' in _dict:
            args['target'] = _dict.get('target')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ReservedIP object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'address') and self.address is not None:
            _dict['address'] = self.address
        if hasattr(self, 'auto_delete') and self.auto_delete is not None:
            _dict['auto_delete'] = self.auto_delete
        if hasattr(self, 'created_at') and self.created_at is not None:
            _dict['created_at'] = datetime_to_string(self.created_at)
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, '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, 'owner') and self.owner is not None:
            _dict['owner'] = self.owner
        if hasattr(self, 'resource_type') and self.resource_type is not None:
            _dict['resource_type'] = self.resource_type
        if hasattr(self, 'target') and self.target is not None:
            if isinstance(self.target, dict):
                _dict['target'] = self.target
            else:
                _dict['target'] = self.target.to_dict()
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this ReservedIP object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ReservedIP') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ReservedIP') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class LifecycleStateEnum(str, Enum):
        """
        The lifecycle state of the reserved IP.
        """

        DELETING = 'deleting'
        FAILED = 'failed'
        PENDING = 'pending'
        STABLE = 'stable'
        SUSPENDED = 'suspended'
        UPDATING = 'updating'
        WAITING = 'waiting'


    class OwnerEnum(str, Enum):
        """
        The owner of the reserved IP.
        """

        PROVIDER = 'provider'
        USER = 'user'


    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        SUBNET_RESERVED_IP = 'subnet_reserved_ip'



class ReservedIPCollection:
    """
    ReservedIPCollection.

    :attr ReservedIPCollectionFirst first: A link to the first page of resources.
    :attr int limit: The maximum number of resources that can be returned by the
          request.
    :attr ReservedIPCollectionNext next: (optional) A link to the next page of
          resources. This property is present for all pages
          except the last page.
    :attr List[ReservedIP] reserved_ips: Collection of reserved IPs in this subnet.
    :attr int total_count: The total number of resources across all pages.
    """

    def __init__(
        self,
        first: 'ReservedIPCollectionFirst',
        limit: int,
        reserved_ips: List['ReservedIP'],
        total_count: int,
        *,
        next: 'ReservedIPCollectionNext' = None,
    ) -> None:
        """
        Initialize a ReservedIPCollection object.

        :param ReservedIPCollectionFirst first: A link to the first page of
               resources.
        :param int limit: The maximum number of resources that can be returned by
               the request.
        :param List[ReservedIP] reserved_ips: Collection of reserved IPs in this
               subnet.
        :param int total_count: The total number of resources across all pages.
        :param ReservedIPCollectionNext next: (optional) A link to the next page of
               resources. This property is present for all pages
               except the last page.
        """
        self.first = first
        self.limit = limit
        self.next = next
        self.reserved_ips = reserved_ips
        self.total_count = total_count

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ReservedIPCollection':
        """Initialize a ReservedIPCollection object from a json dictionary."""
        args = {}
        if 'first' in _dict:
            args['first'] = ReservedIPCollectionFirst.from_dict(_dict.get('first'))
        else:
            raise ValueError('Required property \'first\' not present in ReservedIPCollection JSON')
        if 'limit' in _dict:
            args['limit'] = _dict.get('limit')
        else:
            raise ValueError('Required property \'limit\' not present in ReservedIPCollection JSON')
        if 'next' in _dict:
            args['next'] = ReservedIPCollectionNext.from_dict(_dict.get('next'))
        if 'reserved_ips' in _dict:
            args['reserved_ips'] = [ReservedIP.from_dict(v) for v in _dict.get('reserved_ips')]
        else:
            raise ValueError('Required property \'reserved_ips\' not present in ReservedIPCollection JSON')
        if 'total_count' in _dict:
            args['total_count'] = _dict.get('total_count')
        else:
            raise ValueError('Required property \'total_count\' not present in ReservedIPCollection JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ReservedIPCollection object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'first') and self.first is not None:
            if isinstance(self.first, dict):
                _dict['first'] = self.first
            else:
                _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:
            if isinstance(self.next, dict):
                _dict['next'] = self.next
            else:
                _dict['next'] = self.next.to_dict()
        if hasattr(self, 'reserved_ips') and self.reserved_ips is not None:
            reserved_ips_list = []
            for v in self.reserved_ips:
                if isinstance(v, dict):
                    reserved_ips_list.append(v)
                else:
                    reserved_ips_list.append(v.to_dict())
            _dict['reserved_ips'] = reserved_ips_list
        if hasattr(self, 'total_count') and self.total_count is not None:
            _dict['total_count'] = self.total_count
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this ReservedIPCollection object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ReservedIPCollection') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ReservedIPCollection') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class ReservedIPCollectionBareMetalServerNetworkInterfaceContext:
    """
    ReservedIPCollectionBareMetalServerNetworkInterfaceContext.

    :attr ReservedIPCollectionBareMetalServerNetworkInterfaceContextFirst first: A
          link to the first page of resources.
    :attr List[ReservedIP] ips: Collection of reserved IPs bound to a bare metal
          server network interface.
    :attr int limit: The maximum number of resources that can be returned by the
          request.
    :attr ReservedIPCollectionBareMetalServerNetworkInterfaceContextNext 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: 'ReservedIPCollectionBareMetalServerNetworkInterfaceContextFirst',
        ips: List['ReservedIP'],
        limit: int,
        total_count: int,
        *,
        next: 'ReservedIPCollectionBareMetalServerNetworkInterfaceContextNext' = None,
    ) -> None:
        """
        Initialize a ReservedIPCollectionBareMetalServerNetworkInterfaceContext object.

        :param ReservedIPCollectionBareMetalServerNetworkInterfaceContextFirst
               first: A link to the first page of resources.
        :param List[ReservedIP] ips: Collection of reserved IPs bound to a bare
               metal server network interface.
        :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 ReservedIPCollectionBareMetalServerNetworkInterfaceContextNext next:
               (optional) A link to the next page of resources. This property is present
               for all pages
               except the last page.
        """
        self.first = first
        self.ips = ips
        self.limit = limit
        self.next = next
        self.total_count = total_count

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ReservedIPCollectionBareMetalServerNetworkInterfaceContext':
        """Initialize a ReservedIPCollectionBareMetalServerNetworkInterfaceContext object from a json dictionary."""
        args = {}
        if 'first' in _dict:
            args['first'] = ReservedIPCollectionBareMetalServerNetworkInterfaceContextFirst.from_dict(_dict.get('first'))
        else:
            raise ValueError('Required property \'first\' not present in ReservedIPCollectionBareMetalServerNetworkInterfaceContext JSON')
        if 'ips' in _dict:
            args['ips'] = [ReservedIP.from_dict(v) for v in _dict.get('ips')]
        else:
            raise ValueError('Required property \'ips\' not present in ReservedIPCollectionBareMetalServerNetworkInterfaceContext JSON')
        if 'limit' in _dict:
            args['limit'] = _dict.get('limit')
        else:
            raise ValueError('Required property \'limit\' not present in ReservedIPCollectionBareMetalServerNetworkInterfaceContext JSON')
        if 'next' in _dict:
            args['next'] = ReservedIPCollectionBareMetalServerNetworkInterfaceContextNext.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 ReservedIPCollectionBareMetalServerNetworkInterfaceContext JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ReservedIPCollectionBareMetalServerNetworkInterfaceContext object from 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:
            if isinstance(self.first, dict):
                _dict['first'] = self.first
            else:
                _dict['first'] = self.first.to_dict()
        if hasattr(self, 'ips') and self.ips is not None:
            ips_list = []
            for v in self.ips:
                if isinstance(v, dict):
                    ips_list.append(v)
                else:
                    ips_list.append(v.to_dict())
            _dict['ips'] = ips_list
        if hasattr(self, 'limit') and self.limit is not None:
            _dict['limit'] = self.limit
        if hasattr(self, 'next') and self.next is not None:
            if isinstance(self.next, dict):
                _dict['next'] = self.next
            else:
                _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 ReservedIPCollectionBareMetalServerNetworkInterfaceContext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ReservedIPCollectionBareMetalServerNetworkInterfaceContext') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ReservedIPCollectionBareMetalServerNetworkInterfaceContext') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class ReservedIPCollectionBareMetalServerNetworkInterfaceContextFirst:
    """
    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 ReservedIPCollectionBareMetalServerNetworkInterfaceContextFirst object.

        :param str href: The URL for a page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ReservedIPCollectionBareMetalServerNetworkInterfaceContextFirst':
        """Initialize a ReservedIPCollectionBareMetalServerNetworkInterfaceContextFirst object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in ReservedIPCollectionBareMetalServerNetworkInterfaceContextFirst JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ReservedIPCollectionBareMetalServerNetworkInterfaceContextFirst object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(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 ReservedIPCollectionBareMetalServerNetworkInterfaceContextFirst object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ReservedIPCollectionBareMetalServerNetworkInterfaceContextFirst') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ReservedIPCollectionBareMetalServerNetworkInterfaceContextFirst') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class ReservedIPCollectionBareMetalServerNetworkInterfaceContextNext:
    """
    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 ReservedIPCollectionBareMetalServerNetworkInterfaceContextNext object.

        :param str href: The URL for a page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ReservedIPCollectionBareMetalServerNetworkInterfaceContextNext':
        """Initialize a ReservedIPCollectionBareMetalServerNetworkInterfaceContextNext object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in ReservedIPCollectionBareMetalServerNetworkInterfaceContextNext JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ReservedIPCollectionBareMetalServerNetworkInterfaceContextNext object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(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 ReservedIPCollectionBareMetalServerNetworkInterfaceContextNext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ReservedIPCollectionBareMetalServerNetworkInterfaceContextNext') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ReservedIPCollectionBareMetalServerNetworkInterfaceContextNext') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class ReservedIPCollectionEndpointGatewayContext:
    """
    ReservedIPCollectionEndpointGatewayContext.

    :attr ReservedIPCollectionEndpointGatewayContextFirst first: A link to the first
          page of resources.
    :attr List[ReservedIP] ips: Collection of reserved IPs bound to an endpoint
          gateway.
    :attr int limit: The maximum number of resources that can be returned by the
          request.
    :attr ReservedIPCollectionEndpointGatewayContextNext next: (optional) A link to
          the next page of resources. This property is present for all pages
          except the last page.
    :attr int total_count: The total number of resources across all pages.
    """

    def __init__(
        self,
        first: 'ReservedIPCollectionEndpointGatewayContextFirst',
        ips: List['ReservedIP'],
        limit: int,
        total_count: int,
        *,
        next: 'ReservedIPCollectionEndpointGatewayContextNext' = None,
    ) -> None:
        """
        Initialize a ReservedIPCollectionEndpointGatewayContext object.

        :param ReservedIPCollectionEndpointGatewayContextFirst first: A link to the
               first page of resources.
        :param List[ReservedIP] ips: Collection of reserved IPs bound to an
               endpoint gateway.
        :param int limit: The maximum number of resources that can be returned by
               the request.
        :param int total_count: The total number of resources across all pages.
        :param ReservedIPCollectionEndpointGatewayContextNext next: (optional) A
               link to the next page of resources. This property is present for all pages
               except the last page.
        """
        self.first = first
        self.ips = ips
        self.limit = limit
        self.next = next
        self.total_count = total_count

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ReservedIPCollectionEndpointGatewayContext':
        """Initialize a ReservedIPCollectionEndpointGatewayContext object from a json dictionary."""
        args = {}
        if 'first' in _dict:
            args['first'] = ReservedIPCollectionEndpointGatewayContextFirst.from_dict(_dict.get('first'))
        else:
            raise ValueError('Required property \'first\' not present in ReservedIPCollectionEndpointGatewayContext JSON')
        if 'ips' in _dict:
            args['ips'] = [ReservedIP.from_dict(v) for v in _dict.get('ips')]
        else:
            raise ValueError('Required property \'ips\' not present in ReservedIPCollectionEndpointGatewayContext JSON')
        if 'limit' in _dict:
            args['limit'] = _dict.get('limit')
        else:
            raise ValueError('Required property \'limit\' not present in ReservedIPCollectionEndpointGatewayContext JSON')
        if 'next' in _dict:
            args['next'] = ReservedIPCollectionEndpointGatewayContextNext.from_dict(_dict.get('next'))
        if 'total_count' in _dict:
            args['total_count'] = _dict.get('total_count')
        else:
            raise ValueError('Required property \'total_count\' not present in ReservedIPCollectionEndpointGatewayContext JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ReservedIPCollectionEndpointGatewayContext object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'first') and self.first is not None:
            if isinstance(self.first, dict):
                _dict['first'] = self.first
            else:
                _dict['first'] = self.first.to_dict()
        if hasattr(self, 'ips') and self.ips is not None:
            ips_list = []
            for v in self.ips:
                if isinstance(v, dict):
                    ips_list.append(v)
                else:
                    ips_list.append(v.to_dict())
            _dict['ips'] = ips_list
        if hasattr(self, 'limit') and self.limit is not None:
            _dict['limit'] = self.limit
        if hasattr(self, 'next') and self.next is not None:
            if isinstance(self.next, dict):
                _dict['next'] = self.next
            else:
                _dict['next'] = self.next.to_dict()
        if hasattr(self, 'total_count') and self.total_count is not None:
            _dict['total_count'] = self.total_count
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this ReservedIPCollectionEndpointGatewayContext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ReservedIPCollectionEndpointGatewayContext') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ReservedIPCollectionEndpointGatewayContext') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class ReservedIPCollectionEndpointGatewayContextFirst:
    """
    A link to the first page of resources.

    :attr str href: The URL for a page of resources.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a ReservedIPCollectionEndpointGatewayContextFirst object.

        :param str href: The URL for a page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ReservedIPCollectionEndpointGatewayContextFirst':
        """Initialize a ReservedIPCollectionEndpointGatewayContextFirst object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in ReservedIPCollectionEndpointGatewayContextFirst JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ReservedIPCollectionEndpointGatewayContextFirst object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this ReservedIPCollectionEndpointGatewayContextFirst object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ReservedIPCollectionEndpointGatewayContextFirst') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ReservedIPCollectionEndpointGatewayContextFirst') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class ReservedIPCollectionEndpointGatewayContextNext:
    """
    A link to the next page of resources. This property is present for all pages except
    the last page.

    :attr str href: The URL for a page of resources.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a ReservedIPCollectionEndpointGatewayContextNext object.

        :param str href: The URL for a page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ReservedIPCollectionEndpointGatewayContextNext':
        """Initialize a ReservedIPCollectionEndpointGatewayContextNext object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in ReservedIPCollectionEndpointGatewayContextNext JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ReservedIPCollectionEndpointGatewayContextNext object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this ReservedIPCollectionEndpointGatewayContextNext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ReservedIPCollectionEndpointGatewayContextNext') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ReservedIPCollectionEndpointGatewayContextNext') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class ReservedIPCollectionFirst:
    """
    A link to the first page of resources.

    :attr str href: The URL for a page of resources.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a ReservedIPCollectionFirst object.

        :param str href: The URL for a page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ReservedIPCollectionFirst':
        """Initialize a ReservedIPCollectionFirst object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in ReservedIPCollectionFirst JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ReservedIPCollectionFirst object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this ReservedIPCollectionFirst object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ReservedIPCollectionFirst') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ReservedIPCollectionFirst') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class ReservedIPCollectionInstanceNetworkInterfaceContext:
    """
    ReservedIPCollectionInstanceNetworkInterfaceContext.

    :attr ReservedIPCollectionInstanceNetworkInterfaceContextFirst first: A link to
          the first page of resources.
    :attr List[ReservedIP] ips: Collection of reserved IPs bound to an instance
          network interface.
    :attr int limit: The maximum number of resources that can be returned by the
          request.
    :attr ReservedIPCollectionInstanceNetworkInterfaceContextNext 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: 'ReservedIPCollectionInstanceNetworkInterfaceContextFirst',
        ips: List['ReservedIP'],
        limit: int,
        total_count: int,
        *,
        next: 'ReservedIPCollectionInstanceNetworkInterfaceContextNext' = None,
    ) -> None:
        """
        Initialize a ReservedIPCollectionInstanceNetworkInterfaceContext object.

        :param ReservedIPCollectionInstanceNetworkInterfaceContextFirst first: A
               link to the first page of resources.
        :param List[ReservedIP] ips: Collection of reserved IPs bound to an
               instance network interface.
        :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 ReservedIPCollectionInstanceNetworkInterfaceContextNext next:
               (optional) A link to the next page of resources. This property is present
               for all pages
               except the last page.
        """
        self.first = first
        self.ips = ips
        self.limit = limit
        self.next = next
        self.total_count = total_count

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ReservedIPCollectionInstanceNetworkInterfaceContext':
        """Initialize a ReservedIPCollectionInstanceNetworkInterfaceContext object from a json dictionary."""
        args = {}
        if 'first' in _dict:
            args['first'] = ReservedIPCollectionInstanceNetworkInterfaceContextFirst.from_dict(_dict.get('first'))
        else:
            raise ValueError('Required property \'first\' not present in ReservedIPCollectionInstanceNetworkInterfaceContext JSON')
        if 'ips' in _dict:
            args['ips'] = [ReservedIP.from_dict(v) for v in _dict.get('ips')]
        else:
            raise ValueError('Required property \'ips\' not present in ReservedIPCollectionInstanceNetworkInterfaceContext JSON')
        if 'limit' in _dict:
            args['limit'] = _dict.get('limit')
        else:
            raise ValueError('Required property \'limit\' not present in ReservedIPCollectionInstanceNetworkInterfaceContext JSON')
        if 'next' in _dict:
            args['next'] = ReservedIPCollectionInstanceNetworkInterfaceContextNext.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 ReservedIPCollectionInstanceNetworkInterfaceContext JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ReservedIPCollectionInstanceNetworkInterfaceContext object from 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:
            if isinstance(self.first, dict):
                _dict['first'] = self.first
            else:
                _dict['first'] = self.first.to_dict()
        if hasattr(self, 'ips') and self.ips is not None:
            ips_list = []
            for v in self.ips:
                if isinstance(v, dict):
                    ips_list.append(v)
                else:
                    ips_list.append(v.to_dict())
            _dict['ips'] = ips_list
        if hasattr(self, 'limit') and self.limit is not None:
            _dict['limit'] = self.limit
        if hasattr(self, 'next') and self.next is not None:
            if isinstance(self.next, dict):
                _dict['next'] = self.next
            else:
                _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 ReservedIPCollectionInstanceNetworkInterfaceContext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ReservedIPCollectionInstanceNetworkInterfaceContext') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ReservedIPCollectionInstanceNetworkInterfaceContext') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class ReservedIPCollectionInstanceNetworkInterfaceContextFirst:
    """
    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 ReservedIPCollectionInstanceNetworkInterfaceContextFirst object.

        :param str href: The URL for a page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ReservedIPCollectionInstanceNetworkInterfaceContextFirst':
        """Initialize a ReservedIPCollectionInstanceNetworkInterfaceContextFirst object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in ReservedIPCollectionInstanceNetworkInterfaceContextFirst JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ReservedIPCollectionInstanceNetworkInterfaceContextFirst object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(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 ReservedIPCollectionInstanceNetworkInterfaceContextFirst object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ReservedIPCollectionInstanceNetworkInterfaceContextFirst') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ReservedIPCollectionInstanceNetworkInterfaceContextFirst') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class ReservedIPCollectionInstanceNetworkInterfaceContextNext:
    """
    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 ReservedIPCollectionInstanceNetworkInterfaceContextNext object.

        :param str href: The URL for a page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ReservedIPCollectionInstanceNetworkInterfaceContextNext':
        """Initialize a ReservedIPCollectionInstanceNetworkInterfaceContextNext object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in ReservedIPCollectionInstanceNetworkInterfaceContextNext JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ReservedIPCollectionInstanceNetworkInterfaceContextNext object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(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 ReservedIPCollectionInstanceNetworkInterfaceContextNext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ReservedIPCollectionInstanceNetworkInterfaceContextNext') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ReservedIPCollectionInstanceNetworkInterfaceContextNext') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class ReservedIPCollectionNext:
    """
    A link to the next page of resources. This property is present for all pages except
    the last page.

    :attr str href: The URL for a page of resources.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a ReservedIPCollectionNext object.

        :param str href: The URL for a page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ReservedIPCollectionNext':
        """Initialize a ReservedIPCollectionNext object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in ReservedIPCollectionNext JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ReservedIPCollectionNext object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this ReservedIPCollectionNext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ReservedIPCollectionNext') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ReservedIPCollectionNext') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class ReservedIPPatch:
    """
    ReservedIPPatch.

    :attr bool auto_delete: (optional) Indicates whether this reserved IP member
          will be automatically deleted when either
          `target` is deleted, or the reserved IP is unbound. Must be `false` if the
          reserved IP is unbound.
    :attr str name: (optional) The name for this reserved IP. The name must not be
          used by another reserved IP in the subnet. Names starting with `ibm-` are
          reserved for provider-owned resources, and are not allowed.
    """

    def __init__(
        self,
        *,
        auto_delete: bool = None,
        name: str = None,
    ) -> None:
        """
        Initialize a ReservedIPPatch object.

        :param bool auto_delete: (optional) Indicates whether this reserved IP
               member will be automatically deleted when either
               `target` is deleted, or the reserved IP is unbound. Must be `false` if the
               reserved IP is unbound.
        :param str name: (optional) The name for this reserved IP. The name must
               not be used by another reserved IP in the subnet. Names starting with
               `ibm-` are reserved for provider-owned resources, and are not allowed.
        """
        self.auto_delete = auto_delete
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ReservedIPPatch':
        """Initialize a ReservedIPPatch object from a json dictionary."""
        args = {}
        if 'auto_delete' in _dict:
            args['auto_delete'] = _dict.get('auto_delete')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ReservedIPPatch object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'auto_delete') and self.auto_delete is not None:
            _dict['auto_delete'] = self.auto_delete
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this ReservedIPPatch object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ReservedIPPatch') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ReservedIPPatch') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class ReservedIPReference:
    """
    ReservedIPReference.

    :attr str address: The IP address.
          If the address has not yet been selected, the value will be `0.0.0.0`.
          This property may add support for IPv6 addresses in the future. When processing
          a value in this property, verify that the address is in an expected format. If
          it is not, log an error. Optionally halt processing and surface the error, or
          bypass the resource on which the unexpected IP address format was encountered.
    :attr ReservedIPReferenceDeleted deleted: (optional) If present, this property
          indicates the referenced resource has been deleted, and provides
          some supplementary information.
    :attr str href: The URL for this reserved IP.
    :attr str id: The unique identifier for this reserved IP.
    :attr str name: The name for this reserved IP. The name is unique across all
          reserved IPs in a subnet.
    :attr str resource_type: The resource type.
    """

    def __init__(
        self,
        address: str,
        href: str,
        id: str,
        name: str,
        resource_type: str,
        *,
        deleted: 'ReservedIPReferenceDeleted' = None,
    ) -> None:
        """
        Initialize a ReservedIPReference object.

        :param str address: The IP address.
               If the address has not yet been selected, the value will be `0.0.0.0`.
               This property may add support for IPv6 addresses in the future. When
               processing a value in this property, verify that the address is in an
               expected format. If it is not, log an error. Optionally halt processing and
               surface the error, or bypass the resource on which the unexpected IP
               address format was encountered.
        :param str href: The URL for this reserved IP.
        :param str id: The unique identifier for this reserved IP.
        :param str name: The name for this reserved IP. The name is unique across
               all reserved IPs in a subnet.
        :param str resource_type: The resource type.
        :param ReservedIPReferenceDeleted deleted: (optional) If present, this
               property indicates the referenced resource has been deleted, and provides
               some supplementary information.
        """
        self.address = address
        self.deleted = deleted
        self.href = href
        self.id = id
        self.name = name
        self.resource_type = resource_type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ReservedIPReference':
        """Initialize a ReservedIPReference object from a json dictionary."""
        args = {}
        if 'address' in _dict:
            args['address'] = _dict.get('address')
        else:
            raise ValueError('Required property \'address\' not present in ReservedIPReference JSON')
        if 'deleted' in _dict:
            args['deleted'] = ReservedIPReferenceDeleted.from_dict(_dict.get('deleted'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in ReservedIPReference JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in ReservedIPReference JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in ReservedIPReference JSON')
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError('Required property \'resource_type\' not present in ReservedIPReference JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ReservedIPReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'address') and self.address is not None:
            _dict['address'] = self.address
        if hasattr(self, 'deleted') and self.deleted is not None:
            if isinstance(self.deleted, dict):
                _dict['deleted'] = self.deleted
            else:
                _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'resource_type') and self.resource_type is not None:
            _dict['resource_type'] = self.resource_type
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this ReservedIPReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ReservedIPReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ReservedIPReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        SUBNET_RESERVED_IP = 'subnet_reserved_ip'



class ReservedIPReferenceDeleted:
    """
    If present, this property indicates the referenced resource has been deleted, and
    provides some supplementary information.

    :attr str more_info: Link to documentation about deleted resources.
    """

    def __init__(
        self,
        more_info: str,
    ) -> None:
        """
        Initialize a ReservedIPReferenceDeleted object.

        :param str more_info: Link to documentation about deleted resources.
        """
        self.more_info = more_info

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ReservedIPReferenceDeleted':
        """Initialize a ReservedIPReferenceDeleted object from a json dictionary."""
        args = {}
        if 'more_info' in _dict:
            args['more_info'] = _dict.get('more_info')
        else:
            raise ValueError('Required property \'more_info\' not present in ReservedIPReferenceDeleted JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ReservedIPReferenceDeleted object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'more_info') and self.more_info is not None:
            _dict['more_info'] = self.more_info
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this ReservedIPReferenceDeleted object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ReservedIPReferenceDeleted') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ReservedIPReferenceDeleted') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class ReservedIPTarget:
    """
    The target this reserved IP is bound to.
    If absent, this reserved IP is provider-owned or unbound.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a ReservedIPTarget object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['ReservedIPTargetEndpointGatewayReference', 'ReservedIPTargetVirtualNetworkInterfaceReferenceReservedIPTargetContext', 'ReservedIPTargetNetworkInterfaceReferenceTargetContext', 'ReservedIPTargetBareMetalServerNetworkInterfaceReferenceTargetContext', 'ReservedIPTargetLoadBalancerReference', 'ReservedIPTargetVPNGatewayReference', 'ReservedIPTargetVPNServerReference', 'ReservedIPTargetGenericResourceReference'])
        )
        raise Exception(msg)


class ReservedIPTargetPrototype:
    """
    The target to bind this reserved IP to.  The target must be in the same VPC.
    At present, only endpoint gateway targets are supported.  The endpoint gateway must
    not be already bound to a reserved IP in the subnet's zone.
    If unspecified, the reserved IP will be created unbound.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a ReservedIPTargetPrototype object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['ReservedIPTargetPrototypeEndpointGatewayIdentity'])
        )
        raise Exception(msg)


class ResourceFilter:
    """
    Identifies one or more resources according to the specified filter property.

    :attr str resource_type: (optional) The resource type.
    """

    def __init__(
        self,
        *,
        resource_type: str = None,
    ) -> None:
        """
        Initialize a ResourceFilter object.

        :param str resource_type: (optional) The resource type.
        """
        self.resource_type = resource_type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ResourceFilter':
        """Initialize a ResourceFilter object from a json dictionary."""
        args = {}
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ResourceFilter object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'resource_type') and self.resource_type is not None:
            _dict['resource_type'] = self.resource_type
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this ResourceFilter object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ResourceFilter') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ResourceFilter') -> 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) will be used.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a ResourceGroupIdentity object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['ResourceGroupIdentityById'])
        )
        raise Exception(msg)


class ResourceGroupReference:
    """
    ResourceGroupReference.

    :attr str href: The URL for this resource group.
    :attr str id: The unique identifier for this resource group.
    :attr str name: The name for this resource group.
    """

    def __init__(
        self,
        href: str,
        id: str,
        name: str,
    ) -> None:
        """
        Initialize a ResourceGroupReference object.

        :param str href: The URL for this resource group.
        :param str id: The unique identifier for this resource group.
        :param str name: The name for this resource group.
        """
        self.href = href
        self.id = id
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ResourceGroupReference':
        """Initialize a ResourceGroupReference object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in ResourceGroupReference JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in ResourceGroupReference JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in ResourceGroupReference JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ResourceGroupReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this ResourceGroupReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ResourceGroupReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ResourceGroupReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class Route:
    """
    Route.

    :attr str action: The action to perform with a packet matching the route:
          - `delegate`: delegate to system-provided routes
          - `delegate_vpc`: delegate to system-provided routes, ignoring Internet-bound
          routes
          - `deliver`: deliver the packet to the specified `next_hop`
          - `drop`: drop the packet.
    :attr datetime created_at: The date and time that the route was created.
    :attr RouteCreator creator: (optional) If present, the resource that created the
          route. Routes with this property present cannot
          be directly deleted. All routes with an `origin` of `service` will have this
          property set,
          and future `origin` values may also have this property set.
    :attr str destination: The destination CIDR 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 name for this route. The name is unique across all routes in
          the routing table.
    :attr RouteNextHop next_hop: If `action` is `deliver`, the next hop that packets
          will be delivered to.  For
          other `action` values, its `address` will be `0.0.0.0`.
    :attr str origin: (optional) The origin of this route:
          - `service`: route was directly created by a service
          - `user`: route was directly created by a user
          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 route on which the unexpected
          property value was encountered.
    :attr int priority: The priority of this route. Smaller values have higher
          priority.
          If a routing table contains multiple routes with the same `zone` and
          `destination`, the route with the highest priority (smallest value) is selected.
          If two routes have the same `destination` and `priority`, traffic is distributed
          between them.
    :attr ZoneReference zone: The zone the route applies to. (Traffic from subnets
          in this zone will be
          subject to this route.).
    """

    def __init__(
        self,
        action: str,
        created_at: datetime,
        destination: str,
        href: str,
        id: str,
        lifecycle_state: str,
        name: str,
        next_hop: 'RouteNextHop',
        priority: int,
        zone: 'ZoneReference',
        *,
        creator: 'RouteCreator' = None,
        origin: str = None,
    ) -> None:
        """
        Initialize a Route object.

        :param str action: The action to perform with a packet matching the route:
               - `delegate`: delegate to system-provided routes
               - `delegate_vpc`: delegate to system-provided routes, ignoring
               Internet-bound routes
               - `deliver`: deliver the packet to the specified `next_hop`
               - `drop`: drop the packet.
        :param datetime created_at: The date and time that the route was created.
        :param str destination: The destination CIDR 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 name for this route. The name is unique across all
               routes in the routing table.
        :param RouteNextHop next_hop: If `action` is `deliver`, the next hop that
               packets will be delivered to.  For
               other `action` values, its `address` will be `0.0.0.0`.
        :param int priority: The priority of this route. Smaller values have higher
               priority.
               If a routing table contains multiple routes with the same `zone` and
               `destination`, the route with the highest priority (smallest value) is
               selected. If two routes have the same `destination` and `priority`, traffic
               is distributed between them.
        :param ZoneReference zone: The zone the route applies to. (Traffic from
               subnets in this zone will be
               subject to this route.).
        """
        self.action = action
        self.created_at = created_at
        self.creator = creator
        self.destination = destination
        self.href = href
        self.id = id
        self.lifecycle_state = lifecycle_state
        self.name = name
        self.next_hop = next_hop
        self.origin = origin
        self.priority = priority
        self.zone = zone

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'Route':
        """Initialize a Route object from a json dictionary."""
        args = {}
        if 'action' in _dict:
            args['action'] = _dict.get('action')
        else:
            raise ValueError('Required property \'action\' not present in Route JSON')
        if 'created_at' in _dict:
            args['created_at'] = string_to_datetime(_dict.get('created_at'))
        else:
            raise ValueError('Required property \'created_at\' not present in Route JSON')
        if 'creator' in _dict:
            args['creator'] = _dict.get('creator')
        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 'origin' in _dict:
            args['origin'] = _dict.get('origin')
        if 'priority' in _dict:
            args['priority'] = _dict.get('priority')
        else:
            raise ValueError('Required property \'priority\' 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, '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, 'creator') and getattr(self, 'creator') is not None:
            if isinstance(getattr(self, 'creator'), dict):
                _dict['creator'] = getattr(self, 'creator')
            else:
                _dict['creator'] = getattr(self, 'creator').to_dict()
        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, 'origin') and getattr(self, 'origin') is not None:
            _dict['origin'] = getattr(self, 'origin')
        if hasattr(self, 'priority') and self.priority is not None:
            _dict['priority'] = self.priority
        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 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 ActionEnum(str, Enum):
        """
        The action to perform with a packet matching the route:
        - `delegate`: delegate to system-provided routes
        - `delegate_vpc`: delegate to system-provided routes, ignoring Internet-bound
        routes
        - `deliver`: deliver the packet to the specified `next_hop`
        - `drop`: drop the packet.
        """

        DELEGATE = 'delegate'
        DELEGATE_VPC = 'delegate_vpc'
        DELIVER = 'deliver'
        DROP = 'drop'


    class LifecycleStateEnum(str, Enum):
        """
        The lifecycle state of the route.
        """

        DELETING = 'deleting'
        FAILED = 'failed'
        PENDING = 'pending'
        STABLE = 'stable'
        SUSPENDED = 'suspended'
        UPDATING = 'updating'
        WAITING = 'waiting'


    class OriginEnum(str, Enum):
        """
        The origin of this route:
        - `service`: route was directly created by a service
        - `user`: route was directly created by a user
        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 route on which the unexpected
        property value was encountered.
        """

        SERVICE = 'service'
        USER = 'user'



class RouteCollection:
    """
    RouteCollection.

    :attr RouteCollectionFirst first: A link to the first page of resources.
    :attr int limit: The maximum number of resources that can be returned by the
          request.
    :attr RouteCollectionNext next: (optional) A link to the next page of resources.
          This property is present for all pages
          except the last page.
    :attr List[Route] routes: Collection of routes.
    :attr int total_count: The total number of resources across all pages.
    """

    def __init__(
        self,
        first: 'RouteCollectionFirst',
        limit: int,
        routes: List['Route'],
        total_count: int,
        *,
        next: 'RouteCollectionNext' = None,
    ) -> None:
        """
        Initialize a RouteCollection object.

        :param RouteCollectionFirst first: A link to the first page of resources.
        :param int limit: The maximum number of resources that can be returned by
               the request.
        :param List[Route] routes: Collection of routes.
        :param int total_count: The total number of resources across all pages.
        :param RouteCollectionNext next: (optional) A link to the next page of
               resources. This property is present for all pages
               except the last page.
        """
        self.first = first
        self.limit = limit
        self.next = next
        self.routes = routes
        self.total_count = total_count

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'RouteCollection':
        """Initialize a RouteCollection object from a json dictionary."""
        args = {}
        if 'first' in _dict:
            args['first'] = RouteCollectionFirst.from_dict(_dict.get('first'))
        else:
            raise ValueError('Required property \'first\' not present in RouteCollection JSON')
        if 'limit' in _dict:
            args['limit'] = _dict.get('limit')
        else:
            raise ValueError('Required property \'limit\' not present in RouteCollection JSON')
        if 'next' in _dict:
            args['next'] = RouteCollectionNext.from_dict(_dict.get('next'))
        if 'routes' in _dict:
            args['routes'] = [Route.from_dict(v) for v in _dict.get('routes')]
        else:
            raise ValueError('Required property \'routes\' not present in RouteCollection JSON')
        if 'total_count' in _dict:
            args['total_count'] = _dict.get('total_count')
        else:
            raise ValueError('Required property \'total_count\' not present in RouteCollection JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a RouteCollection object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'first') and self.first is not None:
            if isinstance(self.first, dict):
                _dict['first'] = self.first
            else:
                _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:
            if isinstance(self.next, dict):
                _dict['next'] = self.next
            else:
                _dict['next'] = self.next.to_dict()
        if hasattr(self, 'routes') and self.routes is not None:
            routes_list = []
            for v in self.routes:
                if isinstance(v, dict):
                    routes_list.append(v)
                else:
                    routes_list.append(v.to_dict())
            _dict['routes'] = routes_list
        if hasattr(self, 'total_count') and self.total_count is not None:
            _dict['total_count'] = self.total_count
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this RouteCollection object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'RouteCollection') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'RouteCollection') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class RouteCollectionFirst:
    """
    A link to the first page of resources.

    :attr str href: The URL for a page of resources.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a RouteCollectionFirst object.

        :param str href: The URL for a page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'RouteCollectionFirst':
        """Initialize a RouteCollectionFirst object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in RouteCollectionFirst JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a RouteCollectionFirst object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this RouteCollectionFirst object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'RouteCollectionFirst') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'RouteCollectionFirst') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class RouteCollectionNext:
    """
    A link to the next page of resources. This property is present for all pages except
    the last page.

    :attr str href: The URL for a page of resources.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a RouteCollectionNext object.

        :param str href: The URL for a page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'RouteCollectionNext':
        """Initialize a RouteCollectionNext object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in RouteCollectionNext JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a RouteCollectionNext object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this RouteCollectionNext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'RouteCollectionNext') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'RouteCollectionNext') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class RouteCollectionVPCContext:
    """
    RouteCollectionVPCContext.

    :attr RouteCollectionVPCContextFirst 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 RouteCollectionVPCContextNext next: (optional) A link to the next page of
          resources. This property is present for all pages
          except the last page.
    :attr List[RouteCollectionVPCContextRoutesItem] routes: Collection of routes.
    :attr int total_count: The total number of resources across all pages.
    """

    def __init__(
        self,
        first: 'RouteCollectionVPCContextFirst',
        limit: int,
        routes: List['RouteCollectionVPCContextRoutesItem'],
        total_count: int,
        *,
        next: 'RouteCollectionVPCContextNext' = None,
    ) -> None:
        """
        Initialize a RouteCollectionVPCContext object.

        :param RouteCollectionVPCContextFirst 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[RouteCollectionVPCContextRoutesItem] routes: Collection of
               routes.
        :param int total_count: The total number of resources across all pages.
        :param RouteCollectionVPCContextNext next: (optional) A link to the next
               page of resources. This property is present for all pages
               except the last page.
        """
        self.first = first
        self.limit = limit
        self.next = next
        self.routes = routes
        self.total_count = total_count

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'RouteCollectionVPCContext':
        """Initialize a RouteCollectionVPCContext object from a json dictionary."""
        args = {}
        if 'first' in _dict:
            args['first'] = RouteCollectionVPCContextFirst.from_dict(_dict.get('first'))
        else:
            raise ValueError('Required property \'first\' not present in RouteCollectionVPCContext JSON')
        if 'limit' in _dict:
            args['limit'] = _dict.get('limit')
        else:
            raise ValueError('Required property \'limit\' not present in RouteCollectionVPCContext JSON')
        if 'next' in _dict:
            args['next'] = RouteCollectionVPCContextNext.from_dict(_dict.get('next'))
        if 'routes' in _dict:
            args['routes'] = [RouteCollectionVPCContextRoutesItem.from_dict(v) for v in _dict.get('routes')]
        else:
            raise ValueError('Required property \'routes\' not present in RouteCollectionVPCContext JSON')
        if 'total_count' in _dict:
            args['total_count'] = _dict.get('total_count')
        else:
            raise ValueError('Required property \'total_count\' not present in RouteCollectionVPCContext JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a RouteCollectionVPCContext object from 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:
            if isinstance(self.first, dict):
                _dict['first'] = self.first
            else:
                _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:
            if isinstance(self.next, dict):
                _dict['next'] = self.next
            else:
                _dict['next'] = self.next.to_dict()
        if hasattr(self, 'routes') and self.routes is not None:
            routes_list = []
            for v in self.routes:
                if isinstance(v, dict):
                    routes_list.append(v)
                else:
                    routes_list.append(v.to_dict())
            _dict['routes'] = routes_list
        if hasattr(self, 'total_count') and self.total_count is not None:
            _dict['total_count'] = self.total_count
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this RouteCollectionVPCContext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'RouteCollectionVPCContext') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'RouteCollectionVPCContext') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class RouteCollectionVPCContextFirst:
    """
    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 RouteCollectionVPCContextFirst object.

        :param str href: The URL for a page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'RouteCollectionVPCContextFirst':
        """Initialize a RouteCollectionVPCContextFirst object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in RouteCollectionVPCContextFirst JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a RouteCollectionVPCContextFirst object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(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 RouteCollectionVPCContextFirst object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'RouteCollectionVPCContextFirst') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'RouteCollectionVPCContextFirst') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class RouteCollectionVPCContextNext:
    """
    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 RouteCollectionVPCContextNext object.

        :param str href: The URL for a page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'RouteCollectionVPCContextNext':
        """Initialize a RouteCollectionVPCContextNext object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in RouteCollectionVPCContextNext JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a RouteCollectionVPCContextNext object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(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 RouteCollectionVPCContextNext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'RouteCollectionVPCContextNext') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'RouteCollectionVPCContextNext') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class RouteCollectionVPCContextRoutesItem:
    """
    RouteCollectionVPCContextRoutesItem.

    :attr str action: The action to perform with a packet matching the route:
          - `delegate`: delegate to system-provided routes
          - `delegate_vpc`: delegate to system-provided routes, ignoring Internet-bound
          routes
          - `deliver`: deliver the packet to the specified `next_hop`
          - `drop`: drop the packet.
    :attr datetime created_at: The date and time that the route was created.
    :attr RouteCreator creator: (optional) If present, the resource that created the
          route. Routes with this property present cannot
          be directly deleted. All routes with an `origin` of `service` will have this
          property set,
          and future `origin` values may also have this property set.
    :attr str destination: The destination CIDR 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 name for this route. The name is unique across all routes in
          the routing table.
    :attr RouteNextHop next_hop: If `action` is `deliver`, the next hop that packets
          will be delivered to.  For
          other `action` values, its `address` will be `0.0.0.0`.
    :attr str origin: (optional) The origin of this route:
          - `service`: route was directly created by a service
          - `user`: route was directly created by a user
          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 route on which the unexpected
          property value was encountered.
    :attr int priority: The priority of this route. Smaller values have higher
          priority.
          If a routing table contains multiple routes with the same `zone` and
          `destination`, the route with the highest priority (smallest value) is selected.
          If two routes have the same `destination` and `priority`, traffic is distributed
          between them.
    :attr ZoneReference zone: The zone the route applies to. (Traffic from subnets
          in this zone will be
          subject to this route.).
    """

    def __init__(
        self,
        action: str,
        created_at: datetime,
        destination: str,
        href: str,
        id: str,
        lifecycle_state: str,
        name: str,
        next_hop: 'RouteNextHop',
        priority: int,
        zone: 'ZoneReference',
        *,
        creator: 'RouteCreator' = None,
        origin: str = None,
    ) -> None:
        """
        Initialize a RouteCollectionVPCContextRoutesItem object.

        :param str action: The action to perform with a packet matching the route:
               - `delegate`: delegate to system-provided routes
               - `delegate_vpc`: delegate to system-provided routes, ignoring
               Internet-bound routes
               - `deliver`: deliver the packet to the specified `next_hop`
               - `drop`: drop the packet.
        :param datetime created_at: The date and time that the route was created.
        :param str destination: The destination CIDR 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 name for this route. The name is unique across all
               routes in the routing table.
        :param RouteNextHop next_hop: If `action` is `deliver`, the next hop that
               packets will be delivered to.  For
               other `action` values, its `address` will be `0.0.0.0`.
        :param int priority: The priority of this route. Smaller values have higher
               priority.
               If a routing table contains multiple routes with the same `zone` and
               `destination`, the route with the highest priority (smallest value) is
               selected. If two routes have the same `destination` and `priority`, traffic
               is distributed between them.
        :param ZoneReference zone: The zone the route applies to. (Traffic from
               subnets in this zone will be
               subject to this route.).
        """
        self.action = action
        self.created_at = created_at
        self.creator = creator
        self.destination = destination
        self.href = href
        self.id = id
        self.lifecycle_state = lifecycle_state
        self.name = name
        self.next_hop = next_hop
        self.origin = origin
        self.priority = priority
        self.zone = zone

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'RouteCollectionVPCContextRoutesItem':
        """Initialize a RouteCollectionVPCContextRoutesItem object from a json dictionary."""
        args = {}
        if 'action' in _dict:
            args['action'] = _dict.get('action')
        else:
            raise ValueError('Required property \'action\' not present in RouteCollectionVPCContextRoutesItem 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 RouteCollectionVPCContextRoutesItem JSON')
        if 'creator' in _dict:
            args['creator'] = _dict.get('creator')
        if 'destination' in _dict:
            args['destination'] = _dict.get('destination')
        else:
            raise ValueError('Required property \'destination\' not present in RouteCollectionVPCContextRoutesItem JSON')
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in RouteCollectionVPCContextRoutesItem JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in RouteCollectionVPCContextRoutesItem JSON')
        if 'lifecycle_state' in _dict:
            args['lifecycle_state'] = _dict.get('lifecycle_state')
        else:
            raise ValueError('Required property \'lifecycle_state\' not present in RouteCollectionVPCContextRoutesItem JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in RouteCollectionVPCContextRoutesItem JSON')
        if 'next_hop' in _dict:
            args['next_hop'] = _dict.get('next_hop')
        else:
            raise ValueError('Required property \'next_hop\' not present in RouteCollectionVPCContextRoutesItem JSON')
        if 'origin' in _dict:
            args['origin'] = _dict.get('origin')
        if 'priority' in _dict:
            args['priority'] = _dict.get('priority')
        else:
            raise ValueError('Required property \'priority\' not present in RouteCollectionVPCContextRoutesItem JSON')
        if 'zone' in _dict:
            args['zone'] = ZoneReference.from_dict(_dict.get('zone'))
        else:
            raise ValueError('Required property \'zone\' not present in RouteCollectionVPCContextRoutesItem JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a RouteCollectionVPCContextRoutesItem object from 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, 'creator') and getattr(self, 'creator') is not None:
            if isinstance(getattr(self, 'creator'), dict):
                _dict['creator'] = getattr(self, 'creator')
            else:
                _dict['creator'] = getattr(self, 'creator').to_dict()
        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, 'origin') and getattr(self, 'origin') is not None:
            _dict['origin'] = getattr(self, 'origin')
        if hasattr(self, 'priority') and self.priority is not None:
            _dict['priority'] = self.priority
        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 RouteCollectionVPCContextRoutesItem object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'RouteCollectionVPCContextRoutesItem') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'RouteCollectionVPCContextRoutesItem') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ActionEnum(str, Enum):
        """
        The action to perform with a packet matching the route:
        - `delegate`: delegate to system-provided routes
        - `delegate_vpc`: delegate to system-provided routes, ignoring Internet-bound
        routes
        - `deliver`: deliver the packet to the specified `next_hop`
        - `drop`: drop the packet.
        """

        DELEGATE = 'delegate'
        DELEGATE_VPC = 'delegate_vpc'
        DELIVER = 'deliver'
        DROP = 'drop'


    class LifecycleStateEnum(str, Enum):
        """
        The lifecycle state of the route.
        """

        DELETING = 'deleting'
        FAILED = 'failed'
        PENDING = 'pending'
        STABLE = 'stable'
        SUSPENDED = 'suspended'
        UPDATING = 'updating'
        WAITING = 'waiting'


    class OriginEnum(str, Enum):
        """
        The origin of this route:
        - `service`: route was directly created by a service
        - `user`: route was directly created by a user
        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 route on which the unexpected
        property value was encountered.
        """

        SERVICE = 'service'
        USER = 'user'



class RouteCreator:
    """
    If present, the resource that created the route. Routes with this property present
    cannot be directly deleted. All routes with an `origin` of `service` will have this
    property set, and future `origin` values may also have this property set.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a RouteCreator object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['RouteCreatorVPNGatewayReference', 'RouteCreatorVPNServerReference'])
        )
        raise Exception(msg)


class RouteNextHop:
    """
    RouteNextHop.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a RouteNextHop object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['RouteNextHopIP', 'RouteNextHopVPNGatewayConnectionReference'])
        )
        raise Exception(msg)


class RouteNextHopPatch:
    """
    If `action` is `deliver`, the next hop that packets will be delivered to. For other
    `action` values, specify `0.0.0.0` or remove it by specifying `null`.
    At most two routes per `zone` in a table can have the same `destination` and
    `priority`, and only when each route has an `action` of `deliver` and `next_hop` is an
    IP address.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a RouteNextHopPatch object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['RouteNextHopPatchRouteNextHopIP', 'RouteNextHopPatchVPNGatewayConnectionIdentity'])
        )
        raise Exception(msg)


class RoutePatch:
    """
    RoutePatch.

    :attr str name: (optional) The name for this route. The name must not be used by
          another route in the routing table. Names starting with `ibm-` are reserved for
          system-provided routes, and are not allowed.
    :attr RouteNextHopPatch next_hop: (optional) If `action` is `deliver`, the next
          hop that packets will be delivered to. For other
          `action` values, specify `0.0.0.0` or remove it by specifying `null`.
          At most two routes per `zone` in a table can have the same `destination` and
          `priority`,
          and only when each route has an `action` of `deliver` and `next_hop` is an IP
          address.
    :attr int priority: (optional) The priority of this route. Smaller values have
          higher priority.
          If a routing table contains multiple routes with the same `zone` and
          `destination`, the route with the highest priority (smallest value) is selected.
          If two routes have the same `destination` and `priority`, traffic is distributed
          between them.
    """

    def __init__(
        self,
        *,
        name: str = None,
        next_hop: 'RouteNextHopPatch' = None,
        priority: int = None,
    ) -> None:
        """
        Initialize a RoutePatch object.

        :param str name: (optional) The name for this route. The name must not be
               used by another route in the routing table. Names starting with `ibm-` are
               reserved for system-provided routes, and are not allowed.
        :param RouteNextHopPatch next_hop: (optional) If `action` is `deliver`, the
               next hop that packets will be delivered to. For other
               `action` values, specify `0.0.0.0` or remove it by specifying `null`.
               At most two routes per `zone` in a table can have the same `destination`
               and `priority`,
               and only when each route has an `action` of `deliver` and `next_hop` is an
               IP address.
        :param int priority: (optional) The priority of this route. Smaller values
               have higher priority.
               If a routing table contains multiple routes with the same `zone` and
               `destination`, the route with the highest priority (smallest value) is
               selected. If two routes have the same `destination` and `priority`, traffic
               is distributed between them.
        """
        self.name = name
        self.next_hop = next_hop
        self.priority = priority

    @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')
        if 'next_hop' in _dict:
            args['next_hop'] = _dict.get('next_hop')
        if 'priority' in _dict:
            args['priority'] = _dict.get('priority')
        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
        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, 'priority') and self.priority is not None:
            _dict['priority'] = self.priority
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this RoutePatch object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'RoutePatch') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'RoutePatch') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class RoutePrototype:
    """
    RoutePrototype.

    :attr str action: (optional) The action to perform with a packet matching the
          route:
          - `delegate`: delegate to system-provided routes
          - `delegate_vpc`: delegate to system-provided routes, ignoring Internet-bound
          routes
          - `deliver`: deliver the packet to the specified `next_hop`
          - `drop`: drop the packet.
    :attr str destination: The destination CIDR of the route. The host identifier in
          the CIDR must be zero.
          At most two routes per `zone` in a table can have the same `destination` and
          `priority`, and only if both routes have an `action` of `deliver` and the
          `next_hop` is an IP address.
    :attr str name: (optional) The name for this route. The name must not be used by
          another route in the routing table. Names starting with `ibm-` are reserved for
          system-provided routes, and are not allowed. If unspecified, the name will be a
          hyphenated list of randomly-selected words.
    :attr RoutePrototypeNextHop next_hop: (optional) If `action` is `deliver`, the
          next hop that packets will be delivered to. For other
          `action` values, it must be omitted or specified as `0.0.0.0`.
          At most two routes per `zone` in a table can have the same `destination` and
          `priority`,
          and only when each route has an `action` of `deliver` and `next_hop` is an IP
          address.
    :attr int priority: (optional) The priority of this route. Smaller values have
          higher priority.
          If a routing table contains multiple routes with the same `zone` and
          `destination`, the route with the highest priority (smallest value) is selected.
          If two routes have the same `destination` and `priority`, traffic is distributed
          between them.
    :attr ZoneIdentity zone: The zone to apply the route to. (Traffic from subnets
          in this zone will be
          subject to this route.).
    """

    def __init__(
        self,
        destination: str,
        zone: 'ZoneIdentity',
        *,
        action: str = None,
        name: str = None,
        next_hop: 'RoutePrototypeNextHop' = None,
        priority: int = None,
    ) -> None:
        """
        Initialize a RoutePrototype object.

        :param str destination: The destination CIDR of the route. The host
               identifier in the CIDR must be zero.
               At most two routes per `zone` in a table can have the same `destination`
               and
               `priority`, and only if both routes have an `action` of `deliver` and the
               `next_hop` is an IP address.
        :param ZoneIdentity zone: The zone to apply the route to. (Traffic from
               subnets in this zone will be
               subject to this route.).
        :param str action: (optional) The action to perform with a packet matching
               the route:
               - `delegate`: delegate to system-provided routes
               - `delegate_vpc`: delegate to system-provided routes, ignoring
               Internet-bound routes
               - `deliver`: deliver the packet to the specified `next_hop`
               - `drop`: drop the packet.
        :param str name: (optional) The name for this route. The name must not be
               used by another route in the routing table. Names starting with `ibm-` are
               reserved for system-provided routes, and are not allowed. If unspecified,
               the name will be a hyphenated list of randomly-selected words.
        :param RoutePrototypeNextHop next_hop: (optional) If `action` is `deliver`,
               the next hop that packets will be delivered to. For other
               `action` values, it must be omitted or specified as `0.0.0.0`.
               At most two routes per `zone` in a table can have the same `destination`
               and `priority`,
               and only when each route has an `action` of `deliver` and `next_hop` is an
               IP address.
        :param int priority: (optional) The priority of this route. Smaller values
               have higher priority.
               If a routing table contains multiple routes with the same `zone` and
               `destination`, the route with the highest priority (smallest value) is
               selected. If two routes have the same `destination` and `priority`, traffic
               is distributed between them.
        """
        self.action = action
        self.destination = destination
        self.name = name
        self.next_hop = next_hop
        self.priority = priority
        self.zone = zone

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'RoutePrototype':
        """Initialize a RoutePrototype object from a json dictionary."""
        args = {}
        if 'action' in _dict:
            args['action'] = _dict.get('action')
        if 'destination' in _dict:
            args['destination'] = _dict.get('destination')
        else:
            raise ValueError('Required property \'destination\' not present in RoutePrototype JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        if 'next_hop' in _dict:
            args['next_hop'] = _dict.get('next_hop')
        if 'priority' in _dict:
            args['priority'] = _dict.get('priority')
        if 'zone' in _dict:
            args['zone'] = _dict.get('zone')
        else:
            raise ValueError('Required property \'zone\' not present in RoutePrototype JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a RoutePrototype object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'action') and self.action is not None:
            _dict['action'] = self.action
        if hasattr(self, 'destination') and self.destination is not None:
            _dict['destination'] = self.destination
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'next_hop') and self.next_hop is not None:
            if isinstance(self.next_hop, dict):
                _dict['next_hop'] = self.next_hop
            else:
                _dict['next_hop'] = self.next_hop.to_dict()
        if hasattr(self, 'priority') and self.priority is not None:
            _dict['priority'] = self.priority
        if hasattr(self, 'zone') and self.zone is not None:
            if isinstance(self.zone, dict):
                _dict['zone'] = self.zone
            else:
                _dict['zone'] = self.zone.to_dict()
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this RoutePrototype object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'RoutePrototype') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'RoutePrototype') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ActionEnum(str, Enum):
        """
        The action to perform with a packet matching the route:
        - `delegate`: delegate to system-provided routes
        - `delegate_vpc`: delegate to system-provided routes, ignoring Internet-bound
        routes
        - `deliver`: deliver the packet to the specified `next_hop`
        - `drop`: drop the packet.
        """

        DELEGATE = 'delegate'
        DELEGATE_VPC = 'delegate_vpc'
        DELIVER = 'deliver'
        DROP = 'drop'



class RoutePrototypeNextHop:
    """
    If `action` is `deliver`, the next hop that packets will be delivered to. For other
    `action` values, it must be omitted or specified as `0.0.0.0`.
    At most two routes per `zone` in a table can have the same `destination` and
    `priority`, and only when each route has an `action` of `deliver` and `next_hop` is an
    IP address.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a RoutePrototypeNextHop object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['RoutePrototypeNextHopRouteNextHopPrototypeRouteNextHopIP', 'RoutePrototypeNextHopRouteNextHopPrototypeVPNGatewayConnectionIdentity'])
        )
        raise Exception(msg)


class RouteReference:
    """
    RouteReference.

    :attr RouteReferenceDeleted deleted: (optional) If present, this property
          indicates the referenced resource has been deleted, and provides
          some supplementary information.
    :attr str href: The URL for this route.
    :attr str id: The unique identifier for this route.
    :attr str name: The name for this route. The name is unique across all routes in
          the routing table.
    """

    def __init__(
        self,
        href: str,
        id: str,
        name: str,
        *,
        deleted: 'RouteReferenceDeleted' = None,
    ) -> None:
        """
        Initialize a RouteReference object.

        :param str href: The URL for this route.
        :param str id: The unique identifier for this route.
        :param str name: The name for this route. The name is unique across all
               routes in the routing table.
        :param RouteReferenceDeleted deleted: (optional) If present, this property
               indicates the referenced resource has been deleted, and provides
               some supplementary information.
        """
        self.deleted = deleted
        self.href = href
        self.id = id
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'RouteReference':
        """Initialize a RouteReference object from a json dictionary."""
        args = {}
        if 'deleted' in _dict:
            args['deleted'] = RouteReferenceDeleted.from_dict(_dict.get('deleted'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in RouteReference JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in RouteReference JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in RouteReference JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a RouteReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'deleted') and self.deleted is not None:
            if isinstance(self.deleted, dict):
                _dict['deleted'] = self.deleted
            else:
                _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this RouteReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'RouteReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'RouteReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class RouteReferenceDeleted:
    """
    If present, this property indicates the referenced resource has been deleted, and
    provides some supplementary information.

    :attr str more_info: Link to documentation about deleted resources.
    """

    def __init__(
        self,
        more_info: str,
    ) -> None:
        """
        Initialize a RouteReferenceDeleted object.

        :param str more_info: Link to documentation about deleted resources.
        """
        self.more_info = more_info

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'RouteReferenceDeleted':
        """Initialize a RouteReferenceDeleted object from a json dictionary."""
        args = {}
        if 'more_info' in _dict:
            args['more_info'] = _dict.get('more_info')
        else:
            raise ValueError('Required property \'more_info\' not present in RouteReferenceDeleted JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a RouteReferenceDeleted object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'more_info') and self.more_info is not None:
            _dict['more_info'] = self.more_info
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this RouteReferenceDeleted object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'RouteReferenceDeleted') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'RouteReferenceDeleted') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class RoutingTable:
    """
    RoutingTable.

    :attr List[ResourceFilter] accept_routes_from: The filters specifying the
          resources that may create routes in this routing table.
          At present, only the `resource_type` filter is permitted, and only the
          `vpn_server` value is supported, but filter support is expected to expand in the
          future.
    :attr datetime created_at: The date and time that this routing table was
          created.
    :attr str href: The URL for this routing table.
    :attr str id: The unique identifier for this routing table.
    :attr bool is_default: Indicates whether this is the default routing table for
          this VPC.
    :attr str lifecycle_state: The lifecycle state of the routing table.
    :attr str name: The name for this routing table. The name is unique across all
          routing tables for the VPC.
    :attr str resource_type: The resource type.
    :attr bool route_direct_link_ingress: Indicates whether this routing table is
          used to route traffic that originates from
          [Direct Link](https://cloud.ibm.com/docs/dl) to this VPC.
          Incoming traffic will be routed according to the routing table with one
          exception: routes with an `action` of `deliver` are treated as `drop` unless the
          `next_hop` is an IP address in a subnet in the route's `zone` that is able to
          accept traffic. Therefore, if an incoming packet matches a route with a
          `next_hop` of a VPN gateway connection, the packet will be dropped.
    :attr bool route_internet_ingress: Indicates whether this routing table is used
          to route traffic that originates from the internet.
          Incoming traffic will be routed according to the routing table with two
          exceptions:
          - Traffic destined for IP addresses associated with public gateways will not be
            subject to routes in this routing table.
          - Routes with an `action` of `deliver` are treated as `drop` unless the
          `next_hop` is
            an IP address in a subnet in the route's `zone` that is able to accept
          traffic.
            Therefore, if an incoming packet matches a route with a `next_hop` of a VPN
          gateway
            connection, the packet will be dropped.
    :attr bool route_transit_gateway_ingress: Indicates whether this routing table
          is used to route traffic that originates from from [Transit
          Gateway](https://cloud.ibm.com/docs/transit-gateway) to this VPC.
          Incoming traffic will be routed according to the routing table with one
          exception: routes with an `action` of `deliver` are treated as `drop` unless the
          `next_hop` is an IP address in a subnet in the route's `zone` that is able to
          accept traffic. Therefore, if an incoming packet matches a route with a
          `next_hop` of a VPN gateway connection, the packet will be dropped.
    :attr bool route_vpc_zone_ingress: Indicates whether this routing table is used
          to route traffic that originates from subnets in other zones in this VPC.
          Incoming traffic will be routed according to the routing table with one
          exception: routes with an `action` of `deliver` are treated as `drop` unless the
          `next_hop` is an IP address in a subnet in the route's `zone` that is able to
          accept traffic. Therefore, if an incoming packet matches a route with a
          `next_hop` of a VPN gateway connection, the packet will be dropped.
    :attr List[RouteReference] routes: The routes for this routing table.
    :attr List[SubnetReference] subnets: The subnets to which this routing table is
          attached.
    """

    def __init__(
        self,
        accept_routes_from: List['ResourceFilter'],
        created_at: datetime,
        href: str,
        id: str,
        is_default: bool,
        lifecycle_state: str,
        name: str,
        resource_type: str,
        route_direct_link_ingress: bool,
        route_internet_ingress: bool,
        route_transit_gateway_ingress: bool,
        route_vpc_zone_ingress: bool,
        routes: List['RouteReference'],
        subnets: List['SubnetReference'],
    ) -> None:
        """
        Initialize a RoutingTable object.

        :param List[ResourceFilter] accept_routes_from: The filters specifying the
               resources that may create routes in this routing table.
               At present, only the `resource_type` filter is permitted, and only the
               `vpn_server` value is supported, but filter support is expected to expand
               in the future.
        :param datetime created_at: The date and time that this routing table was
               created.
        :param str href: The URL for this routing table.
        :param str id: The unique identifier for this routing table.
        :param bool is_default: Indicates whether this is the default routing table
               for this VPC.
        :param str lifecycle_state: The lifecycle state of the routing table.
        :param str name: The name for this routing table. The name is unique across
               all routing tables for the VPC.
        :param str resource_type: The resource type.
        :param bool route_direct_link_ingress: Indicates whether this routing table
               is used to route traffic that originates from
               [Direct Link](https://cloud.ibm.com/docs/dl) to this VPC.
               Incoming traffic will be routed according to the routing table with one
               exception: routes with an `action` of `deliver` are treated as `drop`
               unless the `next_hop` is an IP address in a subnet in the route's `zone`
               that is able to accept traffic. Therefore, if an incoming packet matches a
               route with a `next_hop` of a VPN gateway connection, the packet will be
               dropped.
        :param bool route_internet_ingress: Indicates whether this routing table is
               used to route traffic that originates from the internet.
               Incoming traffic will be routed according to the routing table with two
               exceptions:
               - Traffic destined for IP addresses associated with public gateways will
               not be
                 subject to routes in this routing table.
               - Routes with an `action` of `deliver` are treated as `drop` unless the
               `next_hop` is
                 an IP address in a subnet in the route's `zone` that is able to accept
               traffic.
                 Therefore, if an incoming packet matches a route with a `next_hop` of a
               VPN gateway
                 connection, the packet will be dropped.
        :param bool route_transit_gateway_ingress: Indicates whether this routing
               table is used to route traffic that originates from from [Transit
               Gateway](https://cloud.ibm.com/docs/transit-gateway) to this VPC.
               Incoming traffic will be routed according to the routing table with one
               exception: routes with an `action` of `deliver` are treated as `drop`
               unless the `next_hop` is an IP address in a subnet in the route's `zone`
               that is able to accept traffic. Therefore, if an incoming packet matches a
               route with a `next_hop` of a VPN gateway connection, the packet will be
               dropped.
        :param bool route_vpc_zone_ingress: Indicates whether this routing table is
               used to route traffic that originates from subnets in other zones in this
               VPC.
               Incoming traffic will be routed according to the routing table with one
               exception: routes with an `action` of `deliver` are treated as `drop`
               unless the `next_hop` is an IP address in a subnet in the route's `zone`
               that is able to accept traffic. Therefore, if an incoming packet matches a
               route with a `next_hop` of a VPN gateway connection, the packet will be
               dropped.
        :param List[RouteReference] routes: The routes for this routing table.
        :param List[SubnetReference] subnets: The subnets to which this routing
               table is attached.
        """
        self.accept_routes_from = accept_routes_from
        self.created_at = created_at
        self.href = href
        self.id = id
        self.is_default = is_default
        self.lifecycle_state = lifecycle_state
        self.name = name
        self.resource_type = resource_type
        self.route_direct_link_ingress = route_direct_link_ingress
        self.route_internet_ingress = route_internet_ingress
        self.route_transit_gateway_ingress = route_transit_gateway_ingress
        self.route_vpc_zone_ingress = route_vpc_zone_ingress
        self.routes = routes
        self.subnets = subnets

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'RoutingTable':
        """Initialize a RoutingTable object from a json dictionary."""
        args = {}
        if 'accept_routes_from' in _dict:
            args['accept_routes_from'] = [ResourceFilter.from_dict(v) for v in _dict.get('accept_routes_from')]
        else:
            raise ValueError('Required property \'accept_routes_from\' not present in RoutingTable 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 RoutingTable JSON')
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in RoutingTable JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in RoutingTable JSON')
        if 'is_default' in _dict:
            args['is_default'] = _dict.get('is_default')
        else:
            raise ValueError('Required property \'is_default\' not present in RoutingTable JSON')
        if 'lifecycle_state' in _dict:
            args['lifecycle_state'] = _dict.get('lifecycle_state')
        else:
            raise ValueError('Required property \'lifecycle_state\' not present in RoutingTable JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in RoutingTable JSON')
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError('Required property \'resource_type\' not present in RoutingTable JSON')
        if 'route_direct_link_ingress' in _dict:
            args['route_direct_link_ingress'] = _dict.get('route_direct_link_ingress')
        else:
            raise ValueError('Required property \'route_direct_link_ingress\' not present in RoutingTable JSON')
        if 'route_internet_ingress' in _dict:
            args['route_internet_ingress'] = _dict.get('route_internet_ingress')
        else:
            raise ValueError('Required property \'route_internet_ingress\' not present in RoutingTable JSON')
        if 'route_transit_gateway_ingress' in _dict:
            args['route_transit_gateway_ingress'] = _dict.get('route_transit_gateway_ingress')
        else:
            raise ValueError('Required property \'route_transit_gateway_ingress\' not present in RoutingTable JSON')
        if 'route_vpc_zone_ingress' in _dict:
            args['route_vpc_zone_ingress'] = _dict.get('route_vpc_zone_ingress')
        else:
            raise ValueError('Required property \'route_vpc_zone_ingress\' not present in RoutingTable JSON')
        if 'routes' in _dict:
            args['routes'] = [RouteReference.from_dict(v) for v in _dict.get('routes')]
        else:
            raise ValueError('Required property \'routes\' not present in RoutingTable JSON')
        if 'subnets' in _dict:
            args['subnets'] = [SubnetReference.from_dict(v) for v in _dict.get('subnets')]
        else:
            raise ValueError('Required property \'subnets\' not present in RoutingTable JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a RoutingTable object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'accept_routes_from') and self.accept_routes_from is not None:
            accept_routes_from_list = []
            for v in self.accept_routes_from:
                if isinstance(v, dict):
                    accept_routes_from_list.append(v)
                else:
                    accept_routes_from_list.append(v.to_dict())
            _dict['accept_routes_from'] = accept_routes_from_list
        if hasattr(self, 'created_at') and self.created_at is not None:
            _dict['created_at'] = datetime_to_string(self.created_at)
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'is_default') and self.is_default is not None:
            _dict['is_default'] = self.is_default
        if hasattr(self, 'lifecycle_state') and self.lifecycle_state is not None:
            _dict['lifecycle_state'] = self.lifecycle_state
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'resource_type') and self.resource_type is not None:
            _dict['resource_type'] = self.resource_type
        if hasattr(self, 'route_direct_link_ingress') and self.route_direct_link_ingress is not None:
            _dict['route_direct_link_ingress'] = self.route_direct_link_ingress
        if hasattr(self, 'route_internet_ingress') and self.route_internet_ingress is not None:
            _dict['route_internet_ingress'] = self.route_internet_ingress
        if hasattr(self, 'route_transit_gateway_ingress') and self.route_transit_gateway_ingress is not None:
            _dict['route_transit_gateway_ingress'] = self.route_transit_gateway_ingress
        if hasattr(self, 'route_vpc_zone_ingress') and self.route_vpc_zone_ingress is not None:
            _dict['route_vpc_zone_ingress'] = self.route_vpc_zone_ingress
        if hasattr(self, 'routes') and self.routes is not None:
            routes_list = []
            for v in self.routes:
                if isinstance(v, dict):
                    routes_list.append(v)
                else:
                    routes_list.append(v.to_dict())
            _dict['routes'] = routes_list
        if hasattr(self, 'subnets') and self.subnets is not None:
            subnets_list = []
            for v in self.subnets:
                if isinstance(v, dict):
                    subnets_list.append(v)
                else:
                    subnets_list.append(v.to_dict())
            _dict['subnets'] = subnets_list
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this RoutingTable object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'RoutingTable') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'RoutingTable') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class LifecycleStateEnum(str, Enum):
        """
        The lifecycle state of the routing table.
        """

        DELETING = 'deleting'
        FAILED = 'failed'
        PENDING = 'pending'
        STABLE = 'stable'
        SUSPENDED = 'suspended'
        UPDATING = 'updating'
        WAITING = 'waiting'


    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        ROUTING_TABLE = 'routing_table'



class RoutingTableCollection:
    """
    RoutingTableCollection.

    :attr RoutingTableCollectionFirst first: A link to the first page of resources.
    :attr int limit: The maximum number of resources that can be returned by the
          request.
    :attr RoutingTableCollectionNext next: (optional) A link to the next page of
          resources. This property is present for all pages
          except the last page.
    :attr List[RoutingTable] routing_tables: Collection of routing tables.
    :attr int total_count: The total number of resources across all pages.
    """

    def __init__(
        self,
        first: 'RoutingTableCollectionFirst',
        limit: int,
        routing_tables: List['RoutingTable'],
        total_count: int,
        *,
        next: 'RoutingTableCollectionNext' = None,
    ) -> None:
        """
        Initialize a RoutingTableCollection object.

        :param RoutingTableCollectionFirst first: A link to the first page of
               resources.
        :param int limit: The maximum number of resources that can be returned by
               the request.
        :param List[RoutingTable] routing_tables: Collection of routing tables.
        :param int total_count: The total number of resources across all pages.
        :param RoutingTableCollectionNext next: (optional) A link to the next page
               of resources. This property is present for all pages
               except the last page.
        """
        self.first = first
        self.limit = limit
        self.next = next
        self.routing_tables = routing_tables
        self.total_count = total_count

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'RoutingTableCollection':
        """Initialize a RoutingTableCollection object from a json dictionary."""
        args = {}
        if 'first' in _dict:
            args['first'] = RoutingTableCollectionFirst.from_dict(_dict.get('first'))
        else:
            raise ValueError('Required property \'first\' not present in RoutingTableCollection JSON')
        if 'limit' in _dict:
            args['limit'] = _dict.get('limit')
        else:
            raise ValueError('Required property \'limit\' not present in RoutingTableCollection JSON')
        if 'next' in _dict:
            args['next'] = RoutingTableCollectionNext.from_dict(_dict.get('next'))
        if 'routing_tables' in _dict:
            args['routing_tables'] = [RoutingTable.from_dict(v) for v in _dict.get('routing_tables')]
        else:
            raise ValueError('Required property \'routing_tables\' not present in RoutingTableCollection JSON')
        if 'total_count' in _dict:
            args['total_count'] = _dict.get('total_count')
        else:
            raise ValueError('Required property \'total_count\' not present in RoutingTableCollection JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a RoutingTableCollection object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'first') and self.first is not None:
            if isinstance(self.first, dict):
                _dict['first'] = self.first
            else:
                _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:
            if isinstance(self.next, dict):
                _dict['next'] = self.next
            else:
                _dict['next'] = self.next.to_dict()
        if hasattr(self, 'routing_tables') and self.routing_tables is not None:
            routing_tables_list = []
            for v in self.routing_tables:
                if isinstance(v, dict):
                    routing_tables_list.append(v)
                else:
                    routing_tables_list.append(v.to_dict())
            _dict['routing_tables'] = routing_tables_list
        if hasattr(self, 'total_count') and self.total_count is not None:
            _dict['total_count'] = self.total_count
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this RoutingTableCollection object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'RoutingTableCollection') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'RoutingTableCollection') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class RoutingTableCollectionFirst:
    """
    A link to the first page of resources.

    :attr str href: The URL for a page of resources.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a RoutingTableCollectionFirst object.

        :param str href: The URL for a page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'RoutingTableCollectionFirst':
        """Initialize a RoutingTableCollectionFirst object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in RoutingTableCollectionFirst JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a RoutingTableCollectionFirst object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this RoutingTableCollectionFirst object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'RoutingTableCollectionFirst') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'RoutingTableCollectionFirst') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class RoutingTableCollectionNext:
    """
    A link to the next page of resources. This property is present for all pages except
    the last page.

    :attr str href: The URL for a page of resources.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a RoutingTableCollectionNext object.

        :param str href: The URL for a page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'RoutingTableCollectionNext':
        """Initialize a RoutingTableCollectionNext object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in RoutingTableCollectionNext JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a RoutingTableCollectionNext object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this RoutingTableCollectionNext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'RoutingTableCollectionNext') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'RoutingTableCollectionNext') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class RoutingTableIdentity:
    """
    Identifies a routing table by a unique property.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a RoutingTableIdentity object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['RoutingTableIdentityById', 'RoutingTableIdentityByHref'])
        )
        raise Exception(msg)


class RoutingTablePatch:
    """
    RoutingTablePatch.

    :attr List[ResourceFilter] accept_routes_from: (optional) The filters specifying
          the resources that may create routes in this routing table
          (replacing any existing filters). All routes created by resources that match a
          given filter will be removed when an existing filter is removed. Therefore, if
          an empty array is specified, all filters will be removed, resulting in all
          routes not directly created by the user being removed.
          At present, only the `resource_type` filter is permitted, and only the
          `vpn_server` value is supported, but filter support is expected to expand in the
          future.
    :attr str name: (optional) The name for this routing table. The name must not be
          used by another routing table in the VPC.
    :attr bool route_direct_link_ingress: (optional) Indicates whether this routing
          table is used to route traffic that originates from
          [Direct Link](https://cloud.ibm.com/docs/dl/) to this VPC. Updating to `true`
          selects this routing table, provided no other routing table in the VPC already
          has this property set to `true`, and no subnets are attached to this routing
          table. Updating to
          `false` deselects this routing table.
          Incoming traffic will be routed according to the routing table with one
          exception: routes with an `action` of `deliver` are treated as `drop` unless the
          `next_hop` is an IP address in a subnet in the route's `zone` that is able to
          accept traffic. Therefore, if an incoming packet matches a route with a
          `next_hop` of a VPN gateway connection, the packet will be dropped.
    :attr bool route_internet_ingress: (optional) Indicates whether this routing
          table is used to route traffic that originates from the internet.  Updating to
          `true` selects this routing table, provided no other routing table in the VPC
          already has this property set to `true`.  Updating to `false` deselects this
          routing table.
          Incoming traffic will be routed according to the routing table with two
          exceptions:
          -  Traffic destined for IP addresses associated with public gateways will not be
          subject
             to routes in this routing table.
          -  Routes with an `action` of `deliver` are treated as `drop` unless the
          `next_hop` is an
             IP address in a subnet in the route's `zone` that is able to accept traffic.
             Therefore, if an incoming packet matches a route with a `next_hop` of a VPN
          gateway
             connection, the packet will be dropped.
    :attr bool route_transit_gateway_ingress: (optional) Indicates whether this
          routing table is used to route traffic that originates from
          [Transit Gateway](https://cloud.ibm.com/docs/transit-gateway) to this VPC.
          Updating to
          `true` selects this routing table, provided no other routing table in the VPC
          already has this property set to `true`, and no subnets are attached to this
          routing table. Updating to `false` deselects this routing table.
          Incoming traffic will be routed according to the routing table with one
          exception: routes with an `action` of `deliver` are treated as `drop` unless the
          `next_hop` is an IP address in a subnet in the route's `zone` that is able to
          accept traffic. Therefore, if an incoming packet matches a route with a
          `next_hop` of a VPN gateway connection, the packet will be dropped.
          If [Classic
          Access](https://cloud.ibm.com/docs/vpc?topic=vpc-setting-up-access-to-classic-infrastructure)
          is enabled for this VPC, and this property is set to `true`, its incoming
          traffic will also be routed according to this routing table.
    :attr bool route_vpc_zone_ingress: (optional) Indicates whether this routing
          table is used to route traffic that originates from subnets in other zones in
          this VPC. Updating to `true` selects this routing table, provided no other
          routing table in the VPC already has this property set to `true`, and no subnets
          are attached to this routing table. Updating to `false` deselects this routing
          table.
          Incoming traffic will be routed according to the routing table with one
          exception: routes with an `action` of `deliver` are treated as `drop` unless the
          `next_hop` is an IP address in a subnet in the route's `zone` that is able to
          accept traffic. Therefore, if an incoming packet matches a route with a
          `next_hop` of a VPN gateway connection, the packet will be dropped.
    """

    def __init__(
        self,
        *,
        accept_routes_from: List['ResourceFilter'] = None,
        name: str = None,
        route_direct_link_ingress: bool = None,
        route_internet_ingress: bool = None,
        route_transit_gateway_ingress: bool = None,
        route_vpc_zone_ingress: bool = None,
    ) -> None:
        """
        Initialize a RoutingTablePatch object.

        :param List[ResourceFilter] accept_routes_from: (optional) The filters
               specifying the resources that may create routes in this routing table
               (replacing any existing filters). All routes created by resources that
               match a given filter will be removed when an existing filter is removed.
               Therefore, if an empty array is specified, all filters will be removed,
               resulting in all routes not directly created by the user being removed.
               At present, only the `resource_type` filter is permitted, and only the
               `vpn_server` value is supported, but filter support is expected to expand
               in the future.
        :param str name: (optional) The name for this routing table. The name must
               not be used by another routing table in the VPC.
        :param bool route_direct_link_ingress: (optional) Indicates whether this
               routing table is used to route traffic that originates from
               [Direct Link](https://cloud.ibm.com/docs/dl/) to this VPC. Updating to
               `true` selects this routing table, provided no other routing table in the
               VPC already has this property set to `true`, and no subnets are attached to
               this routing table. Updating to
               `false` deselects this routing table.
               Incoming traffic will be routed according to the routing table with one
               exception: routes with an `action` of `deliver` are treated as `drop`
               unless the `next_hop` is an IP address in a subnet in the route's `zone`
               that is able to accept traffic. Therefore, if an incoming packet matches a
               route with a `next_hop` of a VPN gateway connection, the packet will be
               dropped.
        :param bool route_internet_ingress: (optional) Indicates whether this
               routing table is used to route traffic that originates from the internet.
               Updating to `true` selects this routing table, provided no other routing
               table in the VPC already has this property set to `true`.  Updating to
               `false` deselects this routing table.
               Incoming traffic will be routed according to the routing table with two
               exceptions:
               -  Traffic destined for IP addresses associated with public gateways will
               not be subject
                  to routes in this routing table.
               -  Routes with an `action` of `deliver` are treated as `drop` unless the
               `next_hop` is an
                  IP address in a subnet in the route's `zone` that is able to accept
               traffic.
                  Therefore, if an incoming packet matches a route with a `next_hop` of a
               VPN gateway
                  connection, the packet will be dropped.
        :param bool route_transit_gateway_ingress: (optional) Indicates whether
               this routing table is used to route traffic that originates from
               [Transit Gateway](https://cloud.ibm.com/docs/transit-gateway) to this VPC.
               Updating to
               `true` selects this routing table, provided no other routing table in the
               VPC already has this property set to `true`, and no subnets are attached to
               this routing table. Updating to `false` deselects this routing table.
               Incoming traffic will be routed according to the routing table with one
               exception: routes with an `action` of `deliver` are treated as `drop`
               unless the `next_hop` is an IP address in a subnet in the route's `zone`
               that is able to accept traffic. Therefore, if an incoming packet matches a
               route with a `next_hop` of a VPN gateway connection, the packet will be
               dropped.
               If [Classic
               Access](https://cloud.ibm.com/docs/vpc?topic=vpc-setting-up-access-to-classic-infrastructure)
               is enabled for this VPC, and this property is set to `true`, its incoming
               traffic will also be routed according to this routing table.
        :param bool route_vpc_zone_ingress: (optional) Indicates whether this
               routing table is used to route traffic that originates from subnets in
               other zones in this VPC. Updating to `true` selects this routing table,
               provided no other routing table in the VPC already has this property set to
               `true`, and no subnets are attached to this routing table. Updating to
               `false` deselects this routing table.
               Incoming traffic will be routed according to the routing table with one
               exception: routes with an `action` of `deliver` are treated as `drop`
               unless the `next_hop` is an IP address in a subnet in the route's `zone`
               that is able to accept traffic. Therefore, if an incoming packet matches a
               route with a `next_hop` of a VPN gateway connection, the packet will be
               dropped.
        """
        self.accept_routes_from = accept_routes_from
        self.name = name
        self.route_direct_link_ingress = route_direct_link_ingress
        self.route_internet_ingress = route_internet_ingress
        self.route_transit_gateway_ingress = route_transit_gateway_ingress
        self.route_vpc_zone_ingress = route_vpc_zone_ingress

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'RoutingTablePatch':
        """Initialize a RoutingTablePatch object from a json dictionary."""
        args = {}
        if 'accept_routes_from' in _dict:
            args['accept_routes_from'] = [ResourceFilter.from_dict(v) for v in _dict.get('accept_routes_from')]
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        if 'route_direct_link_ingress' in _dict:
            args['route_direct_link_ingress'] = _dict.get('route_direct_link_ingress')
        if 'route_internet_ingress' in _dict:
            args['route_internet_ingress'] = _dict.get('route_internet_ingress')
        if 'route_transit_gateway_ingress' in _dict:
            args['route_transit_gateway_ingress'] = _dict.get('route_transit_gateway_ingress')
        if 'route_vpc_zone_ingress' in _dict:
            args['route_vpc_zone_ingress'] = _dict.get('route_vpc_zone_ingress')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a RoutingTablePatch object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'accept_routes_from') and self.accept_routes_from is not None:
            accept_routes_from_list = []
            for v in self.accept_routes_from:
                if isinstance(v, dict):
                    accept_routes_from_list.append(v)
                else:
                    accept_routes_from_list.append(v.to_dict())
            _dict['accept_routes_from'] = accept_routes_from_list
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'route_direct_link_ingress') and self.route_direct_link_ingress is not None:
            _dict['route_direct_link_ingress'] = self.route_direct_link_ingress
        if hasattr(self, 'route_internet_ingress') and self.route_internet_ingress is not None:
            _dict['route_internet_ingress'] = self.route_internet_ingress
        if hasattr(self, 'route_transit_gateway_ingress') and self.route_transit_gateway_ingress is not None:
            _dict['route_transit_gateway_ingress'] = self.route_transit_gateway_ingress
        if hasattr(self, 'route_vpc_zone_ingress') and self.route_vpc_zone_ingress is not None:
            _dict['route_vpc_zone_ingress'] = self.route_vpc_zone_ingress
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this RoutingTablePatch object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'RoutingTablePatch') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'RoutingTablePatch') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class RoutingTableReference:
    """
    RoutingTableReference.

    :attr RoutingTableReferenceDeleted deleted: (optional) If present, this property
          indicates the referenced resource has been deleted, and provides
          some supplementary information.
    :attr str href: The URL for this routing table.
    :attr str id: The unique identifier for this routing table.
    :attr str name: The name for this routing table. The name is unique across all
          routing tables for the VPC.
    :attr str resource_type: The resource type.
    """

    def __init__(
        self,
        href: str,
        id: str,
        name: str,
        resource_type: str,
        *,
        deleted: 'RoutingTableReferenceDeleted' = None,
    ) -> None:
        """
        Initialize a RoutingTableReference object.

        :param str href: The URL for this routing table.
        :param str id: The unique identifier for this routing table.
        :param str name: The name for this routing table. The name is unique across
               all routing tables for the VPC.
        :param str resource_type: The resource type.
        :param RoutingTableReferenceDeleted deleted: (optional) If present, this
               property indicates the referenced resource has been deleted, and provides
               some supplementary information.
        """
        self.deleted = deleted
        self.href = href
        self.id = id
        self.name = name
        self.resource_type = resource_type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'RoutingTableReference':
        """Initialize a RoutingTableReference object from a json dictionary."""
        args = {}
        if 'deleted' in _dict:
            args['deleted'] = RoutingTableReferenceDeleted.from_dict(_dict.get('deleted'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in RoutingTableReference JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in RoutingTableReference JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in RoutingTableReference JSON')
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError('Required property \'resource_type\' not present in RoutingTableReference JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a RoutingTableReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'deleted') and self.deleted is not None:
            if isinstance(self.deleted, dict):
                _dict['deleted'] = self.deleted
            else:
                _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'resource_type') and self.resource_type is not None:
            _dict['resource_type'] = self.resource_type
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this RoutingTableReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'RoutingTableReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'RoutingTableReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        ROUTING_TABLE = 'routing_table'



class RoutingTableReferenceDeleted:
    """
    If present, this property indicates the referenced resource has been deleted, and
    provides some supplementary information.

    :attr str more_info: Link to documentation about deleted resources.
    """

    def __init__(
        self,
        more_info: str,
    ) -> None:
        """
        Initialize a RoutingTableReferenceDeleted object.

        :param str more_info: Link to documentation about deleted resources.
        """
        self.more_info = more_info

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'RoutingTableReferenceDeleted':
        """Initialize a RoutingTableReferenceDeleted object from a json dictionary."""
        args = {}
        if 'more_info' in _dict:
            args['more_info'] = _dict.get('more_info')
        else:
            raise ValueError('Required property \'more_info\' not present in RoutingTableReferenceDeleted JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a RoutingTableReferenceDeleted object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'more_info') and self.more_info is not None:
            _dict['more_info'] = self.more_info
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this RoutingTableReferenceDeleted object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'RoutingTableReferenceDeleted') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'RoutingTableReferenceDeleted') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class SecurityGroup:
    """
    SecurityGroup.

    :attr datetime created_at: The date and time that this security group was
          created.
    :attr str crn: The security group's CRN.
    :attr str href: The security group's canonical URL.
    :attr str id: The unique identifier for this security group.
    :attr str name: The name for this security group. The name is unique across all
          security groups for the VPC.
    :attr ResourceGroupReference resource_group: The resource group for this
          security group.
    :attr List[SecurityGroupRule] rules: The rules for this security group. If no
          rules exist, all traffic will be denied.
    :attr List[SecurityGroupTargetReference] targets: The targets for this security
          group.
    :attr VPCReference vpc: The VPC this security group resides in.
    """

    def __init__(
        self,
        created_at: datetime,
        crn: str,
        href: str,
        id: str,
        name: str,
        resource_group: 'ResourceGroupReference',
        rules: List['SecurityGroupRule'],
        targets: List['SecurityGroupTargetReference'],
        vpc: 'VPCReference',
    ) -> None:
        """
        Initialize a SecurityGroup object.

        :param datetime created_at: The date and time that this security group was
               created.
        :param str crn: The security group's CRN.
        :param str href: The security group's canonical URL.
        :param str id: The unique identifier for this security group.
        :param str name: The name for this security group. The name is unique
               across all security groups for the VPC.
        :param ResourceGroupReference resource_group: The resource group for this
               security group.
        :param List[SecurityGroupRule] rules: The rules for this security group. If
               no rules exist, all traffic will be denied.
        :param List[SecurityGroupTargetReference] targets: The targets for this
               security group.
        :param VPCReference vpc: The VPC this security group resides in.
        """
        self.created_at = created_at
        self.crn = crn
        self.href = href
        self.id = id
        self.name = name
        self.resource_group = resource_group
        self.rules = rules
        self.targets = targets
        self.vpc = vpc

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'SecurityGroup':
        """Initialize a SecurityGroup object from a json dictionary."""
        args = {}
        if 'created_at' in _dict:
            args['created_at'] = string_to_datetime(_dict.get('created_at'))
        else:
            raise ValueError('Required property \'created_at\' not present in SecurityGroup JSON')
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError('Required property \'crn\' not present in SecurityGroup JSON')
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in SecurityGroup JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in SecurityGroup JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in SecurityGroup JSON')
        if '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(v) for v in _dict.get('rules')]
        else:
            raise ValueError('Required property \'rules\' not present in SecurityGroup JSON')
        if 'targets' in _dict:
            args['targets'] = _dict.get('targets')
        else:
            raise ValueError('Required property \'targets\' not present in SecurityGroup JSON')
        if 'vpc' in _dict:
            args['vpc'] = VPCReference.from_dict(_dict.get('vpc'))
        else:
            raise ValueError('Required property \'vpc\' not present in SecurityGroup JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SecurityGroup object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'created_at') and self.created_at is not None:
            _dict['created_at'] = datetime_to_string(self.created_at)
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'resource_group') and self.resource_group is not None:
            if isinstance(self.resource_group, dict):
                _dict['resource_group'] = self.resource_group
            else:
                _dict['resource_group'] = self.resource_group.to_dict()
        if hasattr(self, 'rules') and self.rules is not None:
            rules_list = []
            for v in self.rules:
                if isinstance(v, dict):
                    rules_list.append(v)
                else:
                    rules_list.append(v.to_dict())
            _dict['rules'] = rules_list
        if hasattr(self, 'targets') and self.targets is not None:
            targets_list = []
            for v in self.targets:
                if isinstance(v, dict):
                    targets_list.append(v)
                else:
                    targets_list.append(v.to_dict())
            _dict['targets'] = targets_list
        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()
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this SecurityGroup object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'SecurityGroup') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'SecurityGroup') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class SecurityGroupCollection:
    """
    SecurityGroupCollection.

    :attr SecurityGroupCollectionFirst first: A link to the first page of resources.
    :attr int limit: The maximum number of resources that can be returned by the
          request.
    :attr SecurityGroupCollectionNext next: (optional) A link to the next page of
          resources. This property is present for all pages
          except the last page.
    :attr List[SecurityGroup] security_groups: Collection of security groups.
    :attr int total_count: The total number of resources across all pages.
    """

    def __init__(
        self,
        first: 'SecurityGroupCollectionFirst',
        limit: int,
        security_groups: List['SecurityGroup'],
        total_count: int,
        *,
        next: 'SecurityGroupCollectionNext' = None,
    ) -> None:
        """
        Initialize a SecurityGroupCollection object.

        :param SecurityGroupCollectionFirst first: A link to the first page of
               resources.
        :param int limit: The maximum number of resources that can be returned by
               the request.
        :param List[SecurityGroup] security_groups: Collection of security groups.
        :param int total_count: The total number of resources across all pages.
        :param SecurityGroupCollectionNext next: (optional) A link to the next page
               of resources. This property is present for all pages
               except the last page.
        """
        self.first = first
        self.limit = limit
        self.next = next
        self.security_groups = security_groups
        self.total_count = total_count

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'SecurityGroupCollection':
        """Initialize a SecurityGroupCollection object from a json dictionary."""
        args = {}
        if 'first' in _dict:
            args['first'] = SecurityGroupCollectionFirst.from_dict(_dict.get('first'))
        else:
            raise ValueError('Required property \'first\' not present in SecurityGroupCollection JSON')
        if 'limit' in _dict:
            args['limit'] = _dict.get('limit')
        else:
            raise ValueError('Required property \'limit\' not present in SecurityGroupCollection JSON')
        if 'next' in _dict:
            args['next'] = SecurityGroupCollectionNext.from_dict(_dict.get('next'))
        if 'security_groups' in _dict:
            args['security_groups'] = [SecurityGroup.from_dict(v) for v in _dict.get('security_groups')]
        else:
            raise ValueError('Required property \'security_groups\' not present in SecurityGroupCollection JSON')
        if 'total_count' in _dict:
            args['total_count'] = _dict.get('total_count')
        else:
            raise ValueError('Required property \'total_count\' not present in SecurityGroupCollection JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SecurityGroupCollection object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'first') and self.first is not None:
            if isinstance(self.first, dict):
                _dict['first'] = self.first
            else:
                _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:
            if isinstance(self.next, dict):
                _dict['next'] = self.next
            else:
                _dict['next'] = self.next.to_dict()
        if hasattr(self, 'security_groups') and self.security_groups is not None:
            security_groups_list = []
            for v in self.security_groups:
                if isinstance(v, dict):
                    security_groups_list.append(v)
                else:
                    security_groups_list.append(v.to_dict())
            _dict['security_groups'] = security_groups_list
        if hasattr(self, 'total_count') and self.total_count is not None:
            _dict['total_count'] = self.total_count
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this SecurityGroupCollection object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'SecurityGroupCollection') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'SecurityGroupCollection') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class SecurityGroupCollectionFirst:
    """
    A link to the first page of resources.

    :attr str href: The URL for a page of resources.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a SecurityGroupCollectionFirst object.

        :param str href: The URL for a page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'SecurityGroupCollectionFirst':
        """Initialize a SecurityGroupCollectionFirst object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in SecurityGroupCollectionFirst JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SecurityGroupCollectionFirst object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this SecurityGroupCollectionFirst object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'SecurityGroupCollectionFirst') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'SecurityGroupCollectionFirst') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class SecurityGroupCollectionNext:
    """
    A link to the next page of resources. This property is present for all pages except
    the last page.

    :attr str href: The URL for a page of resources.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a SecurityGroupCollectionNext object.

        :param str href: The URL for a page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'SecurityGroupCollectionNext':
        """Initialize a SecurityGroupCollectionNext object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in SecurityGroupCollectionNext JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SecurityGroupCollectionNext object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this SecurityGroupCollectionNext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'SecurityGroupCollectionNext') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'SecurityGroupCollectionNext') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class SecurityGroupIdentity:
    """
    Identifies a security group by a unique property.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a SecurityGroupIdentity object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['SecurityGroupIdentityById', 'SecurityGroupIdentityByCRN', 'SecurityGroupIdentityByHref'])
        )
        raise Exception(msg)


class SecurityGroupPatch:
    """
    SecurityGroupPatch.

    :attr str name: (optional) The name for this security group. The name must not
          be used by another security group for the VPC.
    """

    def __init__(
        self,
        *,
        name: str = None,
    ) -> None:
        """
        Initialize a SecurityGroupPatch object.

        :param str name: (optional) The name for this security group. The name must
               not be used by another security group for the VPC.
        """
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'SecurityGroupPatch':
        """Initialize a SecurityGroupPatch object from a json dictionary."""
        args = {}
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SecurityGroupPatch object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this SecurityGroupPatch object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'SecurityGroupPatch') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'SecurityGroupPatch') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class SecurityGroupReference:
    """
    SecurityGroupReference.

    :attr str crn: The security group's CRN.
    :attr SecurityGroupReferenceDeleted deleted: (optional) If present, this
          property indicates the referenced resource has been deleted, and provides
          some supplementary information.
    :attr str href: The security group's canonical URL.
    :attr str id: The unique identifier for this security group.
    :attr str name: The name for this security group. The name is unique across all
          security groups for the VPC.
    """

    def __init__(
        self,
        crn: str,
        href: str,
        id: str,
        name: str,
        *,
        deleted: 'SecurityGroupReferenceDeleted' = None,
    ) -> None:
        """
        Initialize a SecurityGroupReference object.

        :param str crn: The security group's CRN.
        :param str href: The security group's canonical URL.
        :param str id: The unique identifier for this security group.
        :param str name: The name for this security group. The name is unique
               across all security groups for the VPC.
        :param SecurityGroupReferenceDeleted deleted: (optional) If present, this
               property indicates the referenced resource has been deleted, and provides
               some supplementary information.
        """
        self.crn = crn
        self.deleted = deleted
        self.href = href
        self.id = id
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'SecurityGroupReference':
        """Initialize a SecurityGroupReference object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError('Required property \'crn\' not present in SecurityGroupReference JSON')
        if 'deleted' in _dict:
            args['deleted'] = SecurityGroupReferenceDeleted.from_dict(_dict.get('deleted'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in SecurityGroupReference JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in SecurityGroupReference JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in SecurityGroupReference JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SecurityGroupReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'deleted') and self.deleted is not None:
            if isinstance(self.deleted, dict):
                _dict['deleted'] = self.deleted
            else:
                _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this SecurityGroupReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'SecurityGroupReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'SecurityGroupReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class SecurityGroupReferenceDeleted:
    """
    If present, this property indicates the referenced resource has been deleted, and
    provides some supplementary information.

    :attr str more_info: Link to documentation about deleted resources.
    """

    def __init__(
        self,
        more_info: str,
    ) -> None:
        """
        Initialize a SecurityGroupReferenceDeleted object.

        :param str more_info: Link to documentation about deleted resources.
        """
        self.more_info = more_info

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'SecurityGroupReferenceDeleted':
        """Initialize a SecurityGroupReferenceDeleted object from a json dictionary."""
        args = {}
        if 'more_info' in _dict:
            args['more_info'] = _dict.get('more_info')
        else:
            raise ValueError('Required property \'more_info\' not present in SecurityGroupReferenceDeleted JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SecurityGroupReferenceDeleted object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'more_info') and self.more_info is not None:
            _dict['more_info'] = self.more_info
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this SecurityGroupReferenceDeleted object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'SecurityGroupReferenceDeleted') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'SecurityGroupReferenceDeleted') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class SecurityGroupRule:
    """
    SecurityGroupRule.

    :attr str direction: The direction of traffic to enforce.
    :attr str href: The URL for this security group rule.
    :attr str id: The unique identifier for this security group rule.
    :attr str ip_version: The IP version to enforce. The format of `remote.address`
          or `remote.cidr_block` must match this property, 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: The protocol to enforce.
    :attr SecurityGroupRuleRemote remote: The remote IP addresses or security groups
          from which this rule allows traffic (or to
          which, for outbound rules). A CIDR block of `0.0.0.0/0` allows traffic from any
          source
          (or to any destination, for outbound rules).
    """

    def __init__(
        self,
        direction: str,
        href: str,
        id: str,
        ip_version: str,
        protocol: str,
        remote: 'SecurityGroupRuleRemote',
    ) -> None:
        """
        Initialize a SecurityGroupRule object.

        :param str direction: The direction of traffic to enforce.
        :param str href: The URL for this security group rule.
        :param str id: The unique identifier for this security group rule.
        :param str ip_version: The IP version to enforce. The format of
               `remote.address` or `remote.cidr_block` must match this property, 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: The protocol to enforce.
        :param SecurityGroupRuleRemote remote: The remote IP addresses or security
               groups from which this rule allows traffic (or to
               which, for outbound rules). A CIDR block of `0.0.0.0/0` allows traffic from
               any source
               (or to any destination, 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.
        """

        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 property, if they are used. Alternatively, if `remote` references
        a security group, then this rule only applies to IP addresses (network interfaces)
        in that group matching this IP version.
        """

        IPV4 = 'ipv4'


    class ProtocolEnum(str, Enum):
        """
        The protocol to enforce.
        """

        ALL = 'all'
        ICMP = 'icmp'
        TCP = 'tcp'
        UDP = 'udp'



class SecurityGroupRuleCollection:
    """
    Collection of rules in a security group.

    :attr List[SecurityGroupRule] rules: Array of rules.
    """

    def __init__(
        self,
        rules: List['SecurityGroupRule'],
    ) -> None:
        """
        Initialize a SecurityGroupRuleCollection object.

        :param List[SecurityGroupRule] rules: Array of rules.
        """
        self.rules = rules

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'SecurityGroupRuleCollection':
        """Initialize a SecurityGroupRuleCollection object from a json dictionary."""
        args = {}
        if 'rules' in _dict:
            args['rules'] = [SecurityGroupRule.from_dict(v) for v 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:
            rules_list = []
            for v in self.rules:
                if isinstance(v, dict):
                    rules_list.append(v)
                else:
                    rules_list.append(v.to_dict())
            _dict['rules'] = rules_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 SecurityGroupRuleCollection object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'SecurityGroupRuleCollection') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'SecurityGroupRuleCollection') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class SecurityGroupRulePatch:
    """
    SecurityGroupRulePatch.

    :attr int code: (optional) The ICMP traffic code to allow. If set, `type` must
          also be set.
          Specify `null` to remove an existing ICMP traffic code.
    :attr str direction: (optional) The direction of traffic to enforce.
    :attr str ip_version: (optional) The IP version to enforce. The format of
          `remote.address` or `remote.cidr_block` must match this property, if they are
          used. Alternatively, if `remote` references a security group, then this rule
          only applies to IP addresses (network interfaces) in that group matching this IP
          version.
    :attr int port_max: (optional) The inclusive upper bound of the protocol
          destination port range. If set, `port_min` must also be set, and must not be
          larger.
          Specify `null` to remove an existing upper bound.
    :attr int port_min: (optional) The inclusive lower bound of the protocol
          destination port range. If set, `port_max` must also be set, and must not be
          smaller.
          Specify `null` to remove an existing lower bound.
    :attr SecurityGroupRuleRemotePatch remote: (optional) The remote 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 destination, for outbound rules).
    :attr int type: (optional) The ICMP traffic type to allow.
          Specify `null` to remove an existing ICMP traffic type value.
    """

    def __init__(
        self,
        *,
        code: int = None,
        direction: str = None,
        ip_version: str = None,
        port_max: int = None,
        port_min: int = None,
        remote: 'SecurityGroupRuleRemotePatch' = None,
        type: int = None,
    ) -> None:
        """
        Initialize a SecurityGroupRulePatch object.

        :param int code: (optional) The ICMP traffic code to allow. If set, `type`
               must also be set.
               Specify `null` to remove an existing ICMP traffic code.
        :param str direction: (optional) The direction of traffic to enforce.
        :param str ip_version: (optional) The IP version to enforce. The format of
               `remote.address` or `remote.cidr_block` must match this property, if they
               are used. Alternatively, if `remote` references a security group, then this
               rule only applies to IP addresses (network interfaces) in that group
               matching this IP version.
        :param int port_max: (optional) The inclusive upper bound of the protocol
               destination port range. If set, `port_min` must also be set, and must not
               be larger.
               Specify `null` to remove an existing upper bound.
        :param int port_min: (optional) The inclusive lower bound of the protocol
               destination port range. If set, `port_max` must also be set, and must not
               be smaller.
               Specify `null` to remove an existing lower bound.
        :param SecurityGroupRuleRemotePatch remote: (optional) The remote 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 destination, for outbound rules).
        :param int type: (optional) The ICMP traffic type to allow.
               Specify `null` to remove an existing ICMP traffic type value.
        """
        self.code = code
        self.direction = direction
        self.ip_version = ip_version
        self.port_max = port_max
        self.port_min = port_min
        self.remote = remote
        self.type = type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'SecurityGroupRulePatch':
        """Initialize a SecurityGroupRulePatch object from a json dictionary."""
        args = {}
        if 'code' in _dict:
            args['code'] = _dict.get('code')
        if 'direction' in _dict:
            args['direction'] = _dict.get('direction')
        if 'ip_version' in _dict:
            args['ip_version'] = _dict.get('ip_version')
        if 'port_max' in _dict:
            args['port_max'] = _dict.get('port_max')
        if 'port_min' in _dict:
            args['port_min'] = _dict.get('port_min')
        if 'remote' in _dict:
            args['remote'] = _dict.get('remote')
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SecurityGroupRulePatch object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'code') and self.code is not None:
            _dict['code'] = self.code
        if hasattr(self, 'direction') and self.direction is not None:
            _dict['direction'] = self.direction
        if hasattr(self, 'ip_version') and self.ip_version is not None:
            _dict['ip_version'] = self.ip_version
        if hasattr(self, 'port_max') and self.port_max is not None:
            _dict['port_max'] = self.port_max
        if hasattr(self, 'port_min') and self.port_min is not None:
            _dict['port_min'] = self.port_min
        if hasattr(self, 'remote') and self.remote is not None:
            if isinstance(self.remote, dict):
                _dict['remote'] = self.remote
            else:
                _dict['remote'] = self.remote.to_dict()
        if hasattr(self, 'type') and self.type is not None:
            _dict['type'] = self.type
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this SecurityGroupRulePatch object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'SecurityGroupRulePatch') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'SecurityGroupRulePatch') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class DirectionEnum(str, Enum):
        """
        The direction of traffic to enforce.
        """

        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 property, 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.
    :attr str ip_version: (optional) The IP version to enforce. The format of
          `remote.address` or `remote.cidr_block` must match this property, 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: The protocol to enforce.
    :attr SecurityGroupRuleRemotePrototype remote: (optional) The remote 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 within the VPC.
          If unspecified, a CIDR block of `0.0.0.0/0` will be used to allow traffic from
          any source
          (or to any destination, for outbound rules).
    """

    def __init__(
        self,
        direction: str,
        protocol: str,
        *,
        ip_version: str = None,
        remote: 'SecurityGroupRuleRemotePrototype' = None,
    ) -> None:
        """
        Initialize a SecurityGroupRulePrototype object.

        :param str direction: The direction of traffic to enforce.
        :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 property, 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) The remote 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 within the VPC.
               If unspecified, a CIDR block of `0.0.0.0/0` will be used to allow traffic
               from any source
               (or to any destination, 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.
        """

        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 property, if they are used. Alternatively, if `remote` references
        a security group, then this rule only applies to IP addresses (network interfaces)
        in that group matching this IP version.
        """

        IPV4 = 'ipv4'


    class ProtocolEnum(str, Enum):
        """
        The protocol to enforce.
        """

        ALL = 'all'
        ICMP = 'icmp'
        TCP = 'tcp'
        UDP = 'udp'



class SecurityGroupRuleRemote:
    """
    The remote IP addresses or security groups from which this rule allows traffic (or to
    which, for outbound rules). A CIDR block of `0.0.0.0/0` allows traffic from any source
    (or to any destination, 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 remote 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 destination, 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 remote 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 within the VPC.
    If unspecified, a CIDR block of `0.0.0.0/0` will be used to allow traffic from any
    source
    (or to any destination, for outbound rules).

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a SecurityGroupRuleRemotePrototype object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['SecurityGroupRuleRemotePrototypeIP', 'SecurityGroupRuleRemotePrototypeCIDR', 'SecurityGroupRuleRemotePrototypeSecurityGroupIdentity'])
        )
        raise Exception(msg)


class SecurityGroupTargetCollection:
    """
    SecurityGroupTargetCollection.

    :attr SecurityGroupTargetCollectionFirst first: A link to the first page of
          resources.
    :attr int limit: The maximum number of resources that can be returned by the
          request.
    :attr SecurityGroupTargetCollectionNext next: (optional) A link to the next page
          of resources. This property is present for all pages
          except the last page.
    :attr List[SecurityGroupTargetReference] targets: Collection of targets for this
          security group.
    :attr int total_count: The total number of resources across all pages.
    """

    def __init__(
        self,
        first: 'SecurityGroupTargetCollectionFirst',
        limit: int,
        targets: List['SecurityGroupTargetReference'],
        total_count: int,
        *,
        next: 'SecurityGroupTargetCollectionNext' = None,
    ) -> None:
        """
        Initialize a SecurityGroupTargetCollection object.

        :param SecurityGroupTargetCollectionFirst first: A link to the first page
               of resources.
        :param int limit: The maximum number of resources that can be returned by
               the request.
        :param List[SecurityGroupTargetReference] targets: Collection of targets
               for this security group.
        :param int total_count: The total number of resources across all pages.
        :param SecurityGroupTargetCollectionNext next: (optional) A link to the
               next page of resources. This property is present for all pages
               except the last page.
        """
        self.first = first
        self.limit = limit
        self.next = next
        self.targets = targets
        self.total_count = total_count

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'SecurityGroupTargetCollection':
        """Initialize a SecurityGroupTargetCollection object from a json dictionary."""
        args = {}
        if 'first' in _dict:
            args['first'] = SecurityGroupTargetCollectionFirst.from_dict(_dict.get('first'))
        else:
            raise ValueError('Required property \'first\' not present in SecurityGroupTargetCollection JSON')
        if 'limit' in _dict:
            args['limit'] = _dict.get('limit')
        else:
            raise ValueError('Required property \'limit\' not present in SecurityGroupTargetCollection JSON')
        if 'next' in _dict:
            args['next'] = SecurityGroupTargetCollectionNext.from_dict(_dict.get('next'))
        if 'targets' in _dict:
            args['targets'] = _dict.get('targets')
        else:
            raise ValueError('Required property \'targets\' not present in SecurityGroupTargetCollection JSON')
        if 'total_count' in _dict:
            args['total_count'] = _dict.get('total_count')
        else:
            raise ValueError('Required property \'total_count\' not present in SecurityGroupTargetCollection JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SecurityGroupTargetCollection object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'first') and self.first is not None:
            if isinstance(self.first, dict):
                _dict['first'] = self.first
            else:
                _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:
            if isinstance(self.next, dict):
                _dict['next'] = self.next
            else:
                _dict['next'] = self.next.to_dict()
        if hasattr(self, 'targets') and self.targets is not None:
            targets_list = []
            for v in self.targets:
                if isinstance(v, dict):
                    targets_list.append(v)
                else:
                    targets_list.append(v.to_dict())
            _dict['targets'] = targets_list
        if hasattr(self, 'total_count') and self.total_count is not None:
            _dict['total_count'] = self.total_count
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this SecurityGroupTargetCollection object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'SecurityGroupTargetCollection') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'SecurityGroupTargetCollection') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class SecurityGroupTargetCollectionFirst:
    """
    A link to the first page of resources.

    :attr str href: The URL for a page of resources.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a SecurityGroupTargetCollectionFirst object.

        :param str href: The URL for a page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'SecurityGroupTargetCollectionFirst':
        """Initialize a SecurityGroupTargetCollectionFirst object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in SecurityGroupTargetCollectionFirst JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SecurityGroupTargetCollectionFirst object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this SecurityGroupTargetCollectionFirst object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'SecurityGroupTargetCollectionFirst') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'SecurityGroupTargetCollectionFirst') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class SecurityGroupTargetCollectionNext:
    """
    A link to the next page of resources. This property is present for all pages except
    the last page.

    :attr str href: The URL for a page of resources.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a SecurityGroupTargetCollectionNext object.

        :param str href: The URL for a page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'SecurityGroupTargetCollectionNext':
        """Initialize a SecurityGroupTargetCollectionNext object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in SecurityGroupTargetCollectionNext JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SecurityGroupTargetCollectionNext object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this SecurityGroupTargetCollectionNext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'SecurityGroupTargetCollectionNext') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'SecurityGroupTargetCollectionNext') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class SecurityGroupTargetReference:
    """
    The resource types that can be security group targets are expected to expand in the
    future. When iterating over security group targets, do not assume that every target
    resource will be from a known set of resource types. Optionally halt processing and
    surface an error, or bypass resources of unrecognized types.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a SecurityGroupTargetReference object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['SecurityGroupTargetReferenceNetworkInterfaceReferenceTargetContext', 'SecurityGroupTargetReferenceBareMetalServerNetworkInterfaceReferenceTargetContext', 'SecurityGroupTargetReferenceLoadBalancerReference', 'SecurityGroupTargetReferenceEndpointGatewayReference', 'SecurityGroupTargetReferenceVPNServerReference', 'SecurityGroupTargetReferenceVirtualNetworkInterfaceReference'])
        )
        raise Exception(msg)


class Share:
    """
    Share.

    :attr str access_control_mode: The access control mode for the share:
          - `security_group`: The security groups on the virtual network interface for a
          mount
            target control access to the mount target.
          - `vpc`: All clients in the VPC for a mount target have access to the mount
          target.
          The enumerated access control mode values for this property may expand in the
          future. When processing this property, check for and log unknown values.
          Optionally halt processing and surface the error, or bypass the resource on
          which the unexpected access control mode was encountered.
    :attr datetime created_at: The date and time that the file share is created.
    :attr str crn: The CRN for this file share.
    :attr str encryption: The type of encryption used for this file share.
    :attr EncryptionKeyReference encryption_key: (optional) The key used to encrypt
          this file share.
          This property will be present if `encryption_type` is `user_managed`.
    :attr str href: The URL for this file share.
    :attr str id: The unique identifier for this file share.
    :attr int iops: The maximum input/output operations per second (IOPS) for the
          file share. In addition, each client accessing the share will be restricted to
          48,000 IOPS.
          The maximum IOPS for a share may increase in the future.
    :attr ShareJob latest_job: (optional) The latest job associated with this file
          share.
          This property will be absent if no jobs have been created for this file share.
    :attr str lifecycle_state: The lifecycle state of the file share.
    :attr List[ShareMountTargetReference] mount_targets: The mount targets for the
          file share.
    :attr str name: The name for this share. The name is unique across all shares in
          the region.
    :attr ShareProfileReference profile: The
          [profile](https://cloud.ibm.com/docs/vpc?topic=vpc-file-storage-profiles) for
          this file share.
    :attr ShareReference replica_share: (optional) The replica file share for this
          source file share.
          This property will be present when the `replication_role` is `source`.
    :attr str replication_cron_spec: (optional) The cron specification for the file
          share replication schedule.
          This property will be present when the `replication_role` is `replica`.
    :attr str replication_role: The replication role of the file share.
          * `none`: This share is not participating in replication.
          * `replica`: This share is a replication target.
          * `source`: This share is a replication source.
    :attr str replication_status: The replication status of the file share.
          * `active`: This share is actively participating in replication, and the
          replica's data is up-to-date with the replication schedule.
          * `failover_pending`: This share is performing a replication failover.
          * `initializing`: This share is initializing replication.
          * `none`: This share is not participating in replication.
          * `split_pending`: This share is performing a replication split.
    :attr List[ShareReplicationStatusReason] replication_status_reasons: The reasons
          for the current replication status (if any).
          The enumerated reason code values for this property will expand in the future.
          When processing this property, check for and log unknown values. Optionally halt
          processing and surface the error, or bypass the resource on which the unexpected
          reason code was encountered.
    :attr ResourceGroupReference resource_group: The resource group for this file
          share.
    :attr str resource_type: The resource type.
    :attr int size: The size of the file share rounded up to the next gigabyte.
          The maximum size for a share may increase in the future.
    :attr ShareReference source_share: (optional) The source file share for this
          replica file share.
          This property will be present when the `replication_role` is `replica`.
    :attr List[str] user_tags: Tags for this resource.
    :attr ZoneReference zone: The zone this file share will reside in.
    """

    def __init__(
        self,
        access_control_mode: str,
        created_at: datetime,
        crn: str,
        encryption: str,
        href: str,
        id: str,
        iops: int,
        lifecycle_state: str,
        mount_targets: List['ShareMountTargetReference'],
        name: str,
        profile: 'ShareProfileReference',
        replication_role: str,
        replication_status: str,
        replication_status_reasons: List['ShareReplicationStatusReason'],
        resource_group: 'ResourceGroupReference',
        resource_type: str,
        size: int,
        user_tags: List[str],
        zone: 'ZoneReference',
        *,
        encryption_key: 'EncryptionKeyReference' = None,
        latest_job: 'ShareJob' = None,
        replica_share: 'ShareReference' = None,
        replication_cron_spec: str = None,
        source_share: 'ShareReference' = None,
    ) -> None:
        """
        Initialize a Share object.

        :param str access_control_mode: The access control mode for the share:
               - `security_group`: The security groups on the virtual network interface
               for a mount
                 target control access to the mount target.
               - `vpc`: All clients in the VPC for a mount target have access to the mount
               target.
               The enumerated access control mode values for this property may expand in
               the future. When processing this property, check for and log unknown
               values. Optionally halt processing and surface the error, or bypass the
               resource on which the unexpected access control mode was encountered.
        :param datetime created_at: The date and time that the file share is
               created.
        :param str crn: The CRN for this file share.
        :param str encryption: The type of encryption used for this file share.
        :param str href: The URL for this file share.
        :param str id: The unique identifier for this file share.
        :param int iops: The maximum input/output operations per second (IOPS) for
               the file share. In addition, each client accessing the share will be
               restricted to 48,000 IOPS.
               The maximum IOPS for a share may increase in the future.
        :param str lifecycle_state: The lifecycle state of the file share.
        :param List[ShareMountTargetReference] mount_targets: The mount targets for
               the file share.
        :param str name: The name for this share. The name is unique across all
               shares in the region.
        :param ShareProfileReference profile: The
               [profile](https://cloud.ibm.com/docs/vpc?topic=vpc-file-storage-profiles)
               for
               this file share.
        :param str replication_role: The replication role of the file share.
               * `none`: This share is not participating in replication.
               * `replica`: This share is a replication target.
               * `source`: This share is a replication source.
        :param str replication_status: The replication status of the file share.
               * `active`: This share is actively participating in replication, and the
               replica's data is up-to-date with the replication schedule.
               * `failover_pending`: This share is performing a replication failover.
               * `initializing`: This share is initializing replication.
               * `none`: This share is not participating in replication.
               * `split_pending`: This share is performing a replication split.
        :param List[ShareReplicationStatusReason] replication_status_reasons: The
               reasons for the current replication status (if any).
               The enumerated reason code values for this property will expand in the
               future. When processing this property, check for and log unknown values.
               Optionally halt processing and surface the error, or bypass the resource on
               which the unexpected reason code was encountered.
        :param ResourceGroupReference resource_group: The resource group for this
               file share.
        :param str resource_type: The resource type.
        :param int size: The size of the file share rounded up to the next
               gigabyte.
               The maximum size for a share may increase in the future.
        :param List[str] user_tags: Tags for this resource.
        :param ZoneReference zone: The zone this file share will reside in.
        :param EncryptionKeyReference encryption_key: (optional) The key used to
               encrypt this file share.
               This property will be present if `encryption_type` is `user_managed`.
        :param ShareJob latest_job: (optional) The latest job associated with this
               file share.
               This property will be absent if no jobs have been created for this file
               share.
        :param ShareReference replica_share: (optional) The replica file share for
               this source file share.
               This property will be present when the `replication_role` is `source`.
        :param str replication_cron_spec: (optional) The cron specification for the
               file share replication schedule.
               This property will be present when the `replication_role` is `replica`.
        :param ShareReference source_share: (optional) The source file share for
               this replica file share.
               This property will be present when the `replication_role` is `replica`.
        """
        self.access_control_mode = access_control_mode
        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.latest_job = latest_job
        self.lifecycle_state = lifecycle_state
        self.mount_targets = mount_targets
        self.name = name
        self.profile = profile
        self.replica_share = replica_share
        self.replication_cron_spec = replication_cron_spec
        self.replication_role = replication_role
        self.replication_status = replication_status
        self.replication_status_reasons = replication_status_reasons
        self.resource_group = resource_group
        self.resource_type = resource_type
        self.size = size
        self.source_share = source_share
        self.user_tags = user_tags
        self.zone = zone

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'Share':
        """Initialize a Share object from a json dictionary."""
        args = {}
        if 'access_control_mode' in _dict:
            args['access_control_mode'] = _dict.get('access_control_mode')
        else:
            raise ValueError('Required property \'access_control_mode\' not present in Share 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 Share JSON')
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError('Required property \'crn\' not present in Share JSON')
        if 'encryption' in _dict:
            args['encryption'] = _dict.get('encryption')
        else:
            raise ValueError('Required property \'encryption\' not present in Share 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 Share JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in Share JSON')
        if 'iops' in _dict:
            args['iops'] = _dict.get('iops')
        else:
            raise ValueError('Required property \'iops\' not present in Share JSON')
        if 'latest_job' in _dict:
            args['latest_job'] = ShareJob.from_dict(_dict.get('latest_job'))
        if 'lifecycle_state' in _dict:
            args['lifecycle_state'] = _dict.get('lifecycle_state')
        else:
            raise ValueError('Required property \'lifecycle_state\' not present in Share JSON')
        if 'mount_targets' in _dict:
            args['mount_targets'] = [ShareMountTargetReference.from_dict(v) for v in _dict.get('mount_targets')]
        else:
            raise ValueError('Required property \'mount_targets\' not present in Share JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in Share JSON')
        if 'profile' in _dict:
            args['profile'] = ShareProfileReference.from_dict(_dict.get('profile'))
        else:
            raise ValueError('Required property \'profile\' not present in Share JSON')
        if 'replica_share' in _dict:
            args['replica_share'] = ShareReference.from_dict(_dict.get('replica_share'))
        if 'replication_cron_spec' in _dict:
            args['replication_cron_spec'] = _dict.get('replication_cron_spec')
        if 'replication_role' in _dict:
            args['replication_role'] = _dict.get('replication_role')
        else:
            raise ValueError('Required property \'replication_role\' not present in Share JSON')
        if 'replication_status' in _dict:
            args['replication_status'] = _dict.get('replication_status')
        else:
            raise ValueError('Required property \'replication_status\' not present in Share JSON')
        if 'replication_status_reasons' in _dict:
            args['replication_status_reasons'] = [ShareReplicationStatusReason.from_dict(v) for v in _dict.get('replication_status_reasons')]
        else:
            raise ValueError('Required property \'replication_status_reasons\' not present in Share 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 Share JSON')
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError('Required property \'resource_type\' not present in Share JSON')
        if 'size' in _dict:
            args['size'] = _dict.get('size')
        else:
            raise ValueError('Required property \'size\' not present in Share JSON')
        if 'source_share' in _dict:
            args['source_share'] = ShareReference.from_dict(_dict.get('source_share'))
        if 'user_tags' in _dict:
            args['user_tags'] = _dict.get('user_tags')
        else:
            raise ValueError('Required property \'user_tags\' not present in Share JSON')
        if 'zone' in _dict:
            args['zone'] = ZoneReference.from_dict(_dict.get('zone'))
        else:
            raise ValueError('Required property \'zone\' not present in Share JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a Share object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'access_control_mode') and self.access_control_mode is not None:
            _dict['access_control_mode'] = self.access_control_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, '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:
            if isinstance(self.encryption_key, dict):
                _dict['encryption_key'] = self.encryption_key
            else:
                _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, 'latest_job') and self.latest_job is not None:
            if isinstance(self.latest_job, dict):
                _dict['latest_job'] = self.latest_job
            else:
                _dict['latest_job'] = self.latest_job.to_dict()
        if hasattr(self, 'lifecycle_state') and self.lifecycle_state is not None:
            _dict['lifecycle_state'] = self.lifecycle_state
        if hasattr(self, 'mount_targets') and self.mount_targets is not None:
            mount_targets_list = []
            for v in self.mount_targets:
                if isinstance(v, dict):
                    mount_targets_list.append(v)
                else:
                    mount_targets_list.append(v.to_dict())
            _dict['mount_targets'] = mount_targets_list
        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, 'replica_share') and self.replica_share is not None:
            if isinstance(self.replica_share, dict):
                _dict['replica_share'] = self.replica_share
            else:
                _dict['replica_share'] = self.replica_share.to_dict()
        if hasattr(self, 'replication_cron_spec') and self.replication_cron_spec is not None:
            _dict['replication_cron_spec'] = self.replication_cron_spec
        if hasattr(self, 'replication_role') and self.replication_role is not None:
            _dict['replication_role'] = self.replication_role
        if hasattr(self, 'replication_status') and self.replication_status is not None:
            _dict['replication_status'] = self.replication_status
        if hasattr(self, 'replication_status_reasons') and self.replication_status_reasons is not None:
            replication_status_reasons_list = []
            for v in self.replication_status_reasons:
                if isinstance(v, dict):
                    replication_status_reasons_list.append(v)
                else:
                    replication_status_reasons_list.append(v.to_dict())
            _dict['replication_status_reasons'] = replication_status_reasons_list
        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, 'resource_type') and self.resource_type is not None:
            _dict['resource_type'] = self.resource_type
        if hasattr(self, 'size') and self.size is not None:
            _dict['size'] = self.size
        if hasattr(self, 'source_share') and self.source_share is not None:
            if isinstance(self.source_share, dict):
                _dict['source_share'] = self.source_share
            else:
                _dict['source_share'] = self.source_share.to_dict()
        if hasattr(self, 'user_tags') and self.user_tags is not None:
            _dict['user_tags'] = self.user_tags
        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 Share object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'Share') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'Share') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class AccessControlModeEnum(str, Enum):
        """
        The access control mode for the share:
        - `security_group`: The security groups on the virtual network interface for a
        mount
          target control access to the mount target.
        - `vpc`: All clients in the VPC for a mount target have access to the mount
        target.
        The enumerated access control mode values for this property may expand in the
        future. When processing this property, check for and log unknown values.
        Optionally halt processing and surface the error, or bypass the resource on which
        the unexpected access control mode was encountered.
        """

        SECURITY_GROUP = 'security_group'
        VPC = 'vpc'


    class EncryptionEnum(str, Enum):
        """
        The type of encryption used for this file share.
        """

        PROVIDER_MANAGED = 'provider_managed'
        USER_MANAGED = 'user_managed'


    class LifecycleStateEnum(str, Enum):
        """
        The lifecycle state of the file share.
        """

        DELETING = 'deleting'
        FAILED = 'failed'
        PENDING = 'pending'
        STABLE = 'stable'
        SUSPENDED = 'suspended'
        UPDATING = 'updating'
        WAITING = 'waiting'


    class ReplicationRoleEnum(str, Enum):
        """
        The replication role of the file share.
        * `none`: This share is not participating in replication.
        * `replica`: This share is a replication target.
        * `source`: This share is a replication source.
        """

        NONE = 'none'
        REPLICA = 'replica'
        SOURCE = 'source'


    class ReplicationStatusEnum(str, Enum):
        """
        The replication status of the file share.
        * `active`: This share is actively participating in replication, and the replica's
        data is up-to-date with the replication schedule.
        * `failover_pending`: This share is performing a replication failover.
        * `initializing`: This share is initializing replication.
        * `none`: This share is not participating in replication.
        * `split_pending`: This share is performing a replication split.
        """

        ACTIVE = 'active'
        FAILOVER_PENDING = 'failover_pending'
        INITIALIZING = 'initializing'
        NONE = 'none'
        SPLIT_PENDING = 'split_pending'


    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        SHARE = 'share'



class ShareCollection:
    """
    ShareCollection.

    :attr ShareCollectionFirst 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 ShareCollectionNext next: (optional) A link to the next page of resources.
          This property is present for all pages
          except the last page.
    :attr List[Share] shares: Collection of file shares.
    :attr int total_count: The total number of resources across all pages.
    """

    def __init__(
        self,
        first: 'ShareCollectionFirst',
        limit: int,
        shares: List['Share'],
        total_count: int,
        *,
        next: 'ShareCollectionNext' = None,
    ) -> None:
        """
        Initialize a ShareCollection object.

        :param ShareCollectionFirst 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[Share] shares: Collection of file shares.
        :param int total_count: The total number of resources across all pages.
        :param ShareCollectionNext 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.shares = shares
        self.total_count = total_count

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ShareCollection':
        """Initialize a ShareCollection object from a json dictionary."""
        args = {}
        if 'first' in _dict:
            args['first'] = ShareCollectionFirst.from_dict(_dict.get('first'))
        else:
            raise ValueError('Required property \'first\' not present in ShareCollection JSON')
        if 'limit' in _dict:
            args['limit'] = _dict.get('limit')
        else:
            raise ValueError('Required property \'limit\' not present in ShareCollection JSON')
        if 'next' in _dict:
            args['next'] = ShareCollectionNext.from_dict(_dict.get('next'))
        if 'shares' in _dict:
            args['shares'] = [Share.from_dict(v) for v in _dict.get('shares')]
        else:
            raise ValueError('Required property \'shares\' not present in ShareCollection JSON')
        if 'total_count' in _dict:
            args['total_count'] = _dict.get('total_count')
        else:
            raise ValueError('Required property \'total_count\' not present in ShareCollection JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ShareCollection object from 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:
            if isinstance(self.first, dict):
                _dict['first'] = self.first
            else:
                _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:
            if isinstance(self.next, dict):
                _dict['next'] = self.next
            else:
                _dict['next'] = self.next.to_dict()
        if hasattr(self, 'shares') and self.shares is not None:
            shares_list = []
            for v in self.shares:
                if isinstance(v, dict):
                    shares_list.append(v)
                else:
                    shares_list.append(v.to_dict())
            _dict['shares'] = shares_list
        if hasattr(self, 'total_count') and self.total_count is not None:
            _dict['total_count'] = self.total_count
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this ShareCollection object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ShareCollection') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ShareCollection') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class ShareCollectionFirst:
    """
    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 ShareCollectionFirst object.

        :param str href: The URL for a page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ShareCollectionFirst':
        """Initialize a ShareCollectionFirst object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in ShareCollectionFirst JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ShareCollectionFirst object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(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 ShareCollectionFirst object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ShareCollectionFirst') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ShareCollectionFirst') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class ShareCollectionNext:
    """
    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 ShareCollectionNext object.

        :param str href: The URL for a page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ShareCollectionNext':
        """Initialize a ShareCollectionNext object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in ShareCollectionNext JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ShareCollectionNext object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(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 ShareCollectionNext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ShareCollectionNext') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ShareCollectionNext') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class ShareIdentity:
    """
    Identifies a file share by a unique property.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a ShareIdentity object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['ShareIdentityById', 'ShareIdentityByCRN', 'ShareIdentityByHref'])
        )
        raise Exception(msg)


class ShareInitialOwner:
    """
    ShareInitialOwner.

    :attr int gid: (optional) The initial group identifier for the file share.
    :attr int uid: (optional) The initial user identifier for the file share.
    """

    def __init__(
        self,
        *,
        gid: int = None,
        uid: int = None,
    ) -> None:
        """
        Initialize a ShareInitialOwner object.

        :param int gid: (optional) The initial group identifier for the file share.
        :param int uid: (optional) The initial user identifier for the file share.
        """
        self.gid = gid
        self.uid = uid

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ShareInitialOwner':
        """Initialize a ShareInitialOwner object from a json dictionary."""
        args = {}
        if 'gid' in _dict:
            args['gid'] = _dict.get('gid')
        if 'uid' in _dict:
            args['uid'] = _dict.get('uid')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ShareInitialOwner object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'gid') and self.gid is not None:
            _dict['gid'] = self.gid
        if hasattr(self, 'uid') and self.uid is not None:
            _dict['uid'] = self.uid
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this ShareInitialOwner object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ShareInitialOwner') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ShareInitialOwner') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class ShareJob:
    """
    ShareJob.

    :attr str status: The status of the file share job.
          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 file share job on which the
          unexpected property value was encountered.
          * `cancelled`: This job has been cancelled.
          * `failed`: This job has failed.
          * `queued`: This job is queued.
          * `running`: This job is running.
          * `succeeded`: This job completed successfully.
    :attr List[ShareJobStatusReason] status_reasons: The reasons for the file share
          job status (if any).
          The enumerated reason code values for this property will expand in the future.
          When processing this property, check for and log unknown values. Optionally halt
          processing and surface the error, or bypass the resource on which the unexpected
          reason code was encountered.
    :attr str type: The type of the file share job.
          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 file share job on which the
          unexpected property value was encountered.
          * `replication_failover`: This is a share replication failover job.
          * `replication_init`: This is a share replication is initialization job.
          * `replication_split`: This is a share replication split job.
    """

    def __init__(
        self,
        status: str,
        status_reasons: List['ShareJobStatusReason'],
        type: str,
    ) -> None:
        """
        Initialize a ShareJob object.

        :param str status: The status of the file share job.
               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 file share job on which the
               unexpected property value was encountered.
               * `cancelled`: This job has been cancelled.
               * `failed`: This job has failed.
               * `queued`: This job is queued.
               * `running`: This job is running.
               * `succeeded`: This job completed successfully.
        :param List[ShareJobStatusReason] status_reasons: The reasons for the file
               share job status (if any).
               The enumerated reason code values for this property will expand in the
               future. When processing this property, check for and log unknown values.
               Optionally halt processing and surface the error, or bypass the resource on
               which the unexpected reason code was encountered.
        :param str type: The type of the file share job.
               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 file share job on which the
               unexpected property value was encountered.
               * `replication_failover`: This is a share replication failover job.
               * `replication_init`: This is a share replication is initialization job.
               * `replication_split`: This is a share replication split job.
        """
        self.status = status
        self.status_reasons = status_reasons
        self.type = type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ShareJob':
        """Initialize a ShareJob object from a json dictionary."""
        args = {}
        if 'status' in _dict:
            args['status'] = _dict.get('status')
        else:
            raise ValueError('Required property \'status\' not present in ShareJob JSON')
        if 'status_reasons' in _dict:
            args['status_reasons'] = [ShareJobStatusReason.from_dict(v) for v in _dict.get('status_reasons')]
        else:
            raise ValueError('Required property \'status_reasons\' not present in ShareJob JSON')
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in ShareJob JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ShareJob object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'status') and self.status is not None:
            _dict['status'] = self.status
        if hasattr(self, 'status_reasons') and self.status_reasons is not None:
            status_reasons_list = []
            for v in self.status_reasons:
                if isinstance(v, dict):
                    status_reasons_list.append(v)
                else:
                    status_reasons_list.append(v.to_dict())
            _dict['status_reasons'] = status_reasons_list
        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 ShareJob object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ShareJob') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ShareJob') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class StatusEnum(str, Enum):
        """
        The status of the file share job.
        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 file share job on which the unexpected property
        value was encountered.
        * `cancelled`: This job has been cancelled.
        * `failed`: This job has failed.
        * `queued`: This job is queued.
        * `running`: This job is running.
        * `succeeded`: This job completed successfully.
        """

        CANCELLED = 'cancelled'
        FAILED = 'failed'
        QUEUED = 'queued'
        RUNNING = 'running'
        SUCCEEDED = 'succeeded'


    class TypeEnum(str, Enum):
        """
        The type of the file share job.
        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 file share job on which the unexpected property
        value was encountered.
        * `replication_failover`: This is a share replication failover job.
        * `replication_init`: This is a share replication is initialization job.
        * `replication_split`: This is a share replication split job.
        """

        REPLICATION_FAILOVER = 'replication_failover'
        REPLICATION_INIT = 'replication_init'
        REPLICATION_SPLIT = 'replication_split'



class ShareJobStatusReason:
    """
    ShareJobStatusReason.

    :attr str code: A snake case string succinctly identifying the status reason.
    :attr str message: An explanation of the status reason.
    :attr str more_info: (optional) Link to documentation about this status reason.
    """

    def __init__(
        self,
        code: str,
        message: str,
        *,
        more_info: str = None,
    ) -> None:
        """
        Initialize a ShareJobStatusReason object.

        :param str code: A snake case string succinctly identifying the status
               reason.
        :param str message: An explanation of the status reason.
        :param str more_info: (optional) Link to documentation about this status
               reason.
        """
        self.code = code
        self.message = message
        self.more_info = more_info

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ShareJobStatusReason':
        """Initialize a ShareJobStatusReason object from a json dictionary."""
        args = {}
        if 'code' in _dict:
            args['code'] = _dict.get('code')
        else:
            raise ValueError('Required property \'code\' not present in ShareJobStatusReason JSON')
        if 'message' in _dict:
            args['message'] = _dict.get('message')
        else:
            raise ValueError('Required property \'message\' not present in ShareJobStatusReason JSON')
        if 'more_info' in _dict:
            args['more_info'] = _dict.get('more_info')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ShareJobStatusReason object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'code') and self.code is not None:
            _dict['code'] = self.code
        if hasattr(self, 'message') and self.message is not None:
            _dict['message'] = self.message
        if hasattr(self, 'more_info') and self.more_info is not None:
            _dict['more_info'] = self.more_info
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this ShareJobStatusReason object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ShareJobStatusReason') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ShareJobStatusReason') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class CodeEnum(str, Enum):
        """
        A snake case string succinctly identifying the status reason.
        """

        CANNOT_INITIALIZE_REPLICATION = 'cannot_initialize_replication'
        CANNOT_REACH_REPLICA_SHARE = 'cannot_reach_replica_share'
        CANNOT_REACH_SOURCE_SHARE = 'cannot_reach_source_share'



class ShareMountTarget:
    """
    ShareMountTarget.

    :attr str access_control_mode: The access control mode for the share:
          - `security_group`: The security groups on the virtual network interface for a
          mount
            target control access to the mount target.
          - `vpc`: All clients in the VPC for a mount target have access to the mount
          target.
          The enumerated access control mode values for this property may expand in the
          future. When processing this property, check for and log unknown values.
          Optionally halt processing and surface the error, or bypass the resource on
          which the unexpected access control mode was encountered.
    :attr datetime created_at: The date and time that the share mount target was
          created.
    :attr str href: The URL for this share mount target.
    :attr str id: The unique identifier for this share mount target.
    :attr str lifecycle_state: The lifecycle state of the mount target.
    :attr str mount_path: (optional) The mount path for the share.  The server
          component of the mount path may be either an IP address or a fully qualified
          domain name.
          This property will be absent if the `lifecycle_state` of the mount target is
          'pending', `failed`, or `deleting`.
          If the share's `access_control_mode` is:
          - `security_group`: The IP address used in the mount path is the `primary_ip`
            address of the virtual network interface for this share mount target.
          - `vpc`: The fully-qualified domain name used in the mount path is an address
          that
            resolves to the share mount target.
    :attr str name: The name for this share mount target. The name is unique across
          all mount targets for the file share.
    :attr ReservedIPReference primary_ip: (optional) The primary IP address of the
          virtual network interface for the share mount target.
          Absent if `access_control_mode` is `vpc`.
    :attr str resource_type: The resource type.
    :attr SubnetReference subnet: (optional) The subnet of the virtual network
          interface for the share mount target.
          Absent if `access_control_mode` is `vpc`.
    :attr str transit_encryption: The transit encryption mode for this share mount
          target:
          - `none`: Not encrypted in transit
          - `user_managed`: Encrypted in transit using an instance identity certificate
          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 resource on which the unexpected
          property value was encountered.
    :attr VirtualNetworkInterfaceReferenceAttachmentContext
          virtual_network_interface: (optional) The virtual network interface for this
          file share mount target.
          This property will be present when the `access_control_mode` is
          `security_group`.
    :attr VPCReference vpc: If `access_control_mode` is:
          - `security_group`: The VPC for the virtual network interface for this share
          mount
            target
          - `vpc`: The VPC in which clients can mount the file share using this share
            mount target.
    """

    def __init__(
        self,
        access_control_mode: str,
        created_at: datetime,
        href: str,
        id: str,
        lifecycle_state: str,
        name: str,
        resource_type: str,
        transit_encryption: str,
        vpc: 'VPCReference',
        *,
        mount_path: str = None,
        primary_ip: 'ReservedIPReference' = None,
        subnet: 'SubnetReference' = None,
        virtual_network_interface: 'VirtualNetworkInterfaceReferenceAttachmentContext' = None,
    ) -> None:
        """
        Initialize a ShareMountTarget object.

        :param str access_control_mode: The access control mode for the share:
               - `security_group`: The security groups on the virtual network interface
               for a mount
                 target control access to the mount target.
               - `vpc`: All clients in the VPC for a mount target have access to the mount
               target.
               The enumerated access control mode values for this property may expand in
               the future. When processing this property, check for and log unknown
               values. Optionally halt processing and surface the error, or bypass the
               resource on which the unexpected access control mode was encountered.
        :param datetime created_at: The date and time that the share mount target
               was created.
        :param str href: The URL for this share mount target.
        :param str id: The unique identifier for this share mount target.
        :param str lifecycle_state: The lifecycle state of the mount target.
        :param str name: The name for this share mount target. The name is unique
               across all mount targets for the file share.
        :param str resource_type: The resource type.
        :param str transit_encryption: The transit encryption mode for this share
               mount target:
               - `none`: Not encrypted in transit
               - `user_managed`: Encrypted in transit using an instance identity
               certificate
               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 resource on which the
               unexpected property value was encountered.
        :param VPCReference vpc: If `access_control_mode` is:
               - `security_group`: The VPC for the virtual network interface for this
               share mount
                 target
               - `vpc`: The VPC in which clients can mount the file share using this share
                 mount target.
        :param str mount_path: (optional) The mount path for the share.  The server
               component of the mount path may be either an IP address or a fully
               qualified domain name.
               This property will be absent if the `lifecycle_state` of the mount target
               is
               'pending', `failed`, or `deleting`.
               If the share's `access_control_mode` is:
               - `security_group`: The IP address used in the mount path is the
               `primary_ip`
                 address of the virtual network interface for this share mount target.
               - `vpc`: The fully-qualified domain name used in the mount path is an
               address that
                 resolves to the share mount target.
        :param ReservedIPReference primary_ip: (optional) The primary IP address of
               the virtual network interface for the share mount target.
               Absent if `access_control_mode` is `vpc`.
        :param SubnetReference subnet: (optional) The subnet of the virtual network
               interface for the share mount target.
               Absent if `access_control_mode` is `vpc`.
        :param VirtualNetworkInterfaceReferenceAttachmentContext
               virtual_network_interface: (optional) The virtual network interface for
               this file share mount target.
               This property will be present when the `access_control_mode` is
               `security_group`.
        """
        self.access_control_mode = access_control_mode
        self.created_at = created_at
        self.href = href
        self.id = id
        self.lifecycle_state = lifecycle_state
        self.mount_path = mount_path
        self.name = name
        self.primary_ip = primary_ip
        self.resource_type = resource_type
        self.subnet = subnet
        self.transit_encryption = transit_encryption
        self.virtual_network_interface = virtual_network_interface
        self.vpc = vpc

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ShareMountTarget':
        """Initialize a ShareMountTarget object from a json dictionary."""
        args = {}
        if 'access_control_mode' in _dict:
            args['access_control_mode'] = _dict.get('access_control_mode')
        else:
            raise ValueError('Required property \'access_control_mode\' not present in ShareMountTarget 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 ShareMountTarget JSON')
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in ShareMountTarget JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in ShareMountTarget JSON')
        if 'lifecycle_state' in _dict:
            args['lifecycle_state'] = _dict.get('lifecycle_state')
        else:
            raise ValueError('Required property \'lifecycle_state\' not present in ShareMountTarget JSON')
        if 'mount_path' in _dict:
            args['mount_path'] = _dict.get('mount_path')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in ShareMountTarget JSON')
        if 'primary_ip' in _dict:
            args['primary_ip'] = ReservedIPReference.from_dict(_dict.get('primary_ip'))
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError('Required property \'resource_type\' not present in ShareMountTarget JSON')
        if 'subnet' in _dict:
            args['subnet'] = SubnetReference.from_dict(_dict.get('subnet'))
        if 'transit_encryption' in _dict:
            args['transit_encryption'] = _dict.get('transit_encryption')
        else:
            raise ValueError('Required property \'transit_encryption\' not present in ShareMountTarget JSON')
        if 'virtual_network_interface' in _dict:
            args['virtual_network_interface'] = VirtualNetworkInterfaceReferenceAttachmentContext.from_dict(_dict.get('virtual_network_interface'))
        if 'vpc' in _dict:
            args['vpc'] = VPCReference.from_dict(_dict.get('vpc'))
        else:
            raise ValueError('Required property \'vpc\' not present in ShareMountTarget JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ShareMountTarget object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'access_control_mode') and self.access_control_mode is not None:
            _dict['access_control_mode'] = self.access_control_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, '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, 'mount_path') and self.mount_path is not None:
            _dict['mount_path'] = self.mount_path
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'primary_ip') and self.primary_ip is not None:
            if isinstance(self.primary_ip, dict):
                _dict['primary_ip'] = self.primary_ip
            else:
                _dict['primary_ip'] = self.primary_ip.to_dict()
        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:
            if isinstance(self.subnet, dict):
                _dict['subnet'] = self.subnet
            else:
                _dict['subnet'] = self.subnet.to_dict()
        if hasattr(self, 'transit_encryption') and self.transit_encryption is not None:
            _dict['transit_encryption'] = self.transit_encryption
        if hasattr(self, 'virtual_network_interface') and self.virtual_network_interface is not None:
            if isinstance(self.virtual_network_interface, dict):
                _dict['virtual_network_interface'] = self.virtual_network_interface
            else:
                _dict['virtual_network_interface'] = self.virtual_network_interface.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()
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this ShareMountTarget object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ShareMountTarget') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ShareMountTarget') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class AccessControlModeEnum(str, Enum):
        """
        The access control mode for the share:
        - `security_group`: The security groups on the virtual network interface for a
        mount
          target control access to the mount target.
        - `vpc`: All clients in the VPC for a mount target have access to the mount
        target.
        The enumerated access control mode values for this property may expand in the
        future. When processing this property, check for and log unknown values.
        Optionally halt processing and surface the error, or bypass the resource on which
        the unexpected access control mode was encountered.
        """

        SECURITY_GROUP = 'security_group'
        VPC = 'vpc'


    class LifecycleStateEnum(str, Enum):
        """
        The lifecycle state of the mount target.
        """

        DELETING = 'deleting'
        FAILED = 'failed'
        PENDING = 'pending'
        STABLE = 'stable'
        SUSPENDED = 'suspended'
        UPDATING = 'updating'
        WAITING = 'waiting'


    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        SHARE_MOUNT_TARGET = 'share_mount_target'


    class TransitEncryptionEnum(str, Enum):
        """
        The transit encryption mode for this share mount target:
        - `none`: Not encrypted in transit
        - `user_managed`: Encrypted in transit using an instance identity certificate
        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 resource on which the unexpected property value
        was encountered.
        """

        NONE = 'none'
        USER_MANAGED = 'user_managed'



class ShareMountTargetCollection:
    """
    ShareMountTargetCollection.

    :attr ShareMountTargetCollectionFirst 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[ShareMountTarget] mount_targets: Collection of share mount targets.
    :attr ShareMountTargetCollectionNext 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: 'ShareMountTargetCollectionFirst',
        limit: int,
        mount_targets: List['ShareMountTarget'],
        total_count: int,
        *,
        next: 'ShareMountTargetCollectionNext' = None,
    ) -> None:
        """
        Initialize a ShareMountTargetCollection object.

        :param ShareMountTargetCollectionFirst 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[ShareMountTarget] mount_targets: Collection of share mount
               targets.
        :param int total_count: The total number of resources across all pages.
        :param ShareMountTargetCollectionNext 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.mount_targets = mount_targets
        self.next = next
        self.total_count = total_count

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ShareMountTargetCollection':
        """Initialize a ShareMountTargetCollection object from a json dictionary."""
        args = {}
        if 'first' in _dict:
            args['first'] = ShareMountTargetCollectionFirst.from_dict(_dict.get('first'))
        else:
            raise ValueError('Required property \'first\' not present in ShareMountTargetCollection JSON')
        if 'limit' in _dict:
            args['limit'] = _dict.get('limit')
        else:
            raise ValueError('Required property \'limit\' not present in ShareMountTargetCollection JSON')
        if 'mount_targets' in _dict:
            args['mount_targets'] = [ShareMountTarget.from_dict(v) for v in _dict.get('mount_targets')]
        else:
            raise ValueError('Required property \'mount_targets\' not present in ShareMountTargetCollection JSON')
        if 'next' in _dict:
            args['next'] = ShareMountTargetCollectionNext.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 ShareMountTargetCollection JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ShareMountTargetCollection object from 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:
            if isinstance(self.first, dict):
                _dict['first'] = self.first
            else:
                _dict['first'] = self.first.to_dict()
        if hasattr(self, 'limit') and self.limit is not None:
            _dict['limit'] = self.limit
        if hasattr(self, 'mount_targets') and self.mount_targets is not None:
            mount_targets_list = []
            for v in self.mount_targets:
                if isinstance(v, dict):
                    mount_targets_list.append(v)
                else:
                    mount_targets_list.append(v.to_dict())
            _dict['mount_targets'] = mount_targets_list
        if hasattr(self, 'next') and self.next is not None:
            if isinstance(self.next, dict):
                _dict['next'] = self.next
            else:
                _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 ShareMountTargetCollection object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ShareMountTargetCollection') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ShareMountTargetCollection') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class ShareMountTargetCollectionFirst:
    """
    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 ShareMountTargetCollectionFirst object.

        :param str href: The URL for a page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ShareMountTargetCollectionFirst':
        """Initialize a ShareMountTargetCollectionFirst object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in ShareMountTargetCollectionFirst JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ShareMountTargetCollectionFirst object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(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 ShareMountTargetCollectionFirst object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ShareMountTargetCollectionFirst') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ShareMountTargetCollectionFirst') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class ShareMountTargetCollectionNext:
    """
    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 ShareMountTargetCollectionNext object.

        :param str href: The URL for a page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ShareMountTargetCollectionNext':
        """Initialize a ShareMountTargetCollectionNext object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in ShareMountTargetCollectionNext JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ShareMountTargetCollectionNext object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(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 ShareMountTargetCollectionNext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ShareMountTargetCollectionNext') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ShareMountTargetCollectionNext') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class ShareMountTargetPatch:
    """
    ShareMountTargetPatch.

    :attr str name: (optional) The name for this share mount target. The name must
          not be used by another mount target for the file share.
    """

    def __init__(
        self,
        *,
        name: str = None,
    ) -> None:
        """
        Initialize a ShareMountTargetPatch object.

        :param str name: (optional) The name for this share mount target. The name
               must not be used by another mount target for the file share.
        """
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ShareMountTargetPatch':
        """Initialize a ShareMountTargetPatch 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 ShareMountTargetPatch object from 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 ShareMountTargetPatch object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ShareMountTargetPatch') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ShareMountTargetPatch') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class ShareMountTargetPrototype:
    """
    ShareMountTargetPrototype.

    :attr str name: (optional) The name for this share mount target. The name must
          not be used by another mount target for the file share.
    :attr str transit_encryption: (optional) The transit encryption mode to use for
          this share mount target:
          - `none`: Not encrypted in transit.
          - `user_managed`: Encrypted in transit using an instance identity certificate.
          The
                            `access_control_mode` for the share must be `security_group`.
    """

    def __init__(
        self,
        *,
        name: str = None,
        transit_encryption: str = None,
    ) -> None:
        """
        Initialize a ShareMountTargetPrototype object.

        :param str name: (optional) The name for this share mount target. The name
               must not be used by another mount target for the file share.
        :param str transit_encryption: (optional) The transit encryption mode to
               use for this share mount target:
               - `none`: Not encrypted in transit.
               - `user_managed`: Encrypted in transit using an instance identity
               certificate.  The
                                 `access_control_mode` for the share must be
               `security_group`.
        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['ShareMountTargetPrototypeShareMountTargetByAccessControlModeSecurityGroup', 'ShareMountTargetPrototypeShareMountTargetByAccessControlModeVPC'])
        )
        raise Exception(msg)

    class TransitEncryptionEnum(str, Enum):
        """
        The transit encryption mode to use for this share mount target:
        - `none`: Not encrypted in transit.
        - `user_managed`: Encrypted in transit using an instance identity certificate.
        The
                          `access_control_mode` for the share must be `security_group`.
        """

        NONE = 'none'
        USER_MANAGED = 'user_managed'



class ShareMountTargetReference:
    """
    ShareMountTargetReference.

    :attr ShareMountTargetReferenceDeleted deleted: (optional) If present, this
          property indicates the referenced resource has been deleted, and provides
          some supplementary information.
    :attr str href: The URL for this share mount target.
    :attr str id: The unique identifier for this share mount target.
    :attr str name: The name for this share mount target. The name is unique across
          all mount targets for the file share.
    :attr str resource_type: The resource type.
    """

    def __init__(
        self,
        href: str,
        id: str,
        name: str,
        resource_type: str,
        *,
        deleted: 'ShareMountTargetReferenceDeleted' = None,
    ) -> None:
        """
        Initialize a ShareMountTargetReference object.

        :param str href: The URL for this share mount target.
        :param str id: The unique identifier for this share mount target.
        :param str name: The name for this share mount target. The name is unique
               across all mount targets for the file share.
        :param str resource_type: The resource type.
        :param ShareMountTargetReferenceDeleted deleted: (optional) If present,
               this property indicates the referenced resource has been deleted, and
               provides
               some supplementary information.
        """
        self.deleted = deleted
        self.href = href
        self.id = id
        self.name = name
        self.resource_type = resource_type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ShareMountTargetReference':
        """Initialize a ShareMountTargetReference object from a json dictionary."""
        args = {}
        if 'deleted' in _dict:
            args['deleted'] = ShareMountTargetReferenceDeleted.from_dict(_dict.get('deleted'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in ShareMountTargetReference JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in ShareMountTargetReference JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in ShareMountTargetReference JSON')
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError('Required property \'resource_type\' not present in ShareMountTargetReference JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ShareMountTargetReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'deleted') and self.deleted is not None:
            if isinstance(self.deleted, dict):
                _dict['deleted'] = self.deleted
            else:
                _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'resource_type') and self.resource_type is not None:
            _dict['resource_type'] = self.resource_type
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this ShareMountTargetReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ShareMountTargetReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ShareMountTargetReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        SHARE_MOUNT_TARGET = 'share_mount_target'



class ShareMountTargetReferenceDeleted:
    """
    If present, this property indicates the referenced resource has been deleted, and
    provides some supplementary information.

    :attr str more_info: Link to documentation about deleted resources.
    """

    def __init__(
        self,
        more_info: str,
    ) -> None:
        """
        Initialize a ShareMountTargetReferenceDeleted object.

        :param str more_info: Link to documentation about deleted resources.
        """
        self.more_info = more_info

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ShareMountTargetReferenceDeleted':
        """Initialize a ShareMountTargetReferenceDeleted object from a json dictionary."""
        args = {}
        if 'more_info' in _dict:
            args['more_info'] = _dict.get('more_info')
        else:
            raise ValueError('Required property \'more_info\' not present in ShareMountTargetReferenceDeleted JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ShareMountTargetReferenceDeleted object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'more_info') and self.more_info is not None:
            _dict['more_info'] = self.more_info
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this ShareMountTargetReferenceDeleted object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ShareMountTargetReferenceDeleted') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ShareMountTargetReferenceDeleted') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class ShareMountTargetVirtualNetworkInterfacePrototype:
    """
    ShareMountTargetVirtualNetworkInterfacePrototype.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a ShareMountTargetVirtualNetworkInterfacePrototype object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['ShareMountTargetVirtualNetworkInterfacePrototypeVirtualNetworkInterfacePrototypeShareMountTargetContext'])
        )
        raise Exception(msg)


class SharePatch:
    """
    SharePatch.

    :attr str access_control_mode: (optional) The access control mode for the share:
          - `security_group`: The security groups on the virtual network interface for a
            mount target control access to the mount target.
          - `vpc`: All clients in the VPC for a mount target have access to the mount
          target.
          For this property to be changed, the share must have no mount targets and
          `replication_role` must be `none`.
    :attr int iops: (optional) The maximum input/output operations per second (IOPS)
          for the file share. The value must be in the range supported by the share's
          size.
          For this property to be changed, the share `lifecycle_state` must be `stable`.
    :attr str name: (optional) The name for this share. The name must not be used by
          another share in the region.
    :attr ShareProfileIdentity profile: (optional) The profile to use for this file
          share.
          The requested profile must be in the same `family`.
    :attr str replication_cron_spec: (optional) The cron specification for the file
          share replication schedule.
          Replication of a share can be scheduled to occur at most once per hour.
          For this property to be changed, the share `replication_role` must be `replica`.
    :attr int size: (optional) The size of the file share rounded up to the next
          gigabyte. The value must not be less than the share's current size, and must not
          exceed the maximum supported by the share's profile and IOPS.
          For this property to be changed, the share `lifecycle_state` must be `stable`.
    :attr List[str] user_tags: (optional) Tags for this resource.
    """

    def __init__(
        self,
        *,
        access_control_mode: str = None,
        iops: int = None,
        name: str = None,
        profile: 'ShareProfileIdentity' = None,
        replication_cron_spec: str = None,
        size: int = None,
        user_tags: List[str] = None,
    ) -> None:
        """
        Initialize a SharePatch object.

        :param str access_control_mode: (optional) The access control mode for the
               share:
               - `security_group`: The security groups on the virtual network interface
               for a
                 mount target control access to the mount target.
               - `vpc`: All clients in the VPC for a mount target have access to the mount
               target.
               For this property to be changed, the share must have no mount targets and
               `replication_role` must be `none`.
        :param int iops: (optional) The maximum input/output operations per second
               (IOPS) for the file share. The value must be in the range supported by the
               share's size.
               For this property to be changed, the share `lifecycle_state` must be
               `stable`.
        :param str name: (optional) The name for this share. The name must not be
               used by another share in the region.
        :param ShareProfileIdentity profile: (optional) The profile to use for this
               file share.
               The requested profile must be in the same `family`.
        :param str replication_cron_spec: (optional) The cron specification for the
               file share replication schedule.
               Replication of a share can be scheduled to occur at most once per hour.
               For this property to be changed, the share `replication_role` must be
               `replica`.
        :param int size: (optional) The size of the file share rounded up to the
               next gigabyte. The value must not be less than the share's current size,
               and must not exceed the maximum supported by the share's profile and IOPS.
               For this property to be changed, the share `lifecycle_state` must be
               `stable`.
        :param List[str] user_tags: (optional) Tags for this resource.
        """
        self.access_control_mode = access_control_mode
        self.iops = iops
        self.name = name
        self.profile = profile
        self.replication_cron_spec = replication_cron_spec
        self.size = size
        self.user_tags = user_tags

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'SharePatch':
        """Initialize a SharePatch object from a json dictionary."""
        args = {}
        if 'access_control_mode' in _dict:
            args['access_control_mode'] = _dict.get('access_control_mode')
        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')
        if 'replication_cron_spec' in _dict:
            args['replication_cron_spec'] = _dict.get('replication_cron_spec')
        if 'size' in _dict:
            args['size'] = _dict.get('size')
        if 'user_tags' in _dict:
            args['user_tags'] = _dict.get('user_tags')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SharePatch object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'access_control_mode') and self.access_control_mode is not None:
            _dict['access_control_mode'] = self.access_control_mode
        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, 'replication_cron_spec') and self.replication_cron_spec is not None:
            _dict['replication_cron_spec'] = self.replication_cron_spec
        if hasattr(self, 'size') and self.size is not None:
            _dict['size'] = self.size
        if hasattr(self, 'user_tags') and self.user_tags is not None:
            _dict['user_tags'] = self.user_tags
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this SharePatch object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'SharePatch') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'SharePatch') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class AccessControlModeEnum(str, Enum):
        """
        The access control mode for the share:
        - `security_group`: The security groups on the virtual network interface for a
          mount target control access to the mount target.
        - `vpc`: All clients in the VPC for a mount target have access to the mount
        target.
        For this property to be changed, the share must have no mount targets and
        `replication_role` must be `none`.
        """

        SECURITY_GROUP = 'security_group'
        VPC = 'vpc'



class ShareProfile:
    """
    ShareProfile.

    :attr ShareProfileCapacity capacity: The permitted capacity range (in gigabytes)
          for a share with this profile.
    :attr str family: The product family this share profile belongs to.
    :attr str href: The URL for this share profile.
    :attr ShareProfileIOPS iops: The permitted IOPS range for a share with this
          profile.
    :attr str name: The globally unique name for this share profile.
    :attr str resource_type: The resource type.
    """

    def __init__(
        self,
        capacity: 'ShareProfileCapacity',
        family: str,
        href: str,
        iops: 'ShareProfileIOPS',
        name: str,
        resource_type: str,
    ) -> None:
        """
        Initialize a ShareProfile object.

        :param ShareProfileCapacity capacity: The permitted capacity range (in
               gigabytes) for a share with this profile.
        :param str family: The product family this share profile belongs to.
        :param str href: The URL for this share profile.
        :param ShareProfileIOPS iops: The permitted IOPS range for a share with
               this profile.
        :param str name: The globally unique name for this share profile.
        :param str resource_type: The resource type.
        """
        self.capacity = capacity
        self.family = family
        self.href = href
        self.iops = iops
        self.name = name
        self.resource_type = resource_type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ShareProfile':
        """Initialize a ShareProfile object from a json dictionary."""
        args = {}
        if 'capacity' in _dict:
            args['capacity'] = _dict.get('capacity')
        else:
            raise ValueError('Required property \'capacity\' not present in ShareProfile JSON')
        if 'family' in _dict:
            args['family'] = _dict.get('family')
        else:
            raise ValueError('Required property \'family\' not present in ShareProfile JSON')
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in ShareProfile JSON')
        if 'iops' in _dict:
            args['iops'] = _dict.get('iops')
        else:
            raise ValueError('Required property \'iops\' not present in ShareProfile JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in ShareProfile JSON')
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError('Required property \'resource_type\' not present in ShareProfile JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ShareProfile object from 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:
            if isinstance(self.capacity, dict):
                _dict['capacity'] = self.capacity
            else:
                _dict['capacity'] = self.capacity.to_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, 'iops') and self.iops is not None:
            if isinstance(self.iops, dict):
                _dict['iops'] = self.iops
            else:
                _dict['iops'] = self.iops.to_dict()
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'resource_type') and self.resource_type is not None:
            _dict['resource_type'] = self.resource_type
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this ShareProfile object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ShareProfile') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ShareProfile') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class FamilyEnum(str, Enum):
        """
        The product family this share profile belongs to.
        """

        DEFINED_PERFORMANCE = 'defined_performance'


    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        SHARE_PROFILE = 'share_profile'



class ShareProfileCapacity:
    """
    ShareProfileCapacity.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a ShareProfileCapacity object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['ShareProfileCapacityFixed', 'ShareProfileCapacityRange', 'ShareProfileCapacityEnum', 'ShareProfileCapacityDependentRange'])
        )
        raise Exception(msg)


class ShareProfileCollection:
    """
    ShareProfileCollection.

    :attr ShareProfileCollectionFirst 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 ShareProfileCollectionNext next: (optional) A link to the next page of
          resources. This property is present for all pages
          except the last page.
    :attr List[ShareProfile] profiles: Collection of share profiles.
    :attr int total_count: The total number of resources across all pages.
    """

    def __init__(
        self,
        first: 'ShareProfileCollectionFirst',
        limit: int,
        profiles: List['ShareProfile'],
        total_count: int,
        *,
        next: 'ShareProfileCollectionNext' = None,
    ) -> None:
        """
        Initialize a ShareProfileCollection object.

        :param ShareProfileCollectionFirst 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[ShareProfile] profiles: Collection of share profiles.
        :param int total_count: The total number of resources across all pages.
        :param ShareProfileCollectionNext 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) -> 'ShareProfileCollection':
        """Initialize a ShareProfileCollection object from a json dictionary."""
        args = {}
        if 'first' in _dict:
            args['first'] = ShareProfileCollectionFirst.from_dict(_dict.get('first'))
        else:
            raise ValueError('Required property \'first\' not present in ShareProfileCollection JSON')
        if 'limit' in _dict:
            args['limit'] = _dict.get('limit')
        else:
            raise ValueError('Required property \'limit\' not present in ShareProfileCollection JSON')
        if 'next' in _dict:
            args['next'] = ShareProfileCollectionNext.from_dict(_dict.get('next'))
        if 'profiles' in _dict:
            args['profiles'] = [ShareProfile.from_dict(v) for v in _dict.get('profiles')]
        else:
            raise ValueError('Required property \'profiles\' not present in ShareProfileCollection JSON')
        if 'total_count' in _dict:
            args['total_count'] = _dict.get('total_count')
        else:
            raise ValueError('Required property \'total_count\' not present in ShareProfileCollection JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ShareProfileCollection object from 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:
            if isinstance(self.first, dict):
                _dict['first'] = self.first
            else:
                _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:
            if isinstance(self.next, dict):
                _dict['next'] = self.next
            else:
                _dict['next'] = self.next.to_dict()
        if hasattr(self, 'profiles') and self.profiles is not None:
            profiles_list = []
            for v in self.profiles:
                if isinstance(v, dict):
                    profiles_list.append(v)
                else:
                    profiles_list.append(v.to_dict())
            _dict['profiles'] = profiles_list
        if hasattr(self, 'total_count') and self.total_count is not None:
            _dict['total_count'] = self.total_count
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this ShareProfileCollection object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ShareProfileCollection') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ShareProfileCollection') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class ShareProfileCollectionFirst:
    """
    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 ShareProfileCollectionFirst object.

        :param str href: The URL for a page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ShareProfileCollectionFirst':
        """Initialize a ShareProfileCollectionFirst object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in ShareProfileCollectionFirst JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ShareProfileCollectionFirst object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(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 ShareProfileCollectionFirst object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ShareProfileCollectionFirst') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ShareProfileCollectionFirst') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class ShareProfileCollectionNext:
    """
    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 ShareProfileCollectionNext object.

        :param str href: The URL for a page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ShareProfileCollectionNext':
        """Initialize a ShareProfileCollectionNext object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in ShareProfileCollectionNext JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ShareProfileCollectionNext object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(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 ShareProfileCollectionNext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ShareProfileCollectionNext') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ShareProfileCollectionNext') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class ShareProfileIOPS:
    """
    ShareProfileIOPS.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a ShareProfileIOPS object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['ShareProfileIOPSFixed', 'ShareProfileIOPSRange', 'ShareProfileIOPSEnum', 'ShareProfileIOPSDependentRange'])
        )
        raise Exception(msg)


class ShareProfileIdentity:
    """
    Identifies a share profile by a unique property.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a ShareProfileIdentity object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['ShareProfileIdentityByName', 'ShareProfileIdentityByHref'])
        )
        raise Exception(msg)


class ShareProfileReference:
    """
    ShareProfileReference.

    :attr str href: The URL for this share profile.
    :attr str name: The globally unique name for this share profile.
    :attr str resource_type: The resource type.
    """

    def __init__(
        self,
        href: str,
        name: str,
        resource_type: str,
    ) -> None:
        """
        Initialize a ShareProfileReference object.

        :param str href: The URL for this share profile.
        :param str name: The globally unique name for this share profile.
        :param str resource_type: The resource type.
        """
        self.href = href
        self.name = name
        self.resource_type = resource_type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ShareProfileReference':
        """Initialize a ShareProfileReference object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in ShareProfileReference JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in ShareProfileReference JSON')
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError('Required property \'resource_type\' not present in ShareProfileReference JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ShareProfileReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(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, '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 ShareProfileReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ShareProfileReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ShareProfileReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        SHARE_PROFILE = 'share_profile'



class SharePrototype:
    """
    SharePrototype.

    :attr int iops: (optional) The maximum input/output operations per second (IOPS)
          for the file share. The share must be in the `defined_performance` profile
          family, and the value must be in the range supported by the share's specified
          size.
          In addition, each client accessing the share will be restricted to 48,000 IOPS.
    :attr List[ShareMountTargetPrototype] mount_targets: (optional) The mount
          targets for the file share. Each mount target must be in a unique VPC.
    :attr str name: (optional) The name for this share. The name must not be used by
          another share in the region. If unspecified, the name will be a hyphenated list
          of randomly-selected words.
    :attr ShareProfileIdentity profile: The
          [profile](https://cloud.ibm.com/docs/vpc?topic=vpc-file-storage-profiles) to use
          for this file share. The profile must support the share's specified IOPS and
          size.
    :attr SharePrototypeShareContext replica_share: (optional) Configuration for a
          replica file share to create and associate with this file share. If
          unspecified, a replica may be subsequently added by creating a new file share
          with a
          `source_share` referencing this file share.
    :attr List[str] user_tags: (optional) Tags for this resource.
    :attr ZoneIdentity zone: The zone this file share will reside in.
          For a replica share, this must be a different zone in the same region as the
          source share.
    """

    def __init__(
        self,
        profile: 'ShareProfileIdentity',
        zone: 'ZoneIdentity',
        *,
        iops: int = None,
        mount_targets: List['ShareMountTargetPrototype'] = None,
        name: str = None,
        replica_share: 'SharePrototypeShareContext' = None,
        user_tags: List[str] = None,
    ) -> None:
        """
        Initialize a SharePrototype object.

        :param ShareProfileIdentity profile: The
               [profile](https://cloud.ibm.com/docs/vpc?topic=vpc-file-storage-profiles)
               to use
               for this file share. The profile must support the share's specified IOPS
               and size.
        :param ZoneIdentity zone: The zone this file share will reside in.
               For a replica share, this must be a different zone in the same region as
               the
               source share.
        :param int iops: (optional) The maximum input/output operations per second
               (IOPS) for the file share. The share must be in the `defined_performance`
               profile family, and the value must be in the range supported by the share's
               specified size.
               In addition, each client accessing the share will be restricted to 48,000
               IOPS.
        :param List[ShareMountTargetPrototype] mount_targets: (optional) The mount
               targets for the file share. Each mount target must be in a unique VPC.
        :param str name: (optional) The name for this share. The name must not be
               used by another share in the region. If unspecified, the name will be a
               hyphenated list of randomly-selected words.
        :param SharePrototypeShareContext replica_share: (optional) Configuration
               for a replica file share to create and associate with this file share. If
               unspecified, a replica may be subsequently added by creating a new file
               share with a
               `source_share` referencing this file share.
        :param List[str] user_tags: (optional) Tags for this resource.
        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['SharePrototypeShareBySize', 'SharePrototypeShareBySourceShare'])
        )
        raise Exception(msg)


class SharePrototypeShareContext:
    """
    Configuration for a replica file share to create and associate with this file share.
    If unspecified, a replica may be subsequently added by creating a new file share with
    a
    `source_share` referencing this file share.

    :attr int iops: (optional) The maximum input/output operations per second (IOPS)
          for the file share. The share must be in the `defined_performance` profile
          family, and the value must be in the range supported by the share's specified
          size.
          In addition, each client accessing the share will be restricted to 48,000 IOPS.
    :attr List[ShareMountTargetPrototype] mount_targets: (optional) The mount
          targets for this replica file share. Each mount target must be in a unique VPC.
          A replica's mount targets must be mounted read-only.
    :attr str name: (optional) The name for this share. The name must not be used by
          another share in the region. If unspecified, the name will be a hyphenated list
          of randomly-selected words.
    :attr ShareProfileIdentity profile: The
          [profile](https://cloud.ibm.com/docs/vpc?topic=vpc-file-storage-profiles) to use
          for this file share. The profile must support the share's specified IOPS and
          size.
    :attr str replication_cron_spec: The cron specification for the file share
          replication schedule.
          Replication of a share can be scheduled to occur at most once per hour.
    :attr ResourceGroupIdentity resource_group: (optional) The resource group to
          use. If unspecified, the resource group from
          the source share will be used.
    :attr List[str] user_tags: (optional) Tags for this resource.
    :attr ZoneIdentity zone: The zone this replica file share will reside in.
          Must be a different zone in the same region as the source share.
    """

    def __init__(
        self,
        profile: 'ShareProfileIdentity',
        replication_cron_spec: str,
        zone: 'ZoneIdentity',
        *,
        iops: int = None,
        mount_targets: List['ShareMountTargetPrototype'] = None,
        name: str = None,
        resource_group: 'ResourceGroupIdentity' = None,
        user_tags: List[str] = None,
    ) -> None:
        """
        Initialize a SharePrototypeShareContext object.

        :param ShareProfileIdentity profile: The
               [profile](https://cloud.ibm.com/docs/vpc?topic=vpc-file-storage-profiles)
               to use
               for this file share. The profile must support the share's specified IOPS
               and size.
        :param str replication_cron_spec: The cron specification for the file share
               replication schedule.
               Replication of a share can be scheduled to occur at most once per hour.
        :param ZoneIdentity zone: The zone this replica file share will reside in.
               Must be a different zone in the same region as the source share.
        :param int iops: (optional) The maximum input/output operations per second
               (IOPS) for the file share. The share must be in the `defined_performance`
               profile family, and the value must be in the range supported by the share's
               specified size.
               In addition, each client accessing the share will be restricted to 48,000
               IOPS.
        :param List[ShareMountTargetPrototype] mount_targets: (optional) The mount
               targets for this replica file share. Each mount target must be in a unique
               VPC.
               A replica's mount targets must be mounted read-only.
        :param str name: (optional) The name for this share. The name must not be
               used by another share in the region. 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 resource group from
               the source share will be used.
        :param List[str] user_tags: (optional) Tags for this resource.
        """
        self.iops = iops
        self.mount_targets = mount_targets
        self.name = name
        self.profile = profile
        self.replication_cron_spec = replication_cron_spec
        self.resource_group = resource_group
        self.user_tags = user_tags
        self.zone = zone

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'SharePrototypeShareContext':
        """Initialize a SharePrototypeShareContext object from a json dictionary."""
        args = {}
        if 'iops' in _dict:
            args['iops'] = _dict.get('iops')
        if 'mount_targets' in _dict:
            args['mount_targets'] = _dict.get('mount_targets')
        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 SharePrototypeShareContext JSON')
        if 'replication_cron_spec' in _dict:
            args['replication_cron_spec'] = _dict.get('replication_cron_spec')
        else:
            raise ValueError('Required property \'replication_cron_spec\' not present in SharePrototypeShareContext JSON')
        if 'resource_group' in _dict:
            args['resource_group'] = _dict.get('resource_group')
        if 'user_tags' in _dict:
            args['user_tags'] = _dict.get('user_tags')
        if 'zone' in _dict:
            args['zone'] = _dict.get('zone')
        else:
            raise ValueError('Required property \'zone\' not present in SharePrototypeShareContext JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SharePrototypeShareContext object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'iops') and self.iops is not None:
            _dict['iops'] = self.iops
        if hasattr(self, 'mount_targets') and self.mount_targets is not None:
            mount_targets_list = []
            for v in self.mount_targets:
                if isinstance(v, dict):
                    mount_targets_list.append(v)
                else:
                    mount_targets_list.append(v.to_dict())
            _dict['mount_targets'] = mount_targets_list
        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, 'replication_cron_spec') and self.replication_cron_spec is not None:
            _dict['replication_cron_spec'] = self.replication_cron_spec
        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_tags') and self.user_tags is not None:
            _dict['user_tags'] = self.user_tags
        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 SharePrototypeShareContext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'SharePrototypeShareContext') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'SharePrototypeShareContext') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class ShareReference:
    """
    ShareReference.

    :attr str crn: The CRN for this file share.
    :attr ShareReferenceDeleted deleted: (optional) If present, this property
          indicates the referenced resource has been deleted, and provides
          some supplementary information.
    :attr str href: The URL for this file share.
    :attr str id: The unique identifier for this file share.
    :attr str name: The name for this share. The name is unique across all shares in
          the region.
    :attr str resource_type: The resource type.
    """

    def __init__(
        self,
        crn: str,
        href: str,
        id: str,
        name: str,
        resource_type: str,
        *,
        deleted: 'ShareReferenceDeleted' = None,
    ) -> None:
        """
        Initialize a ShareReference object.

        :param str crn: The CRN for this file share.
        :param str href: The URL for this file share.
        :param str id: The unique identifier for this file share.
        :param str name: The name for this share. The name is unique across all
               shares in the region.
        :param str resource_type: The resource type.
        :param ShareReferenceDeleted deleted: (optional) If present, this property
               indicates the referenced resource has been deleted, and provides
               some supplementary information.
        """
        self.crn = crn
        self.deleted = deleted
        self.href = href
        self.id = id
        self.name = name
        self.resource_type = resource_type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ShareReference':
        """Initialize a ShareReference object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError('Required property \'crn\' not present in ShareReference JSON')
        if 'deleted' in _dict:
            args['deleted'] = ShareReferenceDeleted.from_dict(_dict.get('deleted'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in ShareReference JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in ShareReference JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in ShareReference JSON')
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError('Required property \'resource_type\' not present in ShareReference JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ShareReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'deleted') and self.deleted is not None:
            if isinstance(self.deleted, dict):
                _dict['deleted'] = self.deleted
            else:
                _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'resource_type') and self.resource_type is not None:
            _dict['resource_type'] = self.resource_type
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this ShareReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ShareReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ShareReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        SHARE = 'share'



class ShareReferenceDeleted:
    """
    If present, this property indicates the referenced resource has been deleted, and
    provides some supplementary information.

    :attr str more_info: Link to documentation about deleted resources.
    """

    def __init__(
        self,
        more_info: str,
    ) -> None:
        """
        Initialize a ShareReferenceDeleted object.

        :param str more_info: Link to documentation about deleted resources.
        """
        self.more_info = more_info

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ShareReferenceDeleted':
        """Initialize a ShareReferenceDeleted object from a json dictionary."""
        args = {}
        if 'more_info' in _dict:
            args['more_info'] = _dict.get('more_info')
        else:
            raise ValueError('Required property \'more_info\' not present in ShareReferenceDeleted JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ShareReferenceDeleted object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'more_info') and self.more_info is not None:
            _dict['more_info'] = self.more_info
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this ShareReferenceDeleted object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ShareReferenceDeleted') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ShareReferenceDeleted') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class ShareReplicationStatusReason:
    """
    ShareReplicationStatusReason.

    :attr str code: A snake case string succinctly identifying the status reason.
    :attr str message: An explanation of the status reason.
    :attr str more_info: (optional) Link to documentation about this status reason.
    """

    def __init__(
        self,
        code: str,
        message: str,
        *,
        more_info: str = None,
    ) -> None:
        """
        Initialize a ShareReplicationStatusReason object.

        :param str code: A snake case string succinctly identifying the status
               reason.
        :param str message: An explanation of the status reason.
        :param str more_info: (optional) Link to documentation about this status
               reason.
        """
        self.code = code
        self.message = message
        self.more_info = more_info

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ShareReplicationStatusReason':
        """Initialize a ShareReplicationStatusReason object from a json dictionary."""
        args = {}
        if 'code' in _dict:
            args['code'] = _dict.get('code')
        else:
            raise ValueError('Required property \'code\' not present in ShareReplicationStatusReason JSON')
        if 'message' in _dict:
            args['message'] = _dict.get('message')
        else:
            raise ValueError('Required property \'message\' not present in ShareReplicationStatusReason JSON')
        if 'more_info' in _dict:
            args['more_info'] = _dict.get('more_info')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ShareReplicationStatusReason object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'code') and self.code is not None:
            _dict['code'] = self.code
        if hasattr(self, 'message') and self.message is not None:
            _dict['message'] = self.message
        if hasattr(self, 'more_info') and self.more_info is not None:
            _dict['more_info'] = self.more_info
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this ShareReplicationStatusReason object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ShareReplicationStatusReason') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ShareReplicationStatusReason') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class CodeEnum(str, Enum):
        """
        A snake case string succinctly identifying the status reason.
        """

        CANNOT_INITIALIZE_REPLICATION = 'cannot_initialize_replication'
        CANNOT_REACH_REPLICA_SHARE = 'cannot_reach_replica_share'
        CANNOT_REACH_SOURCE_SHARE = 'cannot_reach_source_share'



class Snapshot:
    """
    Snapshot.

    :attr BackupPolicyPlanReference backup_policy_plan: (optional) If present, the
          backup policy plan which created this snapshot.
    :attr bool bootable: Indicates if a boot volume attachment can be created with a
          volume created from this snapshot.
    :attr datetime captured_at: (optional) The date and time the data capture for
          this snapshot was completed.
          If absent, this snapshot's data has not yet been captured. Additionally, this
          property may be absent for snapshots created before 1 January 2022.
    :attr List[SnapshotClone] clones: Clones for this snapshot.
    :attr List[SnapshotCopiesItem] copies: The copies of this snapshot.
    :attr datetime created_at: The date and time that this snapshot was created.
    :attr str crn: The CRN of this snapshot.
    :attr bool deletable: Deprecated: Indicates whether this snapshot can be
          deleted. This value will always be `true`.
    :attr str encryption: The type of encryption used on the source volume.
    :attr EncryptionKeyReference encryption_key: (optional) The root key used to
          wrap the data encryption key for the source volume.
          This property will be present for volumes with an `encryption` type of
          `user_managed`.
    :attr str href: The URL for this snapshot.
    :attr str id: The unique identifier for this snapshot.
    :attr str lifecycle_state: The lifecycle state of this snapshot.
    :attr int minimum_capacity: The minimum capacity of a volume created from this
          snapshot. When a snapshot is created, this will be set to the capacity of the
          `source_volume`.
    :attr str name: The name for this snapshot. The name is unique across all
          snapshots in the region.
    :attr OperatingSystem operating_system: (optional) The operating system included
          in this snapshot.
    :attr ResourceGroupReference resource_group: The resource group for this
          snapshot.
    :attr str resource_type: The resource type.
    :attr List[str] service_tags: The [service
          tags](https://cloud.ibm.com/apidocs/tagging#types-of-tags) prefixed with
          `is.snapshot:` associated with this snapshot.
    :attr int size: The size of this snapshot rounded up to the next gigabyte.
    :attr ImageReference source_image: (optional) If present, the image from which
          the data on this snapshot was most directly
          provisioned.
    :attr SnapshotSourceSnapshot source_snapshot: (optional) If present, the source
          snapshot this snapshot was created from.
    :attr VolumeReference source_volume: The source volume this snapshot was created
          from (may be
          [deleted](https://cloud.ibm.com/apidocs/vpc#deleted-resources)).
    :attr List[str] user_tags: The [user
          tags](https://cloud.ibm.com/apidocs/tagging#types-of-tags) associated with this
          snapshot.
    """

    def __init__(
        self,
        bootable: bool,
        clones: List['SnapshotClone'],
        copies: List['SnapshotCopiesItem'],
        created_at: datetime,
        crn: str,
        deletable: bool,
        encryption: str,
        href: str,
        id: str,
        lifecycle_state: str,
        minimum_capacity: int,
        name: str,
        resource_group: 'ResourceGroupReference',
        resource_type: str,
        service_tags: List[str],
        size: int,
        source_volume: 'VolumeReference',
        user_tags: List[str],
        *,
        backup_policy_plan: 'BackupPolicyPlanReference' = None,
        captured_at: datetime = None,
        encryption_key: 'EncryptionKeyReference' = None,
        operating_system: 'OperatingSystem' = None,
        source_image: 'ImageReference' = None,
        source_snapshot: 'SnapshotSourceSnapshot' = None,
    ) -> None:
        """
        Initialize a Snapshot object.

        :param bool bootable: Indicates if a boot volume attachment can be created
               with a volume created from this snapshot.
        :param List[SnapshotClone] clones: Clones for this snapshot.
        :param List[SnapshotCopiesItem] copies: The copies of this snapshot.
        :param datetime created_at: The date and time that this snapshot was
               created.
        :param str crn: The CRN of this snapshot.
        :param bool deletable: Deprecated: Indicates whether this snapshot can be
               deleted. This value will always be `true`.
        :param str encryption: The type of encryption used on the source volume.
        :param str href: The URL for this snapshot.
        :param str id: The unique identifier for this snapshot.
        :param str lifecycle_state: The lifecycle state of this snapshot.
        :param int minimum_capacity: The minimum capacity of a volume created from
               this snapshot. When a snapshot is created, this will be set to the capacity
               of the `source_volume`.
        :param str name: The name for this snapshot. The name is unique across all
               snapshots in the region.
        :param ResourceGroupReference resource_group: The resource group for this
               snapshot.
        :param str resource_type: The resource type.
        :param List[str] service_tags: The [service
               tags](https://cloud.ibm.com/apidocs/tagging#types-of-tags) prefixed with
               `is.snapshot:` associated with this snapshot.
        :param int size: The size of this snapshot rounded up to the next gigabyte.
        :param VolumeReference source_volume: The source volume this snapshot was
               created from (may be
               [deleted](https://cloud.ibm.com/apidocs/vpc#deleted-resources)).
        :param List[str] user_tags: The [user
               tags](https://cloud.ibm.com/apidocs/tagging#types-of-tags) associated with
               this snapshot.
        :param BackupPolicyPlanReference backup_policy_plan: (optional) If present,
               the backup policy plan which created this snapshot.
        :param datetime captured_at: (optional) The date and time the data capture
               for this snapshot was completed.
               If absent, this snapshot's data has not yet been captured. Additionally,
               this property may be absent for snapshots created before 1 January 2022.
        :param EncryptionKeyReference encryption_key: (optional) The root key used
               to wrap the data encryption key for the source volume.
               This property will be present for volumes with an `encryption` type of
               `user_managed`.
        :param OperatingSystem operating_system: (optional) The operating system
               included in this snapshot.
        :param ImageReference source_image: (optional) If present, the image from
               which the data on this snapshot was most directly
               provisioned.
        :param SnapshotSourceSnapshot source_snapshot: (optional) If present, the
               source snapshot this snapshot was created from.
        """
        self.backup_policy_plan = backup_policy_plan
        self.bootable = bootable
        self.captured_at = captured_at
        self.clones = clones
        self.copies = copies
        self.created_at = created_at
        self.crn = crn
        self.deletable = deletable
        self.encryption = encryption
        self.encryption_key = encryption_key
        self.href = href
        self.id = id
        self.lifecycle_state = lifecycle_state
        self.minimum_capacity = minimum_capacity
        self.name = name
        self.operating_system = operating_system
        self.resource_group = resource_group
        self.resource_type = resource_type
        self.service_tags = service_tags
        self.size = size
        self.source_image = source_image
        self.source_snapshot = source_snapshot
        self.source_volume = source_volume
        self.user_tags = user_tags

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'Snapshot':
        """Initialize a Snapshot object from a json dictionary."""
        args = {}
        if 'backup_policy_plan' in _dict:
            args['backup_policy_plan'] = BackupPolicyPlanReference.from_dict(_dict.get('backup_policy_plan'))
        if 'bootable' in _dict:
            args['bootable'] = _dict.get('bootable')
        else:
            raise ValueError('Required property \'bootable\' not present in Snapshot JSON')
        if 'captured_at' in _dict:
            args['captured_at'] = string_to_datetime(_dict.get('captured_at'))
        if 'clones' in _dict:
            args['clones'] = [SnapshotClone.from_dict(v) for v in _dict.get('clones')]
        else:
            raise ValueError('Required property \'clones\' not present in Snapshot JSON')
        if 'copies' in _dict:
            args['copies'] = [SnapshotCopiesItem.from_dict(v) for v in _dict.get('copies')]
        else:
            raise ValueError('Required property \'copies\' not present in Snapshot 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 Snapshot JSON')
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError('Required property \'crn\' not present in Snapshot JSON')
        if 'deletable' in _dict:
            args['deletable'] = _dict.get('deletable')
        else:
            raise ValueError('Required property \'deletable\' not present in Snapshot JSON')
        if 'encryption' in _dict:
            args['encryption'] = _dict.get('encryption')
        else:
            raise ValueError('Required property \'encryption\' not present in Snapshot 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 Snapshot JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in Snapshot JSON')
        if 'lifecycle_state' in _dict:
            args['lifecycle_state'] = _dict.get('lifecycle_state')
        else:
            raise ValueError('Required property \'lifecycle_state\' not present in Snapshot JSON')
        if 'minimum_capacity' in _dict:
            args['minimum_capacity'] = _dict.get('minimum_capacity')
        else:
            raise ValueError('Required property \'minimum_capacity\' not present in Snapshot JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in Snapshot 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 Snapshot JSON')
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError('Required property \'resource_type\' not present in Snapshot JSON')
        if 'service_tags' in _dict:
            args['service_tags'] = _dict.get('service_tags')
        else:
            raise ValueError('Required property \'service_tags\' not present in Snapshot JSON')
        if 'size' in _dict:
            args['size'] = _dict.get('size')
        else:
            raise ValueError('Required property \'size\' not present in Snapshot JSON')
        if 'source_image' in _dict:
            args['source_image'] = ImageReference.from_dict(_dict.get('source_image'))
        if 'source_snapshot' in _dict:
            args['source_snapshot'] = SnapshotSourceSnapshot.from_dict(_dict.get('source_snapshot'))
        if 'source_volume' in _dict:
            args['source_volume'] = VolumeReference.from_dict(_dict.get('source_volume'))
        else:
            raise ValueError('Required property \'source_volume\' not present in Snapshot JSON')
        if 'user_tags' in _dict:
            args['user_tags'] = _dict.get('user_tags')
        else:
            raise ValueError('Required property \'user_tags\' not present in Snapshot JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a Snapshot object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'backup_policy_plan') and self.backup_policy_plan is not None:
            if isinstance(self.backup_policy_plan, dict):
                _dict['backup_policy_plan'] = self.backup_policy_plan
            else:
                _dict['backup_policy_plan'] = self.backup_policy_plan.to_dict()
        if hasattr(self, 'bootable') and self.bootable is not None:
            _dict['bootable'] = self.bootable
        if hasattr(self, 'captured_at') and self.captured_at is not None:
            _dict['captured_at'] = datetime_to_string(self.captured_at)
        if hasattr(self, 'clones') and self.clones is not None:
            clones_list = []
            for v in self.clones:
                if isinstance(v, dict):
                    clones_list.append(v)
                else:
                    clones_list.append(v.to_dict())
            _dict['clones'] = clones_list
        if hasattr(self, 'copies') and self.copies is not None:
            copies_list = []
            for v in self.copies:
                if isinstance(v, dict):
                    copies_list.append(v)
                else:
                    copies_list.append(v.to_dict())
            _dict['copies'] = copies_list
        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, 'deletable') and self.deletable is not None:
            _dict['deletable'] = self.deletable
        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:
            if isinstance(self.encryption_key, dict):
                _dict['encryption_key'] = self.encryption_key
            else:
                _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, 'lifecycle_state') and self.lifecycle_state is not None:
            _dict['lifecycle_state'] = self.lifecycle_state
        if hasattr(self, 'minimum_capacity') and self.minimum_capacity is not None:
            _dict['minimum_capacity'] = self.minimum_capacity
        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:
            if isinstance(self.operating_system, dict):
                _dict['operating_system'] = self.operating_system
            else:
                _dict['operating_system'] = self.operating_system.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, 'resource_type') and self.resource_type is not None:
            _dict['resource_type'] = self.resource_type
        if hasattr(self, 'service_tags') and self.service_tags is not None:
            _dict['service_tags'] = self.service_tags
        if hasattr(self, 'size') and self.size is not None:
            _dict['size'] = self.size
        if hasattr(self, 'source_image') and self.source_image is not None:
            if isinstance(self.source_image, dict):
                _dict['source_image'] = self.source_image
            else:
                _dict['source_image'] = self.source_image.to_dict()
        if hasattr(self, 'source_snapshot') and self.source_snapshot is not None:
            if isinstance(self.source_snapshot, dict):
                _dict['source_snapshot'] = self.source_snapshot
            else:
                _dict['source_snapshot'] = self.source_snapshot.to_dict()
        if hasattr(self, 'source_volume') and self.source_volume is not None:
            if isinstance(self.source_volume, dict):
                _dict['source_volume'] = self.source_volume
            else:
                _dict['source_volume'] = self.source_volume.to_dict()
        if hasattr(self, 'user_tags') and self.user_tags is not None:
            _dict['user_tags'] = self.user_tags
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this Snapshot object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'Snapshot') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'Snapshot') -> 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 source volume.
        """

        PROVIDER_MANAGED = 'provider_managed'
        USER_MANAGED = 'user_managed'


    class LifecycleStateEnum(str, Enum):
        """
        The lifecycle state of this snapshot.
        """

        DELETING = 'deleting'
        FAILED = 'failed'
        PENDING = 'pending'
        STABLE = 'stable'
        SUSPENDED = 'suspended'
        UPDATING = 'updating'
        WAITING = 'waiting'


    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        SNAPSHOT = 'snapshot'



class SnapshotClone:
    """
    SnapshotClone.

    :attr bool available: Indicates whether this snapshot clone is available for
          use.
    :attr datetime created_at: The date and time that this snapshot clone was
          created.
    :attr ZoneReference zone: The zone this snapshot clone resides in.
    """

    def __init__(
        self,
        available: bool,
        created_at: datetime,
        zone: 'ZoneReference',
    ) -> None:
        """
        Initialize a SnapshotClone object.

        :param bool available: Indicates whether this snapshot clone is available
               for use.
        :param datetime created_at: The date and time that this snapshot clone was
               created.
        :param ZoneReference zone: The zone this snapshot clone resides in.
        """
        self.available = available
        self.created_at = created_at
        self.zone = zone

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'SnapshotClone':
        """Initialize a SnapshotClone object from a json dictionary."""
        args = {}
        if 'available' in _dict:
            args['available'] = _dict.get('available')
        else:
            raise ValueError('Required property \'available\' not present in SnapshotClone 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 SnapshotClone JSON')
        if 'zone' in _dict:
            args['zone'] = ZoneReference.from_dict(_dict.get('zone'))
        else:
            raise ValueError('Required property \'zone\' not present in SnapshotClone JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SnapshotClone object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'available') and self.available is not None:
            _dict['available'] = self.available
        if hasattr(self, 'created_at') and self.created_at is not None:
            _dict['created_at'] = datetime_to_string(self.created_at)
        if hasattr(self, '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 SnapshotClone object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'SnapshotClone') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'SnapshotClone') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class SnapshotCloneCollection:
    """
    SnapshotCloneCollection.

    :attr List[SnapshotClone] clones: Collection of snapshot clones.
    """

    def __init__(
        self,
        clones: List['SnapshotClone'],
    ) -> None:
        """
        Initialize a SnapshotCloneCollection object.

        :param List[SnapshotClone] clones: Collection of snapshot clones.
        """
        self.clones = clones

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'SnapshotCloneCollection':
        """Initialize a SnapshotCloneCollection object from a json dictionary."""
        args = {}
        if 'clones' in _dict:
            args['clones'] = [SnapshotClone.from_dict(v) for v in _dict.get('clones')]
        else:
            raise ValueError('Required property \'clones\' not present in SnapshotCloneCollection JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SnapshotCloneCollection object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'clones') and self.clones is not None:
            clones_list = []
            for v in self.clones:
                if isinstance(v, dict):
                    clones_list.append(v)
                else:
                    clones_list.append(v.to_dict())
            _dict['clones'] = clones_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 SnapshotCloneCollection object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'SnapshotCloneCollection') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'SnapshotCloneCollection') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class SnapshotClonePrototype:
    """
    SnapshotClonePrototype.

    :attr ZoneIdentity zone: The zone this snapshot clone will reside in. Must be in
          the same region as the
          snapshot.
    """

    def __init__(
        self,
        zone: 'ZoneIdentity',
    ) -> None:
        """
        Initialize a SnapshotClonePrototype object.

        :param ZoneIdentity zone: The zone this snapshot clone will reside in. Must
               be in the same region as the
               snapshot.
        """
        self.zone = zone

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'SnapshotClonePrototype':
        """Initialize a SnapshotClonePrototype object from a json dictionary."""
        args = {}
        if 'zone' in _dict:
            args['zone'] = _dict.get('zone')
        else:
            raise ValueError('Required property \'zone\' not present in SnapshotClonePrototype JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SnapshotClonePrototype object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _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 SnapshotClonePrototype object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'SnapshotClonePrototype') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'SnapshotClonePrototype') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class SnapshotCollection:
    """
    SnapshotCollection.

    :attr SnapshotCollectionFirst 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 SnapshotCollectionNext next: (optional) A link to the next page of
          resources. This property is present for all pages
          except the last page.
    :attr List[Snapshot] snapshots: Collection of snapshots.
    :attr int total_count: The total number of resources across all pages.
    """

    def __init__(
        self,
        first: 'SnapshotCollectionFirst',
        limit: int,
        snapshots: List['Snapshot'],
        total_count: int,
        *,
        next: 'SnapshotCollectionNext' = None,
    ) -> None:
        """
        Initialize a SnapshotCollection object.

        :param SnapshotCollectionFirst 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[Snapshot] snapshots: Collection of snapshots.
        :param int total_count: The total number of resources across all pages.
        :param SnapshotCollectionNext 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.snapshots = snapshots
        self.total_count = total_count

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'SnapshotCollection':
        """Initialize a SnapshotCollection object from a json dictionary."""
        args = {}
        if 'first' in _dict:
            args['first'] = SnapshotCollectionFirst.from_dict(_dict.get('first'))
        else:
            raise ValueError('Required property \'first\' not present in SnapshotCollection JSON')
        if 'limit' in _dict:
            args['limit'] = _dict.get('limit')
        else:
            raise ValueError('Required property \'limit\' not present in SnapshotCollection JSON')
        if 'next' in _dict:
            args['next'] = SnapshotCollectionNext.from_dict(_dict.get('next'))
        if 'snapshots' in _dict:
            args['snapshots'] = [Snapshot.from_dict(v) for v in _dict.get('snapshots')]
        else:
            raise ValueError('Required property \'snapshots\' not present in SnapshotCollection JSON')
        if 'total_count' in _dict:
            args['total_count'] = _dict.get('total_count')
        else:
            raise ValueError('Required property \'total_count\' not present in SnapshotCollection JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SnapshotCollection object from 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:
            if isinstance(self.first, dict):
                _dict['first'] = self.first
            else:
                _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:
            if isinstance(self.next, dict):
                _dict['next'] = self.next
            else:
                _dict['next'] = self.next.to_dict()
        if hasattr(self, 'snapshots') and self.snapshots is not None:
            snapshots_list = []
            for v in self.snapshots:
                if isinstance(v, dict):
                    snapshots_list.append(v)
                else:
                    snapshots_list.append(v.to_dict())
            _dict['snapshots'] = snapshots_list
        if hasattr(self, 'total_count') and self.total_count is not None:
            _dict['total_count'] = self.total_count
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this SnapshotCollection object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'SnapshotCollection') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'SnapshotCollection') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class SnapshotCollectionFirst:
    """
    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 SnapshotCollectionFirst object.

        :param str href: The URL for a page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'SnapshotCollectionFirst':
        """Initialize a SnapshotCollectionFirst object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in SnapshotCollectionFirst JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SnapshotCollectionFirst object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(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 SnapshotCollectionFirst object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'SnapshotCollectionFirst') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'SnapshotCollectionFirst') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class SnapshotCollectionNext:
    """
    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 SnapshotCollectionNext object.

        :param str href: The URL for a page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'SnapshotCollectionNext':
        """Initialize a SnapshotCollectionNext object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in SnapshotCollectionNext JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SnapshotCollectionNext object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(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 SnapshotCollectionNext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'SnapshotCollectionNext') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'SnapshotCollectionNext') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class SnapshotCopiesItem:
    """
    SnapshotCopiesItem.

    :attr str crn: The CRN for the copied snapshot.
    :attr SnapshotReferenceDeleted deleted: (optional) If present, this property
          indicates the referenced resource has been deleted, and provides
          some supplementary information.
    :attr str href: The URL for the copied snapshot.
    :attr str id: The unique identifier for the copied snapshot.
    :attr str name: The name for the copied snapshot.
    :attr SnapshotRemote remote: (optional) If present, this property indicates that
          the resource associated with this reference
          is remote and therefore may not be directly retrievable.
    :attr str resource_type: The resource type.
    """

    def __init__(
        self,
        crn: str,
        href: str,
        id: str,
        name: str,
        resource_type: str,
        *,
        deleted: 'SnapshotReferenceDeleted' = None,
        remote: 'SnapshotRemote' = None,
    ) -> None:
        """
        Initialize a SnapshotCopiesItem object.

        :param str crn: The CRN for the copied snapshot.
        :param str href: The URL for the copied snapshot.
        :param str id: The unique identifier for the copied snapshot.
        :param str name: The name for the copied snapshot.
        :param str resource_type: The resource type.
        :param SnapshotReferenceDeleted deleted: (optional) If present, this
               property indicates the referenced resource has been deleted, and provides
               some supplementary information.
        :param SnapshotRemote remote: (optional) If present, this property
               indicates that the resource associated with this reference
               is remote and therefore may not be directly retrievable.
        """
        self.crn = crn
        self.deleted = deleted
        self.href = href
        self.id = id
        self.name = name
        self.remote = remote
        self.resource_type = resource_type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'SnapshotCopiesItem':
        """Initialize a SnapshotCopiesItem object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError('Required property \'crn\' not present in SnapshotCopiesItem JSON')
        if 'deleted' in _dict:
            args['deleted'] = SnapshotReferenceDeleted.from_dict(_dict.get('deleted'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in SnapshotCopiesItem JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in SnapshotCopiesItem JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in SnapshotCopiesItem JSON')
        if 'remote' in _dict:
            args['remote'] = SnapshotRemote.from_dict(_dict.get('remote'))
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError('Required property \'resource_type\' not present in SnapshotCopiesItem JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SnapshotCopiesItem object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'deleted') and self.deleted is not None:
            if isinstance(self.deleted, dict):
                _dict['deleted'] = self.deleted
            else:
                _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, '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, '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 SnapshotCopiesItem object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'SnapshotCopiesItem') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'SnapshotCopiesItem') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        SNAPSHOT = 'snapshot'



class SnapshotIdentity:
    """
    Identifies a snapshot by a unique property.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a SnapshotIdentity object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['SnapshotIdentityById', 'SnapshotIdentityByCRN', 'SnapshotIdentityByHref'])
        )
        raise Exception(msg)


class SnapshotPatch:
    """
    SnapshotPatch.

    :attr str name: (optional) The name for this snapshot. The name must not be used
          by another snapshot in the region.
    :attr List[str] user_tags: (optional) The [user
          tags](https://cloud.ibm.com/apidocs/tagging#types-of-tags) associated with this
          snapshot.
    """

    def __init__(
        self,
        *,
        name: str = None,
        user_tags: List[str] = None,
    ) -> None:
        """
        Initialize a SnapshotPatch object.

        :param str name: (optional) The name for this snapshot. The name must not
               be used by another snapshot in the region.
        :param List[str] user_tags: (optional) The [user
               tags](https://cloud.ibm.com/apidocs/tagging#types-of-tags) associated with
               this snapshot.
        """
        self.name = name
        self.user_tags = user_tags

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'SnapshotPatch':
        """Initialize a SnapshotPatch object from a json dictionary."""
        args = {}
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        if 'user_tags' in _dict:
            args['user_tags'] = _dict.get('user_tags')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SnapshotPatch object from 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, 'user_tags') and self.user_tags is not None:
            _dict['user_tags'] = self.user_tags
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this SnapshotPatch object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'SnapshotPatch') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'SnapshotPatch') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class SnapshotPrototype:
    """
    SnapshotPrototype.

    :attr List[SnapshotClonePrototype] clones: (optional) Clones to create for this
          snapshot.
    :attr str name: (optional) The name for this snapshot. The name must not be used
          by another snapshot in the region. 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) will be
          used.
    :attr List[str] user_tags: (optional) The [user
          tags](https://cloud.ibm.com/apidocs/tagging#types-of-tags) associated with this
          snapshot.
    """

    def __init__(
        self,
        *,
        clones: List['SnapshotClonePrototype'] = None,
        name: str = None,
        resource_group: 'ResourceGroupIdentity' = None,
        user_tags: List[str] = None,
    ) -> None:
        """
        Initialize a SnapshotPrototype object.

        :param List[SnapshotClonePrototype] clones: (optional) Clones to create for
               this snapshot.
        :param str name: (optional) The name for this snapshot. The name must not
               be used by another snapshot in the region. 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) will be
               used.
        :param List[str] user_tags: (optional) The [user
               tags](https://cloud.ibm.com/apidocs/tagging#types-of-tags) associated with
               this snapshot.
        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['SnapshotPrototypeSnapshotBySourceVolume', 'SnapshotPrototypeSnapshotBySourceSnapshot'])
        )
        raise Exception(msg)


class SnapshotReference:
    """
    SnapshotReference.

    :attr str crn: The CRN of this snapshot.
    :attr SnapshotReferenceDeleted deleted: (optional) If present, this property
          indicates the referenced resource has been deleted, and provides
          some supplementary information.
    :attr str href: The URL for this snapshot.
    :attr str id: The unique identifier for this snapshot.
    :attr str name: The name for this snapshot. The name is unique across all
          snapshots in the region.
    :attr SnapshotRemote remote: (optional) If present, this property indicates that
          the resource associated with this reference
          is remote and therefore may not be directly retrievable.
    :attr str resource_type: The resource type.
    """

    def __init__(
        self,
        crn: str,
        href: str,
        id: str,
        name: str,
        resource_type: str,
        *,
        deleted: 'SnapshotReferenceDeleted' = None,
        remote: 'SnapshotRemote' = None,
    ) -> None:
        """
        Initialize a SnapshotReference object.

        :param str crn: The CRN of this snapshot.
        :param str href: The URL for this snapshot.
        :param str id: The unique identifier for this snapshot.
        :param str name: The name for this snapshot. The name is unique across all
               snapshots in the region.
        :param str resource_type: The resource type.
        :param SnapshotReferenceDeleted deleted: (optional) If present, this
               property indicates the referenced resource has been deleted, and provides
               some supplementary information.
        :param SnapshotRemote remote: (optional) If present, this property
               indicates that the resource associated with this reference
               is remote and therefore may not be directly retrievable.
        """
        self.crn = crn
        self.deleted = deleted
        self.href = href
        self.id = id
        self.name = name
        self.remote = remote
        self.resource_type = resource_type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'SnapshotReference':
        """Initialize a SnapshotReference object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError('Required property \'crn\' not present in SnapshotReference JSON')
        if 'deleted' in _dict:
            args['deleted'] = SnapshotReferenceDeleted.from_dict(_dict.get('deleted'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in SnapshotReference JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in SnapshotReference JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in SnapshotReference JSON')
        if 'remote' in _dict:
            args['remote'] = SnapshotRemote.from_dict(_dict.get('remote'))
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError('Required property \'resource_type\' not present in SnapshotReference JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SnapshotReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'deleted') and self.deleted is not None:
            if isinstance(self.deleted, dict):
                _dict['deleted'] = self.deleted
            else:
                _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, '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, '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 SnapshotReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'SnapshotReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'SnapshotReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        SNAPSHOT = 'snapshot'



class SnapshotReferenceDeleted:
    """
    If present, this property indicates the referenced resource has been deleted, and
    provides some supplementary information.

    :attr str more_info: Link to documentation about deleted resources.
    """

    def __init__(
        self,
        more_info: str,
    ) -> None:
        """
        Initialize a SnapshotReferenceDeleted object.

        :param str more_info: Link to documentation about deleted resources.
        """
        self.more_info = more_info

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'SnapshotReferenceDeleted':
        """Initialize a SnapshotReferenceDeleted object from a json dictionary."""
        args = {}
        if 'more_info' in _dict:
            args['more_info'] = _dict.get('more_info')
        else:
            raise ValueError('Required property \'more_info\' not present in SnapshotReferenceDeleted JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SnapshotReferenceDeleted object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'more_info') and self.more_info is not None:
            _dict['more_info'] = self.more_info
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this SnapshotReferenceDeleted object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'SnapshotReferenceDeleted') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'SnapshotReferenceDeleted') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class SnapshotRemote:
    """
    If present, this property indicates that the resource associated with this reference
    is remote and therefore may not be directly retrievable.

    :attr RegionReference region: (optional) If present, this property indicates
          that the referenced resource is remote to this
          region, and identifies the native region.
    """

    def __init__(
        self,
        *,
        region: 'RegionReference' = None,
    ) -> None:
        """
        Initialize a SnapshotRemote object.

        :param RegionReference region: (optional) If present, this property
               indicates that the referenced resource is remote to this
               region, and identifies the native region.
        """
        self.region = region

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'SnapshotRemote':
        """Initialize a SnapshotRemote object from a json dictionary."""
        args = {}
        if 'region' in _dict:
            args['region'] = RegionReference.from_dict(_dict.get('region'))
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SnapshotRemote object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'region') and self.region is not None:
            if isinstance(self.region, dict):
                _dict['region'] = self.region
            else:
                _dict['region'] = self.region.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 SnapshotRemote object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'SnapshotRemote') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'SnapshotRemote') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class SnapshotSourceSnapshot:
    """
    If present, the source snapshot this snapshot was created from.

    :attr str crn: The CRN of the source snapshot.
    :attr SnapshotReferenceDeleted deleted: (optional) If present, this property
          indicates the referenced resource has been deleted, and provides
          some supplementary information.
    :attr str href: The URL for the source snapshot.
    :attr str id: The unique identifier for the source snapshot.
    :attr str name: The name for the source snapshot. The name is unique across all
          snapshots in the source snapshot's native region.
    :attr SnapshotRemote remote: (optional) If present, this property indicates that
          the resource associated with this reference
          is remote and therefore may not be directly retrievable.
    :attr str resource_type: The resource type.
    """

    def __init__(
        self,
        crn: str,
        href: str,
        id: str,
        name: str,
        resource_type: str,
        *,
        deleted: 'SnapshotReferenceDeleted' = None,
        remote: 'SnapshotRemote' = None,
    ) -> None:
        """
        Initialize a SnapshotSourceSnapshot object.

        :param str crn: The CRN of the source snapshot.
        :param str href: The URL for the source snapshot.
        :param str id: The unique identifier for the source snapshot.
        :param str name: The name for the source snapshot. The name is unique
               across all snapshots in the source snapshot's native region.
        :param str resource_type: The resource type.
        :param SnapshotReferenceDeleted deleted: (optional) If present, this
               property indicates the referenced resource has been deleted, and provides
               some supplementary information.
        :param SnapshotRemote remote: (optional) If present, this property
               indicates that the resource associated with this reference
               is remote and therefore may not be directly retrievable.
        """
        self.crn = crn
        self.deleted = deleted
        self.href = href
        self.id = id
        self.name = name
        self.remote = remote
        self.resource_type = resource_type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'SnapshotSourceSnapshot':
        """Initialize a SnapshotSourceSnapshot object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError('Required property \'crn\' not present in SnapshotSourceSnapshot JSON')
        if 'deleted' in _dict:
            args['deleted'] = SnapshotReferenceDeleted.from_dict(_dict.get('deleted'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in SnapshotSourceSnapshot JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in SnapshotSourceSnapshot JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in SnapshotSourceSnapshot JSON')
        if 'remote' in _dict:
            args['remote'] = SnapshotRemote.from_dict(_dict.get('remote'))
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError('Required property \'resource_type\' not present in SnapshotSourceSnapshot JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SnapshotSourceSnapshot object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'deleted') and self.deleted is not None:
            if isinstance(self.deleted, dict):
                _dict['deleted'] = self.deleted
            else:
                _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, '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, '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 SnapshotSourceSnapshot object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'SnapshotSourceSnapshot') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'SnapshotSourceSnapshot') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        SNAPSHOT = 'snapshot'



class Subnet:
    """
    Subnet.

    :attr int available_ipv4_address_count: The number of IPv4 addresses in this
          subnet that are not in-use, and have not been reserved by the user or the
          provider.
    :attr datetime created_at: The date and time that the subnet was created.
    :attr str crn: The CRN for this subnet.
    :attr str href: The URL for this subnet.
    :attr str id: The unique identifier for this subnet.
    :attr str ip_version: The IP version(s) supported by this subnet.
    :attr str ipv4_cidr_block: The IPv4 range of the subnet, expressed in CIDR
          format.
    :attr str name: The name for this subnet. The name is unique across all subnets
          in the VPC.
    :attr NetworkACLReference network_acl: The network ACL for this subnet.
    :attr PublicGatewayReference public_gateway: (optional) The public gateway to
          use for internet-bound traffic for this subnet.
    :attr ResourceGroupReference resource_group: The resource group for this subnet.
    :attr str resource_type: The resource type.
    :attr RoutingTableReference routing_table: The routing table for this subnet.
    :attr str status: The status of the subnet.
    :attr int total_ipv4_address_count: The total number of IPv4 addresses in this
          subnet.
          Note: This is calculated as 2<sup>(32 - prefix length)</sup>. For example, the
          prefix length `/24` gives:<br> 2<sup>(32 - 24)</sup> = 2<sup>8</sup> = 256
          addresses.
    :attr VPCReference vpc: The VPC this subnet resides in.
    :attr ZoneReference zone: The zone this subnet resides in.
    """

    def __init__(
        self,
        available_ipv4_address_count: int,
        created_at: datetime,
        crn: str,
        href: str,
        id: str,
        ip_version: str,
        ipv4_cidr_block: str,
        name: str,
        network_acl: 'NetworkACLReference',
        resource_group: 'ResourceGroupReference',
        resource_type: str,
        routing_table: 'RoutingTableReference',
        status: str,
        total_ipv4_address_count: int,
        vpc: 'VPCReference',
        zone: 'ZoneReference',
        *,
        public_gateway: 'PublicGatewayReference' = None,
    ) -> None:
        """
        Initialize a Subnet object.

        :param int available_ipv4_address_count: The number of IPv4 addresses in
               this subnet that are not in-use, and have not been reserved by the user or
               the provider.
        :param datetime created_at: The date and time that the subnet was created.
        :param str crn: The CRN for this subnet.
        :param str href: The URL for this subnet.
        :param str id: The unique identifier for this subnet.
        :param str ip_version: The IP version(s) supported by this subnet.
        :param str ipv4_cidr_block: The IPv4 range of the subnet, expressed in CIDR
               format.
        :param str name: The name for this subnet. The name is unique across all
               subnets in the VPC.
        :param NetworkACLReference network_acl: The network ACL for this subnet.
        :param ResourceGroupReference resource_group: The resource group for this
               subnet.
        :param str resource_type: The resource type.
        :param RoutingTableReference routing_table: The routing table for this
               subnet.
        :param str status: The status of the subnet.
        :param int total_ipv4_address_count: The total number of IPv4 addresses in
               this subnet.
               Note: This is calculated as 2<sup>(32 - prefix length)</sup>. For example,
               the prefix length `/24` gives:<br> 2<sup>(32 - 24)</sup> = 2<sup>8</sup> =
               256 addresses.
        :param VPCReference vpc: The VPC this subnet resides in.
        :param ZoneReference zone: The zone this subnet resides in.
        :param PublicGatewayReference public_gateway: (optional) The public gateway
               to use for internet-bound traffic for this subnet.
        """
        self.available_ipv4_address_count = available_ipv4_address_count
        self.created_at = created_at
        self.crn = crn
        self.href = href
        self.id = id
        self.ip_version = ip_version
        self.ipv4_cidr_block = ipv4_cidr_block
        self.name = name
        self.network_acl = network_acl
        self.public_gateway = public_gateway
        self.resource_group = resource_group
        self.resource_type = resource_type
        self.routing_table = routing_table
        self.status = status
        self.total_ipv4_address_count = total_ipv4_address_count
        self.vpc = vpc
        self.zone = zone

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'Subnet':
        """Initialize a Subnet object from a json dictionary."""
        args = {}
        if 'available_ipv4_address_count' in _dict:
            args['available_ipv4_address_count'] = _dict.get('available_ipv4_address_count')
        else:
            raise ValueError('Required property \'available_ipv4_address_count\' not present in Subnet JSON')
        if 'created_at' in _dict:
            args['created_at'] = string_to_datetime(_dict.get('created_at'))
        else:
            raise ValueError('Required property \'created_at\' not present in Subnet JSON')
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError('Required property \'crn\' not present in Subnet JSON')
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in Subnet JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in Subnet JSON')
        if 'ip_version' in _dict:
            args['ip_version'] = _dict.get('ip_version')
        else:
            raise ValueError('Required property \'ip_version\' not present in Subnet JSON')
        if 'ipv4_cidr_block' in _dict:
            args['ipv4_cidr_block'] = _dict.get('ipv4_cidr_block')
        else:
            raise ValueError('Required property \'ipv4_cidr_block\' not present in Subnet JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in Subnet JSON')
        if 'network_acl' in _dict:
            args['network_acl'] = NetworkACLReference.from_dict(_dict.get('network_acl'))
        else:
            raise ValueError('Required property \'network_acl\' not present in Subnet JSON')
        if 'public_gateway' in _dict:
            args['public_gateway'] = PublicGatewayReference.from_dict(_dict.get('public_gateway'))
        if 'resource_group' in _dict:
            args['resource_group'] = ResourceGroupReference.from_dict(_dict.get('resource_group'))
        else:
            raise ValueError('Required property \'resource_group\' not present in Subnet JSON')
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError('Required property \'resource_type\' not present in Subnet JSON')
        if 'routing_table' in _dict:
            args['routing_table'] = RoutingTableReference.from_dict(_dict.get('routing_table'))
        else:
            raise ValueError('Required property \'routing_table\' not present in Subnet JSON')
        if 'status' in _dict:
            args['status'] = _dict.get('status')
        else:
            raise ValueError('Required property \'status\' not present in Subnet JSON')
        if 'total_ipv4_address_count' in _dict:
            args['total_ipv4_address_count'] = _dict.get('total_ipv4_address_count')
        else:
            raise ValueError('Required property \'total_ipv4_address_count\' not present in Subnet JSON')
        if 'vpc' in _dict:
            args['vpc'] = VPCReference.from_dict(_dict.get('vpc'))
        else:
            raise ValueError('Required property \'vpc\' not present in Subnet JSON')
        if 'zone' in _dict:
            args['zone'] = ZoneReference.from_dict(_dict.get('zone'))
        else:
            raise ValueError('Required property \'zone\' not present in Subnet JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a Subnet object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'available_ipv4_address_count') and self.available_ipv4_address_count is not None:
            _dict['available_ipv4_address_count'] = self.available_ipv4_address_count
        if hasattr(self, 'created_at') and self.created_at is not None:
            _dict['created_at'] = datetime_to_string(self.created_at)
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'ip_version') and self.ip_version is not None:
            _dict['ip_version'] = self.ip_version
        if hasattr(self, 'ipv4_cidr_block') and self.ipv4_cidr_block is not None:
            _dict['ipv4_cidr_block'] = self.ipv4_cidr_block
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'network_acl') and self.network_acl is not None:
            if isinstance(self.network_acl, dict):
                _dict['network_acl'] = self.network_acl
            else:
                _dict['network_acl'] = self.network_acl.to_dict()
        if hasattr(self, 'public_gateway') and self.public_gateway is not None:
            if isinstance(self.public_gateway, dict):
                _dict['public_gateway'] = self.public_gateway
            else:
                _dict['public_gateway'] = self.public_gateway.to_dict()
        if hasattr(self, 'resource_group') and self.resource_group is not None:
            if isinstance(self.resource_group, dict):
                _dict['resource_group'] = self.resource_group
            else:
                _dict['resource_group'] = self.resource_group.to_dict()
        if hasattr(self, 'resource_type') and self.resource_type is not None:
            _dict['resource_type'] = self.resource_type
        if hasattr(self, 'routing_table') and self.routing_table is not None:
            if isinstance(self.routing_table, dict):
                _dict['routing_table'] = self.routing_table
            else:
                _dict['routing_table'] = self.routing_table.to_dict()
        if hasattr(self, '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:
            if isinstance(self.vpc, dict):
                _dict['vpc'] = self.vpc
            else:
                _dict['vpc'] = self.vpc.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 Subnet object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'Subnet') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'Subnet') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class IpVersionEnum(str, Enum):
        """
        The IP version(s) supported by this subnet.
        """

        IPV4 = 'ipv4'


    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        SUBNET = 'subnet'


    class StatusEnum(str, Enum):
        """
        The status of the subnet.
        """

        AVAILABLE = 'available'
        DELETING = 'deleting'
        FAILED = 'failed'
        PENDING = 'pending'



class SubnetCollection:
    """
    SubnetCollection.

    :attr SubnetCollectionFirst first: A link to the first page of resources.
    :attr int limit: The maximum number of resources that can be returned by the
          request.
    :attr SubnetCollectionNext next: (optional) A link to the next page of
          resources. This property is present for all pages
          except the last page.
    :attr List[Subnet] subnets: Collection of subnets.
    :attr int total_count: The total number of resources across all pages.
    """

    def __init__(
        self,
        first: 'SubnetCollectionFirst',
        limit: int,
        subnets: List['Subnet'],
        total_count: int,
        *,
        next: 'SubnetCollectionNext' = None,
    ) -> None:
        """
        Initialize a SubnetCollection object.

        :param SubnetCollectionFirst first: A link to the first page of resources.
        :param int limit: The maximum number of resources that can be returned by
               the request.
        :param List[Subnet] subnets: Collection of subnets.
        :param int total_count: The total number of resources across all pages.
        :param SubnetCollectionNext next: (optional) A link to the next page of
               resources. This property is present for all pages
               except the last page.
        """
        self.first = first
        self.limit = limit
        self.next = next
        self.subnets = subnets
        self.total_count = total_count

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'SubnetCollection':
        """Initialize a SubnetCollection object from a json dictionary."""
        args = {}
        if 'first' in _dict:
            args['first'] = SubnetCollectionFirst.from_dict(_dict.get('first'))
        else:
            raise ValueError('Required property \'first\' not present in SubnetCollection JSON')
        if 'limit' in _dict:
            args['limit'] = _dict.get('limit')
        else:
            raise ValueError('Required property \'limit\' not present in SubnetCollection JSON')
        if 'next' in _dict:
            args['next'] = SubnetCollectionNext.from_dict(_dict.get('next'))
        if 'subnets' in _dict:
            args['subnets'] = [Subnet.from_dict(v) for v in _dict.get('subnets')]
        else:
            raise ValueError('Required property \'subnets\' not present in SubnetCollection JSON')
        if 'total_count' in _dict:
            args['total_count'] = _dict.get('total_count')
        else:
            raise ValueError('Required property \'total_count\' not present in SubnetCollection JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SubnetCollection object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'first') and self.first is not None:
            if isinstance(self.first, dict):
                _dict['first'] = self.first
            else:
                _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:
            if isinstance(self.next, dict):
                _dict['next'] = self.next
            else:
                _dict['next'] = self.next.to_dict()
        if hasattr(self, 'subnets') and self.subnets is not None:
            subnets_list = []
            for v in self.subnets:
                if isinstance(v, dict):
                    subnets_list.append(v)
                else:
                    subnets_list.append(v.to_dict())
            _dict['subnets'] = subnets_list
        if hasattr(self, 'total_count') and self.total_count is not None:
            _dict['total_count'] = self.total_count
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this 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 name for this subnet. The name must not be used
          by another subnet in the VPC.
    :attr NetworkACLIdentity network_acl: (optional) The network ACL to use for this
          subnet.
    :attr SubnetPublicGatewayPatch public_gateway: (optional) The public gateway to
          use for internet-bound traffic for this subnet.
    :attr RoutingTableIdentity routing_table: (optional) The routing table to use
          for this subnet.  The routing table properties
          `route_direct_link_ingress`, `route_internet_ingress`,
          `route_transit_gateway_ingress`, and `route_vpc_zone_ingress` must be `false`.
    """

    def __init__(
        self,
        *,
        name: str = None,
        network_acl: 'NetworkACLIdentity' = None,
        public_gateway: 'SubnetPublicGatewayPatch' = None,
        routing_table: 'RoutingTableIdentity' = None,
    ) -> None:
        """
        Initialize a SubnetPatch object.

        :param str name: (optional) The name for this subnet. The name must not be
               used by another subnet in the VPC.
        :param NetworkACLIdentity network_acl: (optional) The network ACL to use
               for this subnet.
        :param SubnetPublicGatewayPatch public_gateway: (optional) The public
               gateway to use for internet-bound traffic for this subnet.
        :param RoutingTableIdentity routing_table: (optional) The routing table to
               use for this subnet.  The routing table properties
               `route_direct_link_ingress`, `route_internet_ingress`,
               `route_transit_gateway_ingress`, and `route_vpc_zone_ingress` must be
               `false`.
        """
        self.name = name
        self.network_acl = network_acl
        self.public_gateway = public_gateway
        self.routing_table = routing_table

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'SubnetPatch':
        """Initialize a SubnetPatch object from a json dictionary."""
        args = {}
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        if 'network_acl' in _dict:
            args['network_acl'] = _dict.get('network_acl')
        if 'public_gateway' in _dict:
            args['public_gateway'] = _dict.get('public_gateway')
        if 'routing_table' in _dict:
            args['routing_table'] = _dict.get('routing_table')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SubnetPatch object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'network_acl') and self.network_acl is not None:
            if isinstance(self.network_acl, dict):
                _dict['network_acl'] = self.network_acl
            else:
                _dict['network_acl'] = self.network_acl.to_dict()
        if hasattr(self, 'public_gateway') and self.public_gateway is not None:
            if isinstance(self.public_gateway, dict):
                _dict['public_gateway'] = self.public_gateway
            else:
                _dict['public_gateway'] = self.public_gateway.to_dict()
        if hasattr(self, 'routing_table') and self.routing_table is not None:
            if isinstance(self.routing_table, dict):
                _dict['routing_table'] = self.routing_table
            else:
                _dict['routing_table'] = self.routing_table.to_dict()
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this SubnetPatch object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'SubnetPatch') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'SubnetPatch') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class SubnetPrototype:
    """
    SubnetPrototype.

    :attr str ip_version: (optional) The IP version(s) to support for this subnet.
    :attr str name: (optional) The name for this subnet. The name must not be used
          by another subnet in the VPC. 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 use
          for internet-bound traffic for this subnet. If
          unspecified, the subnet will not be attached to a public 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) will be
          used.
    :attr RoutingTableIdentity routing_table: (optional) The routing table to use
          for this subnet. If unspecified, the default routing table
          for the VPC is used. The routing table properties `route_direct_link_ingress`,
          `route_internet_ingress`, `route_transit_gateway_ingress`, and
          `route_vpc_zone_ingress` must be `false`.
    :attr VPCIdentity vpc: The VPC the subnet will reside in.
    """

    def __init__(
        self,
        vpc: 'VPCIdentity',
        *,
        ip_version: str = None,
        name: str = None,
        network_acl: 'NetworkACLIdentity' = None,
        public_gateway: 'PublicGatewayIdentity' = None,
        resource_group: 'ResourceGroupIdentity' = None,
        routing_table: 'RoutingTableIdentity' = None,
    ) -> None:
        """
        Initialize a SubnetPrototype object.

        :param VPCIdentity vpc: The VPC the subnet will reside in.
        :param str ip_version: (optional) The IP version(s) to support for this
               subnet.
        :param str name: (optional) The name for this subnet. The name must not be
               used by another subnet in the VPC. 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 use for internet-bound traffic for this subnet. If
               unspecified, the subnet will not be attached to a public 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) will be
               used.
        :param RoutingTableIdentity routing_table: (optional) The routing table to
               use for this subnet. If unspecified, the default routing table
               for the VPC is used. The routing table properties
               `route_direct_link_ingress`,
               `route_internet_ingress`, `route_transit_gateway_ingress`, and
               `route_vpc_zone_ingress` must be `false`.
        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['SubnetPrototypeSubnetByTotalCount', 'SubnetPrototypeSubnetByCIDR'])
        )
        raise Exception(msg)

    class IpVersionEnum(str, Enum):
        """
        The IP version(s) to support for this subnet.
        """

        IPV4 = 'ipv4'



class SubnetPublicGatewayPatch:
    """
    The public gateway to use for internet-bound traffic for this subnet.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a SubnetPublicGatewayPatch object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['SubnetPublicGatewayPatchPublicGatewayIdentityById', 'SubnetPublicGatewayPatchPublicGatewayIdentityByCRN', 'SubnetPublicGatewayPatchPublicGatewayIdentityByHref'])
        )
        raise Exception(msg)


class SubnetReference:
    """
    SubnetReference.

    :attr str crn: The CRN for this subnet.
    :attr SubnetReferenceDeleted deleted: (optional) If present, this property
          indicates the referenced resource has been deleted, and provides
          some supplementary information.
    :attr str href: The URL for this subnet.
    :attr str id: The unique identifier for this subnet.
    :attr str name: The name for this subnet. The name is unique across all subnets
          in the VPC.
    :attr str resource_type: The resource type.
    """

    def __init__(
        self,
        crn: str,
        href: str,
        id: str,
        name: str,
        resource_type: str,
        *,
        deleted: 'SubnetReferenceDeleted' = None,
    ) -> None:
        """
        Initialize a SubnetReference object.

        :param str crn: The CRN for this subnet.
        :param str href: The URL for this subnet.
        :param str id: The unique identifier for this subnet.
        :param str name: The name for this subnet. The name is unique across all
               subnets in the VPC.
        :param str resource_type: The resource type.
        :param SubnetReferenceDeleted deleted: (optional) If present, this property
               indicates the referenced resource has been deleted, and provides
               some supplementary information.
        """
        self.crn = crn
        self.deleted = deleted
        self.href = href
        self.id = id
        self.name = name
        self.resource_type = resource_type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'SubnetReference':
        """Initialize a SubnetReference object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError('Required property \'crn\' not present in SubnetReference JSON')
        if 'deleted' in _dict:
            args['deleted'] = SubnetReferenceDeleted.from_dict(_dict.get('deleted'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in SubnetReference JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in SubnetReference JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in SubnetReference JSON')
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError('Required property \'resource_type\' not present in SubnetReference JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SubnetReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'deleted') and self.deleted is not None:
            if isinstance(self.deleted, dict):
                _dict['deleted'] = self.deleted
            else:
                _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'resource_type') and self.resource_type is not None:
            _dict['resource_type'] = self.resource_type
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this 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 ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        SUBNET = 'subnet'



class SubnetReferenceDeleted:
    """
    If present, this property indicates the referenced resource has been deleted, and
    provides some supplementary information.

    :attr str more_info: Link to documentation about deleted resources.
    """

    def __init__(
        self,
        more_info: str,
    ) -> None:
        """
        Initialize a SubnetReferenceDeleted object.

        :param str more_info: Link to documentation about deleted resources.
        """
        self.more_info = more_info

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'SubnetReferenceDeleted':
        """Initialize a SubnetReferenceDeleted object from a json dictionary."""
        args = {}
        if 'more_info' in _dict:
            args['more_info'] = _dict.get('more_info')
        else:
            raise ValueError('Required property \'more_info\' not present in SubnetReferenceDeleted JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SubnetReferenceDeleted object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'more_info') and self.more_info is not None:
            _dict['more_info'] = self.more_info
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this SubnetReferenceDeleted object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'SubnetReferenceDeleted') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'SubnetReferenceDeleted') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class TrustedProfileIdentity:
    """
    Identifies a trusted profile by a unique property.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a TrustedProfileIdentity object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['TrustedProfileIdentityTrustedProfileById', 'TrustedProfileIdentityTrustedProfileByCRN'])
        )
        raise Exception(msg)


class TrustedProfileReference:
    """
    TrustedProfileReference.

    :attr str crn: The CRN for this trusted profile.
    :attr str id: The unique identifier for this trusted profile.
    :attr str resource_type: The resource type.
    """

    def __init__(
        self,
        crn: str,
        id: str,
        resource_type: str,
    ) -> None:
        """
        Initialize a TrustedProfileReference object.

        :param str crn: The CRN for this trusted profile.
        :param str id: The unique identifier for this trusted profile.
        :param str resource_type: The resource type.
        """
        self.crn = crn
        self.id = id
        self.resource_type = resource_type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'TrustedProfileReference':
        """Initialize a TrustedProfileReference object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError('Required property \'crn\' not present in TrustedProfileReference JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in TrustedProfileReference JSON')
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError('Required property \'resource_type\' not present in TrustedProfileReference JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a TrustedProfileReference object from 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, 'id') and self.id is not None:
            _dict['id'] = self.id
        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 TrustedProfileReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'TrustedProfileReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'TrustedProfileReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        TRUSTED_PROFILE = 'trusted_profile'



class VCPU:
    """
    The VCPU configuration.

    :attr str architecture: The VCPU architecture.
    :attr int count: The number of VCPUs assigned.
    :attr str manufacturer: The VCPU manufacturer.
    """

    def __init__(
        self,
        architecture: str,
        count: int,
        manufacturer: str,
    ) -> None:
        """
        Initialize a VCPU object.

        :param str architecture: The VCPU architecture.
        :param int count: The number of VCPUs assigned.
        :param str manufacturer: The VCPU manufacturer.
        """
        self.architecture = architecture
        self.count = count
        self.manufacturer = manufacturer

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VCPU':
        """Initialize a VCPU object from a json dictionary."""
        args = {}
        if 'architecture' in _dict:
            args['architecture'] = _dict.get('architecture')
        else:
            raise ValueError('Required property \'architecture\' not present in VCPU JSON')
        if 'count' in _dict:
            args['count'] = _dict.get('count')
        else:
            raise ValueError('Required property \'count\' not present in VCPU JSON')
        if 'manufacturer' in _dict:
            args['manufacturer'] = _dict.get('manufacturer')
        else:
            raise ValueError('Required property \'manufacturer\' not present in VCPU JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VCPU object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'architecture') and self.architecture is not None:
            _dict['architecture'] = self.architecture
        if hasattr(self, 'count') and self.count is not None:
            _dict['count'] = self.count
        if hasattr(self, 'manufacturer') and self.manufacturer is not None:
            _dict['manufacturer'] = self.manufacturer
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VCPU object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VCPU') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VCPU') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VPC:
    """
    VPC.

    :attr bool classic_access: Indicates whether this VPC is connected to Classic
          Infrastructure. If true, this VPC's resources have private network connectivity
          to the account's Classic Infrastructure resources. Only one VPC, per region, may
          be connected in this way. This value is set at creation and subsequently
          immutable.
    :attr datetime created_at: The date and time that the VPC was created.
    :attr str crn: The CRN for this VPC.
    :attr List[VPCCSESourceIP] cse_source_ips: (optional) The CSE ([Cloud Service
          Endpoint](https://cloud.ibm.com/docs/resources?topic=resources-service-endpoints))
          source IP addresses for the VPC. The VPC will have one CSE source IP address per
          zone.
    :attr NetworkACLReference default_network_acl: The default network ACL to use
          for subnets created in this VPC.
    :attr RoutingTableReference default_routing_table: The default routing table to
          use for subnets created in this VPC.
    :attr SecurityGroupReference default_security_group: The default security group
          for this VPC. Resources created in this VPC that allow
          a security group to be optionally specified will use this security group by
          default.
    :attr VPCDNS dns: The DNS configuration for this VPC.
    :attr List[VPCHealthReason] health_reasons: The reasons for the current
          `health_state` (if any).
          The enumerated reason code values for this property will expand in the future.
          When processing this property, check for and log unknown values. Optionally halt
          processing and surface the error, or bypass the resource on which the unexpected
          reason code was encountered.
    :attr str health_state: The health of this resource.
          - `ok`: No abnormal behavior detected
          - `degraded`: Experiencing compromised performance, capacity, or connectivity
          - `faulted`: Completely unreachable, inoperative, or otherwise entirely
          incapacitated
          - `inapplicable`: The health state does not apply because of the current
          lifecycle state. A resource with a lifecycle state of `failed` or `deleting`
          will have a health state of `inapplicable`. A `pending` resource may also have
          this state.
    :attr str href: The URL for this VPC.
    :attr str id: The unique identifier for this VPC.
    :attr str name: The name for this VPC. The name is unique across all VPCs in the
          region.
    :attr ResourceGroupReference resource_group: The resource group for this VPC.
    :attr str resource_type: The resource type.
    :attr str status: The status of this VPC.
    """

    def __init__(
        self,
        classic_access: bool,
        created_at: datetime,
        crn: str,
        default_network_acl: 'NetworkACLReference',
        default_routing_table: 'RoutingTableReference',
        default_security_group: 'SecurityGroupReference',
        dns: 'VPCDNS',
        health_reasons: List['VPCHealthReason'],
        health_state: str,
        href: str,
        id: str,
        name: str,
        resource_group: 'ResourceGroupReference',
        resource_type: str,
        status: str,
        *,
        cse_source_ips: List['VPCCSESourceIP'] = None,
    ) -> None:
        """
        Initialize a VPC object.

        :param bool classic_access: Indicates whether this VPC is connected to
               Classic Infrastructure. If true, this VPC's resources have private network
               connectivity to the account's Classic Infrastructure resources. Only one
               VPC, per region, may be connected in this way. This value is set at
               creation and subsequently immutable.
        :param datetime created_at: The date and time that the VPC was created.
        :param str crn: The CRN for this VPC.
        :param NetworkACLReference default_network_acl: The default network ACL to
               use for subnets created in this VPC.
        :param RoutingTableReference default_routing_table: The default routing
               table to use for subnets created in this VPC.
        :param SecurityGroupReference default_security_group: The default security
               group for this VPC. Resources created in this VPC that allow
               a security group to be optionally specified will use this security group by
               default.
        :param VPCDNS dns: The DNS configuration for this VPC.
        :param List[VPCHealthReason] health_reasons: The reasons for the current
               `health_state` (if any).
               The enumerated reason code values for this property will expand in the
               future. When processing this property, check for and log unknown values.
               Optionally halt processing and surface the error, or bypass the resource on
               which the unexpected reason code was encountered.
        :param str health_state: The health of this resource.
               - `ok`: No abnormal behavior detected
               - `degraded`: Experiencing compromised performance, capacity, or
               connectivity
               - `faulted`: Completely unreachable, inoperative, or otherwise entirely
               incapacitated
               - `inapplicable`: The health state does not apply because of the current
               lifecycle state. A resource with a lifecycle state of `failed` or
               `deleting` will have a health state of `inapplicable`. A `pending` resource
               may also have this state.
        :param str href: The URL for this VPC.
        :param str id: The unique identifier for this VPC.
        :param str name: The name for this VPC. The name is unique across all VPCs
               in the region.
        :param ResourceGroupReference resource_group: The resource group for this
               VPC.
        :param str resource_type: The resource type.
        :param str status: The status of this VPC.
        :param List[VPCCSESourceIP] cse_source_ips: (optional) The CSE ([Cloud
               Service
               Endpoint](https://cloud.ibm.com/docs/resources?topic=resources-service-endpoints))
               source IP addresses for the VPC. The VPC will have one CSE source IP
               address per zone.
        """
        self.classic_access = classic_access
        self.created_at = created_at
        self.crn = crn
        self.cse_source_ips = cse_source_ips
        self.default_network_acl = default_network_acl
        self.default_routing_table = default_routing_table
        self.default_security_group = default_security_group
        self.dns = dns
        self.health_reasons = health_reasons
        self.health_state = health_state
        self.href = href
        self.id = id
        self.name = name
        self.resource_group = resource_group
        self.resource_type = resource_type
        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(v) for v in _dict.get('cse_source_ips')]
        if 'default_network_acl' in _dict:
            args['default_network_acl'] = NetworkACLReference.from_dict(_dict.get('default_network_acl'))
        else:
            raise ValueError('Required property \'default_network_acl\' not present in VPC JSON')
        if 'default_routing_table' in _dict:
            args['default_routing_table'] = RoutingTableReference.from_dict(_dict.get('default_routing_table'))
        else:
            raise ValueError('Required property \'default_routing_table\' not present in VPC JSON')
        if 'default_security_group' in _dict:
            args['default_security_group'] = SecurityGroupReference.from_dict(_dict.get('default_security_group'))
        else:
            raise ValueError('Required property \'default_security_group\' not present in VPC JSON')
        if 'dns' in _dict:
            args['dns'] = VPCDNS.from_dict(_dict.get('dns'))
        else:
            raise ValueError('Required property \'dns\' not present in VPC JSON')
        if 'health_reasons' in _dict:
            args['health_reasons'] = [VPCHealthReason.from_dict(v) for v in _dict.get('health_reasons')]
        else:
            raise ValueError('Required property \'health_reasons\' not present in VPC JSON')
        if 'health_state' in _dict:
            args['health_state'] = _dict.get('health_state')
        else:
            raise ValueError('Required property \'health_state\' 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 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError('Required property \'resource_type\' 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:
            cse_source_ips_list = []
            for v in self.cse_source_ips:
                if isinstance(v, dict):
                    cse_source_ips_list.append(v)
                else:
                    cse_source_ips_list.append(v.to_dict())
            _dict['cse_source_ips'] = cse_source_ips_list
        if hasattr(self, 'default_network_acl') and self.default_network_acl is not None:
            if isinstance(self.default_network_acl, dict):
                _dict['default_network_acl'] = self.default_network_acl
            else:
                _dict['default_network_acl'] = self.default_network_acl.to_dict()
        if hasattr(self, 'default_routing_table') and self.default_routing_table is not None:
            if isinstance(self.default_routing_table, dict):
                _dict['default_routing_table'] = self.default_routing_table
            else:
                _dict['default_routing_table'] = self.default_routing_table.to_dict()
        if hasattr(self, 'default_security_group') and self.default_security_group is not None:
            if isinstance(self.default_security_group, dict):
                _dict['default_security_group'] = self.default_security_group
            else:
                _dict['default_security_group'] = self.default_security_group.to_dict()
        if hasattr(self, 'dns') and self.dns is not None:
            if isinstance(self.dns, dict):
                _dict['dns'] = self.dns
            else:
                _dict['dns'] = self.dns.to_dict()
        if hasattr(self, 'health_reasons') and self.health_reasons is not None:
            health_reasons_list = []
            for v in self.health_reasons:
                if isinstance(v, dict):
                    health_reasons_list.append(v)
                else:
                    health_reasons_list.append(v.to_dict())
            _dict['health_reasons'] = health_reasons_list
        if hasattr(self, 'health_state') and self.health_state is not None:
            _dict['health_state'] = self.health_state
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, '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, '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
        return _dict

    def _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 HealthStateEnum(str, Enum):
        """
        The health of this resource.
        - `ok`: No abnormal behavior detected
        - `degraded`: Experiencing compromised performance, capacity, or connectivity
        - `faulted`: Completely unreachable, inoperative, or otherwise entirely
        incapacitated
        - `inapplicable`: The health state does not apply because of the current lifecycle
        state. A resource with a lifecycle state of `failed` or `deleting` will have a
        health state of `inapplicable`. A `pending` resource may also have this state.
        """

        DEGRADED = 'degraded'
        FAULTED = 'faulted'
        INAPPLICABLE = 'inapplicable'
        OK = 'ok'


    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        VPC = 'vpc'


    class StatusEnum(str, Enum):
        """
        The status of this VPC.
        """

        AVAILABLE = 'available'
        DELETING = 'deleting'
        FAILED = 'failed'
        PENDING = 'pending'



class VPCCSESourceIP:
    """
    VPCCSESourceIP.

    :attr IP ip: The cloud service endpoint source IP address for this zone.
    :attr ZoneReference zone: The zone this cloud service endpoint source IP resides
          in.
    """

    def __init__(
        self,
        ip: 'IP',
        zone: 'ZoneReference',
    ) -> None:
        """
        Initialize a VPCCSESourceIP object.

        :param IP ip: The cloud service endpoint source IP address for this zone.
        :param ZoneReference zone: The zone this cloud service endpoint source IP
               resides in.
        """
        self.ip = ip
        self.zone = zone

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPCCSESourceIP':
        """Initialize a VPCCSESourceIP object from a json dictionary."""
        args = {}
        if 'ip' in _dict:
            args['ip'] = IP.from_dict(_dict.get('ip'))
        else:
            raise ValueError('Required property \'ip\' not present in VPCCSESourceIP JSON')
        if 'zone' in _dict:
            args['zone'] = ZoneReference.from_dict(_dict.get('zone'))
        else:
            raise ValueError('Required property \'zone\' not present in VPCCSESourceIP JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPCCSESourceIP object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'ip') and self.ip is not None:
            if isinstance(self.ip, dict):
                _dict['ip'] = self.ip
            else:
                _dict['ip'] = self.ip.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 VPCCSESourceIP object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPCCSESourceIP') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPCCSESourceIP') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VPCCollection:
    """
    VPCCollection.

    :attr VPCCollectionFirst first: A link to the first page of resources.
    :attr int limit: The maximum number of resources that can be returned by the
          request.
    :attr VPCCollectionNext next: (optional) A link to the next page of resources.
          This property is present for all pages
          except the last page.
    :attr int total_count: The total number of resources across all pages.
    :attr List[VPC] vpcs: Collection of VPCs.
    """

    def __init__(
        self,
        first: 'VPCCollectionFirst',
        limit: int,
        total_count: int,
        vpcs: List['VPC'],
        *,
        next: 'VPCCollectionNext' = None,
    ) -> None:
        """
        Initialize a VPCCollection object.

        :param VPCCollectionFirst first: A link to the first page of resources.
        :param int limit: The maximum number of resources that can be returned by
               the request.
        :param int total_count: The total number of resources across all pages.
        :param List[VPC] vpcs: Collection of VPCs.
        :param VPCCollectionNext next: (optional) A link to the next page of
               resources. This property is present for all pages
               except the last page.
        """
        self.first = first
        self.limit = limit
        self.next = next
        self.total_count = total_count
        self.vpcs = vpcs

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPCCollection':
        """Initialize a VPCCollection object from a json dictionary."""
        args = {}
        if 'first' in _dict:
            args['first'] = VPCCollectionFirst.from_dict(_dict.get('first'))
        else:
            raise ValueError('Required property \'first\' not present in VPCCollection JSON')
        if 'limit' in _dict:
            args['limit'] = _dict.get('limit')
        else:
            raise ValueError('Required property \'limit\' not present in VPCCollection JSON')
        if 'next' in _dict:
            args['next'] = VPCCollectionNext.from_dict(_dict.get('next'))
        if 'total_count' in _dict:
            args['total_count'] = _dict.get('total_count')
        else:
            raise ValueError('Required property \'total_count\' not present in VPCCollection JSON')
        if 'vpcs' in _dict:
            args['vpcs'] = [VPC.from_dict(v) for v 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:
            if isinstance(self.first, dict):
                _dict['first'] = self.first
            else:
                _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:
            if isinstance(self.next, dict):
                _dict['next'] = self.next
            else:
                _dict['next'] = self.next.to_dict()
        if hasattr(self, 'total_count') and self.total_count is not None:
            _dict['total_count'] = self.total_count
        if hasattr(self, 'vpcs') and self.vpcs is not None:
            vpcs_list = []
            for v in self.vpcs:
                if isinstance(v, dict):
                    vpcs_list.append(v)
                else:
                    vpcs_list.append(v.to_dict())
            _dict['vpcs'] = vpcs_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 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 VPCDNS:
    """
    The DNS configuration for this VPC.

    :attr bool enable_hub: Indicates whether this VPC is enabled as a DNS name
          resolution hub.
    :attr int resolution_binding_count: The number of DNS resolution bindings for
          this VPC.
    :attr VPCDNSResolver resolver: The DNS resolver configuration for the VPC.
    """

    def __init__(
        self,
        enable_hub: bool,
        resolution_binding_count: int,
        resolver: 'VPCDNSResolver',
    ) -> None:
        """
        Initialize a VPCDNS object.

        :param bool enable_hub: Indicates whether this VPC is enabled as a DNS name
               resolution hub.
        :param int resolution_binding_count: The number of DNS resolution bindings
               for this VPC.
        :param VPCDNSResolver resolver: The DNS resolver configuration for the VPC.
        """
        self.enable_hub = enable_hub
        self.resolution_binding_count = resolution_binding_count
        self.resolver = resolver

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPCDNS':
        """Initialize a VPCDNS object from a json dictionary."""
        args = {}
        if 'enable_hub' in _dict:
            args['enable_hub'] = _dict.get('enable_hub')
        else:
            raise ValueError('Required property \'enable_hub\' not present in VPCDNS JSON')
        if 'resolution_binding_count' in _dict:
            args['resolution_binding_count'] = _dict.get('resolution_binding_count')
        else:
            raise ValueError('Required property \'resolution_binding_count\' not present in VPCDNS JSON')
        if 'resolver' in _dict:
            args['resolver'] = _dict.get('resolver')
        else:
            raise ValueError('Required property \'resolver\' not present in VPCDNS JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPCDNS object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'enable_hub') and self.enable_hub is not None:
            _dict['enable_hub'] = self.enable_hub
        if hasattr(self, 'resolution_binding_count') and self.resolution_binding_count is not None:
            _dict['resolution_binding_count'] = self.resolution_binding_count
        if hasattr(self, 'resolver') and self.resolver is not None:
            if isinstance(self.resolver, dict):
                _dict['resolver'] = self.resolver
            else:
                _dict['resolver'] = self.resolver.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 VPCDNS object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPCDNS') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPCDNS') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VPCDNSPatch:
    """
    The DNS configuration for this VPC.

    :attr bool enable_hub: (optional) Indicates whether this VPC is enabled as a DNS
          name resolution hub.
          Updating the value to `true` requires `allow_dns_resolution_binding` to be
          `true` for all endpoint gateways residing in this VPC.
          Changing the value requires `dns.resolution_binding_count` to be zero.
    :attr VPCDNSResolverPatch resolver: (optional)
    """

    def __init__(
        self,
        *,
        enable_hub: bool = None,
        resolver: 'VPCDNSResolverPatch' = None,
    ) -> None:
        """
        Initialize a VPCDNSPatch object.

        :param bool enable_hub: (optional) Indicates whether this VPC is enabled as
               a DNS name resolution hub.
               Updating the value to `true` requires `allow_dns_resolution_binding` to be
               `true` for all endpoint gateways residing in this VPC.
               Changing the value requires `dns.resolution_binding_count` to be zero.
        :param VPCDNSResolverPatch resolver: (optional)
        """
        self.enable_hub = enable_hub
        self.resolver = resolver

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPCDNSPatch':
        """Initialize a VPCDNSPatch object from a json dictionary."""
        args = {}
        if 'enable_hub' in _dict:
            args['enable_hub'] = _dict.get('enable_hub')
        if 'resolver' in _dict:
            args['resolver'] = VPCDNSResolverPatch.from_dict(_dict.get('resolver'))
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPCDNSPatch object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'enable_hub') and self.enable_hub is not None:
            _dict['enable_hub'] = self.enable_hub
        if hasattr(self, 'resolver') and self.resolver is not None:
            if isinstance(self.resolver, dict):
                _dict['resolver'] = self.resolver
            else:
                _dict['resolver'] = self.resolver.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 VPCDNSPatch object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPCDNSPatch') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPCDNSPatch') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VPCDNSPrototype:
    """
    The DNS configuration for this VPC.
    If unspecified, the system will assign DNS servers capable of resolving hosts and
    endpoint gateways within this VPC, and hosts on the internet.

    :attr bool enable_hub: (optional) Indicates whether this VPC is enabled as a DNS
          name resolution hub.
    :attr VPCDNSResolverPrototype resolver: (optional)
    """

    def __init__(
        self,
        *,
        enable_hub: bool = None,
        resolver: 'VPCDNSResolverPrototype' = None,
    ) -> None:
        """
        Initialize a VPCDNSPrototype object.

        :param bool enable_hub: (optional) Indicates whether this VPC is enabled as
               a DNS name resolution hub.
        :param VPCDNSResolverPrototype resolver: (optional)
        """
        self.enable_hub = enable_hub
        self.resolver = resolver

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPCDNSPrototype':
        """Initialize a VPCDNSPrototype object from a json dictionary."""
        args = {}
        if 'enable_hub' in _dict:
            args['enable_hub'] = _dict.get('enable_hub')
        if 'resolver' in _dict:
            args['resolver'] = _dict.get('resolver')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPCDNSPrototype object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'enable_hub') and self.enable_hub is not None:
            _dict['enable_hub'] = self.enable_hub
        if hasattr(self, 'resolver') and self.resolver is not None:
            if isinstance(self.resolver, dict):
                _dict['resolver'] = self.resolver
            else:
                _dict['resolver'] = self.resolver.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 VPCDNSPrototype object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPCDNSPrototype') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPCDNSPrototype') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VPCDNSResolutionBinding:
    """
    VPCDNSResolutionBinding.

    :attr datetime created_at: The date and time that the DNS resolution binding was
          created.
    :attr List[EndpointGatewayReferenceRemote] endpoint_gateways: The endpoint
          gateways that have `allow_dns_resolution_binding` set to `true` and reside in
          the VPC that has `dns.enable_hub` set to `false`.
          The endpoint gateways may be remote and therefore may not be directly
          retrievable.
    :attr str href: The URL for this DNS resolution binding.
    :attr str id: The unique identifier for this DNS resolution binding.
    :attr str lifecycle_state: The lifecycle state of the DNS resolution binding.
    :attr str name: The name for this DNS resolution binding. The name is unique
          across all DNS resolution bindings for the VPC.
    :attr str resource_type: The resource type.
    :attr VPCReferenceRemote vpc: The VPC bound to for DNS resolution.
          The VPC may be remote and therefore may not be directly retrievable.
    """

    def __init__(
        self,
        created_at: datetime,
        endpoint_gateways: List['EndpointGatewayReferenceRemote'],
        href: str,
        id: str,
        lifecycle_state: str,
        name: str,
        resource_type: str,
        vpc: 'VPCReferenceRemote',
    ) -> None:
        """
        Initialize a VPCDNSResolutionBinding object.

        :param datetime created_at: The date and time that the DNS resolution
               binding was created.
        :param List[EndpointGatewayReferenceRemote] endpoint_gateways: The endpoint
               gateways that have `allow_dns_resolution_binding` set to `true` and reside
               in the VPC that has `dns.enable_hub` set to `false`.
               The endpoint gateways may be remote and therefore may not be directly
               retrievable.
        :param str href: The URL for this DNS resolution binding.
        :param str id: The unique identifier for this DNS resolution binding.
        :param str lifecycle_state: The lifecycle state of the DNS resolution
               binding.
        :param str name: The name for this DNS resolution binding. The name is
               unique across all DNS resolution bindings for the VPC.
        :param str resource_type: The resource type.
        :param VPCReferenceRemote vpc: The VPC bound to for DNS resolution.
               The VPC may be remote and therefore may not be directly retrievable.
        """
        self.created_at = created_at
        self.endpoint_gateways = endpoint_gateways
        self.href = href
        self.id = id
        self.lifecycle_state = lifecycle_state
        self.name = name
        self.resource_type = resource_type
        self.vpc = vpc

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPCDNSResolutionBinding':
        """Initialize a VPCDNSResolutionBinding 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 VPCDNSResolutionBinding JSON')
        if 'endpoint_gateways' in _dict:
            args['endpoint_gateways'] = [EndpointGatewayReferenceRemote.from_dict(v) for v in _dict.get('endpoint_gateways')]
        else:
            raise ValueError('Required property \'endpoint_gateways\' not present in VPCDNSResolutionBinding JSON')
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in VPCDNSResolutionBinding JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in VPCDNSResolutionBinding JSON')
        if 'lifecycle_state' in _dict:
            args['lifecycle_state'] = _dict.get('lifecycle_state')
        else:
            raise ValueError('Required property \'lifecycle_state\' not present in VPCDNSResolutionBinding JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in VPCDNSResolutionBinding JSON')
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError('Required property \'resource_type\' not present in VPCDNSResolutionBinding JSON')
        if 'vpc' in _dict:
            args['vpc'] = VPCReferenceRemote.from_dict(_dict.get('vpc'))
        else:
            raise ValueError('Required property \'vpc\' not present in VPCDNSResolutionBinding JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPCDNSResolutionBinding object from 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, 'endpoint_gateways') and self.endpoint_gateways is not None:
            endpoint_gateways_list = []
            for v in self.endpoint_gateways:
                if isinstance(v, dict):
                    endpoint_gateways_list.append(v)
                else:
                    endpoint_gateways_list.append(v.to_dict())
            _dict['endpoint_gateways'] = endpoint_gateways_list
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'lifecycle_state') and self.lifecycle_state is not None:
            _dict['lifecycle_state'] = self.lifecycle_state
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'resource_type') and self.resource_type is not None:
            _dict['resource_type'] = self.resource_type
        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()
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VPCDNSResolutionBinding object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPCDNSResolutionBinding') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPCDNSResolutionBinding') -> 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 DNS resolution binding.
        """

        DELETING = 'deleting'
        FAILED = 'failed'
        PENDING = 'pending'
        STABLE = 'stable'
        SUSPENDED = 'suspended'
        UPDATING = 'updating'
        WAITING = 'waiting'


    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        VPC_DNS_RESOLUTION_BINDING = 'vpc_dns_resolution_binding'



class VPCDNSResolutionBindingCollection:
    """
    VPCDNSResolutionBindingCollection.

    :attr List[VPCDNSResolutionBinding] dns_resolution_bindings: Collection of DNS
          resolution bindings for this VPC.
    :attr VPCDNSResolutionBindingCollectionFirst 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 VPCDNSResolutionBindingCollectionNext 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,
        dns_resolution_bindings: List['VPCDNSResolutionBinding'],
        first: 'VPCDNSResolutionBindingCollectionFirst',
        limit: int,
        total_count: int,
        *,
        next: 'VPCDNSResolutionBindingCollectionNext' = None,
    ) -> None:
        """
        Initialize a VPCDNSResolutionBindingCollection object.

        :param List[VPCDNSResolutionBinding] dns_resolution_bindings: Collection of
               DNS resolution bindings for this VPC.
        :param VPCDNSResolutionBindingCollectionFirst 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 VPCDNSResolutionBindingCollectionNext next: (optional) A link to the
               next page of resources. This property is present for all pages
               except the last page.
        """
        self.dns_resolution_bindings = dns_resolution_bindings
        self.first = first
        self.limit = limit
        self.next = next
        self.total_count = total_count

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPCDNSResolutionBindingCollection':
        """Initialize a VPCDNSResolutionBindingCollection object from a json dictionary."""
        args = {}
        if 'dns_resolution_bindings' in _dict:
            args['dns_resolution_bindings'] = [VPCDNSResolutionBinding.from_dict(v) for v in _dict.get('dns_resolution_bindings')]
        else:
            raise ValueError('Required property \'dns_resolution_bindings\' not present in VPCDNSResolutionBindingCollection JSON')
        if 'first' in _dict:
            args['first'] = VPCDNSResolutionBindingCollectionFirst.from_dict(_dict.get('first'))
        else:
            raise ValueError('Required property \'first\' not present in VPCDNSResolutionBindingCollection JSON')
        if 'limit' in _dict:
            args['limit'] = _dict.get('limit')
        else:
            raise ValueError('Required property \'limit\' not present in VPCDNSResolutionBindingCollection JSON')
        if 'next' in _dict:
            args['next'] = VPCDNSResolutionBindingCollectionNext.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 VPCDNSResolutionBindingCollection JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPCDNSResolutionBindingCollection object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'dns_resolution_bindings') and self.dns_resolution_bindings is not None:
            dns_resolution_bindings_list = []
            for v in self.dns_resolution_bindings:
                if isinstance(v, dict):
                    dns_resolution_bindings_list.append(v)
                else:
                    dns_resolution_bindings_list.append(v.to_dict())
            _dict['dns_resolution_bindings'] = dns_resolution_bindings_list
        if hasattr(self, 'first') and self.first is not None:
            if isinstance(self.first, dict):
                _dict['first'] = self.first
            else:
                _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:
            if isinstance(self.next, dict):
                _dict['next'] = self.next
            else:
                _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 VPCDNSResolutionBindingCollection object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPCDNSResolutionBindingCollection') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPCDNSResolutionBindingCollection') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VPCDNSResolutionBindingCollectionFirst:
    """
    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 VPCDNSResolutionBindingCollectionFirst object.

        :param str href: The URL for a page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPCDNSResolutionBindingCollectionFirst':
        """Initialize a VPCDNSResolutionBindingCollectionFirst object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in VPCDNSResolutionBindingCollectionFirst JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPCDNSResolutionBindingCollectionFirst object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(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 VPCDNSResolutionBindingCollectionFirst object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPCDNSResolutionBindingCollectionFirst') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPCDNSResolutionBindingCollectionFirst') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VPCDNSResolutionBindingCollectionNext:
    """
    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 VPCDNSResolutionBindingCollectionNext object.

        :param str href: The URL for a page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPCDNSResolutionBindingCollectionNext':
        """Initialize a VPCDNSResolutionBindingCollectionNext object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in VPCDNSResolutionBindingCollectionNext JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPCDNSResolutionBindingCollectionNext object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(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 VPCDNSResolutionBindingCollectionNext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPCDNSResolutionBindingCollectionNext') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPCDNSResolutionBindingCollectionNext') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VPCDNSResolutionBindingPatch:
    """
    VPCDNSResolutionBindingPatch.

    :attr str name: (optional) The name for this DNS resolution binding. The name
          must not be used by another DNS resolution binding for the VPC.
    """

    def __init__(
        self,
        *,
        name: str = None,
    ) -> None:
        """
        Initialize a VPCDNSResolutionBindingPatch object.

        :param str name: (optional) The name for this DNS resolution binding. The
               name must not be used by another DNS resolution binding for the VPC.
        """
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPCDNSResolutionBindingPatch':
        """Initialize a VPCDNSResolutionBindingPatch 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 VPCDNSResolutionBindingPatch object from 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 VPCDNSResolutionBindingPatch object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPCDNSResolutionBindingPatch') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPCDNSResolutionBindingPatch') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VPCDNSResolver:
    """
    VPCDNSResolver.

    :attr List[DNSServer] servers: The DNS servers for this VPC. The servers are
          populated:
          - by the system when `dns.resolver.type` is `system`
          - using the DNS servers in `dns.resolver.vpc` when `dns.resolver.type` is
          `delegated`
          - using `dns.resolver.manual_servers` when the `dns.resolver.type` is `manual`.
    :attr str type: The type of the DNS resolver used for the VPC.
          - `delegated`: DNS server addresses are provided by the DNS resolver of the VPC
                         specified in `dns.resolver.vpc`.
          - `manual`: DNS server addresses are specified in `dns.resolver.manual_servers`.
          - `system`: DNS server addresses are provided by the system.
    """

    def __init__(
        self,
        servers: List['DNSServer'],
        type: str,
    ) -> None:
        """
        Initialize a VPCDNSResolver object.

        :param List[DNSServer] servers: The DNS servers for this VPC. The servers
               are populated:
               - by the system when `dns.resolver.type` is `system`
               - using the DNS servers in `dns.resolver.vpc` when `dns.resolver.type` is
               `delegated`
               - using `dns.resolver.manual_servers` when the `dns.resolver.type` is
               `manual`.
        :param str type: The type of the DNS resolver used for the VPC.
               - `delegated`: DNS server addresses are provided by the DNS resolver of the
               VPC
                              specified in `dns.resolver.vpc`.
               - `manual`: DNS server addresses are specified in
               `dns.resolver.manual_servers`.
               - `system`: DNS server addresses are provided by the system.
        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['VPCDNSResolverTypeDelegated', 'VPCDNSResolverTypeManual', 'VPCDNSResolverTypeSystem'])
        )
        raise Exception(msg)

    class TypeEnum(str, Enum):
        """
        The type of the DNS resolver used for the VPC.
        - `delegated`: DNS server addresses are provided by the DNS resolver of the VPC
                       specified in `dns.resolver.vpc`.
        - `manual`: DNS server addresses are specified in `dns.resolver.manual_servers`.
        - `system`: DNS server addresses are provided by the system.
        """

        DELEGATED = 'delegated'
        MANUAL = 'manual'
        SYSTEM = 'system'



class VPCDNSResolverPatch:
    """
    VPCDNSResolverPatch.

    :attr List[DNSServerPrototype] manual_servers: (optional) The DNS servers to use
          for this VPC, replacing any existing servers. All the DNS servers must either:
          - have a unique `zone_affinity`, or
          - not have a `zone_affinity`.
          `dns.resolver.manual_servers` must be set if and only if `dns.resolver.type` is
          `manual`.
    :attr str type: (optional) The type of the DNS resolver to use.
          - `delegated`: DNS server addresses will be provided by the resolver for the VPC
                         specified in `dns.resolver.vpc`. Requires `dns.enable_hub` to be
                         `false`.
          - `manual`: DNS server addresses are specified in `dns.resolver.manual_servers`.
          - `system`: DNS server addresses will be provided by the system and depend on
          the
                      configuration.
          Updating from `manual` requires `dns.resolver.manual_servers` to be specified as
          `null`.
          Updating to `manual` requires `dns.resolver.manual_servers` to be specified and
          not empty.
          Updating from `delegated` requires `dns.resolver.vpc` to be specified as `null`.
    :attr VPCDNSResolverVPCPatch vpc: (optional) The VPC to provide DNS server
          addresses for this VPC.  The specified VPC must be configured
          with a [DNS Services](https://cloud.ibm.com/docs/dns-svcs) custom resolver and
          must be in
          one of this VPC's DNS resolution bindings.
          Specify `null` to remove an existing VPC.
          This property must be set if and only if `dns.resolver.type` is `delegated`.
    """

    def __init__(
        self,
        *,
        manual_servers: List['DNSServerPrototype'] = None,
        type: str = None,
        vpc: 'VPCDNSResolverVPCPatch' = None,
    ) -> None:
        """
        Initialize a VPCDNSResolverPatch object.

        :param List[DNSServerPrototype] manual_servers: (optional) The DNS servers
               to use for this VPC, replacing any existing servers. All the DNS servers
               must either:
               - have a unique `zone_affinity`, or
               - not have a `zone_affinity`.
               `dns.resolver.manual_servers` must be set if and only if
               `dns.resolver.type` is `manual`.
        :param str type: (optional) The type of the DNS resolver to use.
               - `delegated`: DNS server addresses will be provided by the resolver for
               the VPC
                              specified in `dns.resolver.vpc`. Requires `dns.enable_hub`
               to be
                              `false`.
               - `manual`: DNS server addresses are specified in
               `dns.resolver.manual_servers`.
               - `system`: DNS server addresses will be provided by the system and depend
               on the
                           configuration.
               Updating from `manual` requires `dns.resolver.manual_servers` to be
               specified as
               `null`.
               Updating to `manual` requires `dns.resolver.manual_servers` to be specified
               and not empty.
               Updating from `delegated` requires `dns.resolver.vpc` to be specified as
               `null`.
        :param VPCDNSResolverVPCPatch vpc: (optional) The VPC to provide DNS server
               addresses for this VPC.  The specified VPC must be configured
               with a [DNS Services](https://cloud.ibm.com/docs/dns-svcs) custom resolver
               and must be in
               one of this VPC's DNS resolution bindings.
               Specify `null` to remove an existing VPC.
               This property must be set if and only if `dns.resolver.type` is
               `delegated`.
        """
        self.manual_servers = manual_servers
        self.type = type
        self.vpc = vpc

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPCDNSResolverPatch':
        """Initialize a VPCDNSResolverPatch object from a json dictionary."""
        args = {}
        if 'manual_servers' in _dict:
            args['manual_servers'] = [DNSServerPrototype.from_dict(v) for v in _dict.get('manual_servers')]
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        if 'vpc' in _dict:
            args['vpc'] = _dict.get('vpc')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPCDNSResolverPatch object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'manual_servers') and self.manual_servers is not None:
            manual_servers_list = []
            for v in self.manual_servers:
                if isinstance(v, dict):
                    manual_servers_list.append(v)
                else:
                    manual_servers_list.append(v.to_dict())
            _dict['manual_servers'] = manual_servers_list
        if hasattr(self, 'type') and self.type is not None:
            _dict['type'] = self.type
        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()
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VPCDNSResolverPatch object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPCDNSResolverPatch') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPCDNSResolverPatch') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class TypeEnum(str, Enum):
        """
        The type of the DNS resolver to use.
        - `delegated`: DNS server addresses will be provided by the resolver for the VPC
                       specified in `dns.resolver.vpc`. Requires `dns.enable_hub` to be
                       `false`.
        - `manual`: DNS server addresses are specified in `dns.resolver.manual_servers`.
        - `system`: DNS server addresses will be provided by the system and depend on the
                    configuration.
        Updating from `manual` requires `dns.resolver.manual_servers` to be specified as
        `null`.
        Updating to `manual` requires `dns.resolver.manual_servers` to be specified and
        not empty.
        Updating from `delegated` requires `dns.resolver.vpc` to be specified as `null`.
        """

        DELEGATED = 'delegated'
        MANUAL = 'manual'
        SYSTEM = 'system'



class VPCDNSResolverPrototype:
    """
    VPCDNSResolverPrototype.

    :attr str type: (optional) The type of the DNS resolver to use.
          - `manual`: DNS server addresses are specified in `dns.resolver.manual_servers`.
          - `system`: DNS server addresses will be provided by the system and depend on
          the
                      configuration.
    """

    def __init__(
        self,
        *,
        type: str = None,
    ) -> None:
        """
        Initialize a VPCDNSResolverPrototype object.

        :param str type: (optional) The type of the DNS resolver to use.
               - `manual`: DNS server addresses are specified in
               `dns.resolver.manual_servers`.
               - `system`: DNS server addresses will be provided by the system and depend
               on the
                           configuration.
        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['VPCDNSResolverPrototypeVPCDNSResolverTypeManualPrototype', 'VPCDNSResolverPrototypeVPCDNSResolverTypeSystemPrototype'])
        )
        raise Exception(msg)

    class TypeEnum(str, Enum):
        """
        The type of the DNS resolver to use.
        - `manual`: DNS server addresses are specified in `dns.resolver.manual_servers`.
        - `system`: DNS server addresses will be provided by the system and depend on the
                    configuration.
        """

        MANUAL = 'manual'
        SYSTEM = 'system'



class VPCDNSResolverVPCPatch:
    """
    The VPC to provide DNS server addresses for this VPC.  The specified VPC must be
    configured with a [DNS Services](https://cloud.ibm.com/docs/dns-svcs) custom resolver
    and must be in one of this VPC's DNS resolution bindings.
    Specify `null` to remove an existing VPC.
    This property must be set if and only if `dns.resolver.type` is `delegated`.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a VPCDNSResolverVPCPatch object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['VPCDNSResolverVPCPatchVPCIdentityById', 'VPCDNSResolverVPCPatchVPCIdentityByCRN', 'VPCDNSResolverVPCPatchVPCIdentityByHref'])
        )
        raise Exception(msg)


class VPCHealthReason:
    """
    VPCHealthReason.

    :attr str code: A snake case string succinctly identifying the reason for this
          health state.
    :attr str message: An explanation of the reason for this health state.
    :attr str more_info: (optional) Link to documentation about the reason for this
          health state.
    """

    def __init__(
        self,
        code: str,
        message: str,
        *,
        more_info: str = None,
    ) -> None:
        """
        Initialize a VPCHealthReason object.

        :param str code: A snake case string succinctly identifying the reason for
               this health state.
        :param str message: An explanation of the reason for this health state.
        :param str more_info: (optional) Link to documentation about the reason for
               this health state.
        """
        self.code = code
        self.message = message
        self.more_info = more_info

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPCHealthReason':
        """Initialize a VPCHealthReason object from a json dictionary."""
        args = {}
        if 'code' in _dict:
            args['code'] = _dict.get('code')
        else:
            raise ValueError('Required property \'code\' not present in VPCHealthReason JSON')
        if 'message' in _dict:
            args['message'] = _dict.get('message')
        else:
            raise ValueError('Required property \'message\' not present in VPCHealthReason JSON')
        if 'more_info' in _dict:
            args['more_info'] = _dict.get('more_info')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPCHealthReason object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'code') and self.code is not None:
            _dict['code'] = self.code
        if hasattr(self, 'message') and self.message is not None:
            _dict['message'] = self.message
        if hasattr(self, 'more_info') and self.more_info is not None:
            _dict['more_info'] = self.more_info
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VPCHealthReason object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPCHealthReason') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPCHealthReason') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class CodeEnum(str, Enum):
        """
        A snake case string succinctly identifying the reason for this health state.
        """

        INTERNAL_ERROR = 'internal_error'



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 VPCDNSPatch dns: (optional) The DNS configuration for this VPC.
    :attr str name: (optional) The name for this VPC. The name must not be used by
          another VPC in the region.
    """

    def __init__(
        self,
        *,
        dns: 'VPCDNSPatch' = None,
        name: str = None,
    ) -> None:
        """
        Initialize a VPCPatch object.

        :param VPCDNSPatch dns: (optional) The DNS configuration for this VPC.
        :param str name: (optional) The name for this VPC. The name must not be
               used by another VPC in the region.
        """
        self.dns = dns
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPCPatch':
        """Initialize a VPCPatch object from a json dictionary."""
        args = {}
        if 'dns' in _dict:
            args['dns'] = VPCDNSPatch.from_dict(_dict.get('dns'))
        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, 'dns') and self.dns is not None:
            if isinstance(self.dns, dict):
                _dict['dns'] = self.dns
            else:
                _dict['dns'] = self.dns.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 VPCPatch object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPCPatch') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPCPatch') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VPCReference:
    """
    VPCReference.

    :attr str crn: The CRN for this VPC.
    :attr VPCReferenceDeleted deleted: (optional) If present, this property
          indicates the referenced resource has been deleted, and provides
          some supplementary information.
    :attr str href: The URL for this VPC.
    :attr str id: The unique identifier for this VPC.
    :attr str name: The name for this VPC. The name is unique across all VPCs in the
          region.
    :attr str resource_type: The resource type.
    """

    def __init__(
        self,
        crn: str,
        href: str,
        id: str,
        name: str,
        resource_type: str,
        *,
        deleted: 'VPCReferenceDeleted' = None,
    ) -> None:
        """
        Initialize a VPCReference object.

        :param str crn: The CRN for this VPC.
        :param str href: The URL for this VPC.
        :param str id: The unique identifier for this VPC.
        :param str name: The name for this VPC. The name is unique across all VPCs
               in the region.
        :param str resource_type: The resource type.
        :param VPCReferenceDeleted deleted: (optional) If present, this property
               indicates the referenced resource has been deleted, and provides
               some supplementary information.
        """
        self.crn = crn
        self.deleted = deleted
        self.href = href
        self.id = id
        self.name = name
        self.resource_type = resource_type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPCReference':
        """Initialize a VPCReference object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError('Required property \'crn\' not present in VPCReference JSON')
        if 'deleted' in _dict:
            args['deleted'] = VPCReferenceDeleted.from_dict(_dict.get('deleted'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in VPCReference JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in VPCReference JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in VPCReference JSON')
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError('Required property \'resource_type\' not present in VPCReference JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPCReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'deleted') and self.deleted is not None:
            if isinstance(self.deleted, dict):
                _dict['deleted'] = self.deleted
            else:
                _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'resource_type') and self.resource_type is not None:
            _dict['resource_type'] = self.resource_type
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this 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 ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        VPC = 'vpc'



class VPCReferenceDNSResolverContext:
    """
    A VPC whose DNS resolver is delegated to provide DNS servers for this VPC.
    The VPC may be remote and therefore may not be directly retrievable.

    :attr str crn: The CRN for this VPC.
    :attr VPCReferenceDNSResolverContextDeleted deleted: (optional) If present, this
          property indicates the referenced resource has been deleted, and provides
          some supplementary information.
    :attr str href: The URL for this VPC.
    :attr str id: The unique identifier for this VPC.
    :attr str name: The name for this VPC. The name is unique across all VPCs in the
          region.
    :attr VPCRemote remote: (optional) If present, this property indicates that the
          resource associated with this reference
          is remote and therefore may not be directly retrievable.
    :attr str resource_type: The resource type.
    """

    def __init__(
        self,
        crn: str,
        href: str,
        id: str,
        name: str,
        resource_type: str,
        *,
        deleted: 'VPCReferenceDNSResolverContextDeleted' = None,
        remote: 'VPCRemote' = None,
    ) -> None:
        """
        Initialize a VPCReferenceDNSResolverContext 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 name for this VPC. The name is unique across all VPCs
               in the region.
        :param str resource_type: The resource type.
        :param VPCReferenceDNSResolverContextDeleted deleted: (optional) If
               present, this property indicates the referenced resource has been deleted,
               and provides
               some supplementary information.
        :param VPCRemote remote: (optional) If present, this property indicates
               that the resource associated with this reference
               is remote and therefore may not be directly retrievable.
        """
        self.crn = crn
        self.deleted = deleted
        self.href = href
        self.id = id
        self.name = name
        self.remote = remote
        self.resource_type = resource_type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPCReferenceDNSResolverContext':
        """Initialize a VPCReferenceDNSResolverContext object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError('Required property \'crn\' not present in VPCReferenceDNSResolverContext JSON')
        if 'deleted' in _dict:
            args['deleted'] = VPCReferenceDNSResolverContextDeleted.from_dict(_dict.get('deleted'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in VPCReferenceDNSResolverContext JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in VPCReferenceDNSResolverContext JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in VPCReferenceDNSResolverContext JSON')
        if 'remote' in _dict:
            args['remote'] = VPCRemote.from_dict(_dict.get('remote'))
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError('Required property \'resource_type\' not present in VPCReferenceDNSResolverContext JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPCReferenceDNSResolverContext object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'deleted') and self.deleted is not None:
            if isinstance(self.deleted, dict):
                _dict['deleted'] = self.deleted
            else:
                _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, '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, '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 VPCReferenceDNSResolverContext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPCReferenceDNSResolverContext') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPCReferenceDNSResolverContext') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        VPC = 'vpc'



class VPCReferenceDNSResolverContextDeleted:
    """
    If present, this property indicates the referenced resource has been deleted, and
    provides some supplementary information.

    :attr str more_info: Link to documentation about deleted resources.
    """

    def __init__(
        self,
        more_info: str,
    ) -> None:
        """
        Initialize a VPCReferenceDNSResolverContextDeleted object.

        :param str more_info: Link to documentation about deleted resources.
        """
        self.more_info = more_info

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPCReferenceDNSResolverContextDeleted':
        """Initialize a VPCReferenceDNSResolverContextDeleted object from a json dictionary."""
        args = {}
        if 'more_info' in _dict:
            args['more_info'] = _dict.get('more_info')
        else:
            raise ValueError('Required property \'more_info\' not present in VPCReferenceDNSResolverContextDeleted JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPCReferenceDNSResolverContextDeleted object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'more_info') and self.more_info is not None:
            _dict['more_info'] = self.more_info
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VPCReferenceDNSResolverContextDeleted object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPCReferenceDNSResolverContextDeleted') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPCReferenceDNSResolverContextDeleted') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VPCReferenceDeleted:
    """
    If present, this property indicates the referenced resource has been deleted, and
    provides some supplementary information.

    :attr str more_info: Link to documentation about deleted resources.
    """

    def __init__(
        self,
        more_info: str,
    ) -> None:
        """
        Initialize a VPCReferenceDeleted object.

        :param str more_info: Link to documentation about deleted resources.
        """
        self.more_info = more_info

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPCReferenceDeleted':
        """Initialize a VPCReferenceDeleted object from a json dictionary."""
        args = {}
        if 'more_info' in _dict:
            args['more_info'] = _dict.get('more_info')
        else:
            raise ValueError('Required property \'more_info\' not present in VPCReferenceDeleted JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPCReferenceDeleted object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'more_info') and self.more_info is not None:
            _dict['more_info'] = self.more_info
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VPCReferenceDeleted object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPCReferenceDeleted') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPCReferenceDeleted') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VPCReferenceRemote:
    """
    VPCReferenceRemote.

    :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 name for this VPC. The name is unique across all VPCs in the
          region.
    :attr VPCRemote remote: (optional) If present, this property indicates that the
          resource associated with this reference
          is remote and therefore may not be directly retrievable.
    :attr str resource_type: The resource type.
    """

    def __init__(
        self,
        crn: str,
        href: str,
        id: str,
        name: str,
        resource_type: str,
        *,
        remote: 'VPCRemote' = None,
    ) -> None:
        """
        Initialize a VPCReferenceRemote 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 name for this VPC. The name is unique across all VPCs
               in the region.
        :param str resource_type: The resource type.
        :param VPCRemote remote: (optional) If present, this property indicates
               that the resource associated with this reference
               is remote and therefore may not be directly retrievable.
        """
        self.crn = crn
        self.href = href
        self.id = id
        self.name = name
        self.remote = remote
        self.resource_type = resource_type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPCReferenceRemote':
        """Initialize a VPCReferenceRemote object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError('Required property \'crn\' not present in VPCReferenceRemote JSON')
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in VPCReferenceRemote JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in VPCReferenceRemote JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in VPCReferenceRemote JSON')
        if 'remote' in _dict:
            args['remote'] = VPCRemote.from_dict(_dict.get('remote'))
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError('Required property \'resource_type\' not present in VPCReferenceRemote JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPCReferenceRemote object from 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, '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, '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 VPCReferenceRemote object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPCReferenceRemote') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPCReferenceRemote') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        VPC = 'vpc'



class VPCRemote:
    """
    If present, this property indicates that the resource associated with this reference
    is remote and therefore may not be directly retrievable.

    :attr AccountReference account: (optional) If present, this property indicates
          that the referenced resource is remote to this
          account, and identifies the owning account.
    :attr RegionReference region: (optional) If present, this property indicates
          that the referenced resource is remote to this
          region, and identifies the native region.
    """

    def __init__(
        self,
        *,
        account: 'AccountReference' = None,
        region: 'RegionReference' = None,
    ) -> None:
        """
        Initialize a VPCRemote object.

        :param AccountReference account: (optional) If present, this property
               indicates that the referenced resource is remote to this
               account, and identifies the owning account.
        :param RegionReference region: (optional) If present, this property
               indicates that the referenced resource is remote to this
               region, and identifies the native region.
        """
        self.account = account
        self.region = region

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPCRemote':
        """Initialize a VPCRemote object from a json dictionary."""
        args = {}
        if 'account' in _dict:
            args['account'] = AccountReference.from_dict(_dict.get('account'))
        if 'region' in _dict:
            args['region'] = RegionReference.from_dict(_dict.get('region'))
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPCRemote object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'account') and self.account is not None:
            if isinstance(self.account, dict):
                _dict['account'] = self.account
            else:
                _dict['account'] = self.account.to_dict()
        if hasattr(self, 'region') and self.region is not None:
            if isinstance(self.region, dict):
                _dict['region'] = self.region
            else:
                _dict['region'] = self.region.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 VPCRemote object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPCRemote') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPCRemote') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VPNGateway:
    """
    VPNGateway.

    :attr List[VPNGatewayConnectionReference] connections: Connections for this VPN
          gateway.
    :attr datetime created_at: The date and time that this VPN gateway was created.
    :attr str crn: The VPN gateway's CRN.
    :attr List[VPNGatewayHealthReason] health_reasons: The reasons for the current
          VPN gateway health_state (if any):
          - `cannot_create_vpc_route`: VPN cannot create route (check for conflict)
          - `cannot_reserve_ip_address`: IP address exhaustion (release addresses on the
          VPN's
            subnet)
          - `internal_error`: Internal error (contact IBM support)
          The enumerated reason code values for this property will expand in the future.
          When processing this property, check for and log unknown values. Optionally halt
          processing and surface the error, or bypass the resource on which the unexpected
          reason code was encountered.
    :attr str health_state: The health of this resource.
          - `ok`: No abnormal behavior detected
          - `degraded`: Experiencing compromised performance, capacity, or connectivity
          - `faulted`: Completely unreachable, inoperative, or otherwise entirely
          incapacitated
          - `inapplicable`: The health state does not apply because of the current
          lifecycle state. A resource with a lifecycle state of `failed` or `deleting`
          will have a health state of `inapplicable`. A `pending` resource may also have
          this state.
    :attr str href: The VPN gateway's canonical URL.
    :attr str id: The unique identifier for this VPN gateway.
    :attr List[VPNGatewayLifecycleReason] lifecycle_reasons: The reasons for the
          current VPN gateway lifecycle_state (if any):
          - `resource_suspended_by_provider`: The resource has been suspended (contact IBM
            support)
          The enumerated reason code values for this property will expand in the future.
          When processing this property, check for and log unknown values. Optionally halt
          processing and surface the error, or bypass the resource on which the unexpected
          reason code was encountered.
    :attr str lifecycle_state: The lifecycle state of the VPN gateway.
    :attr List[VPNGatewayMember] members: Collection of VPN gateway members.
    :attr str name: The name for this VPN gateway. The name is unique across all VPN
          gateways in the VPC.
    :attr ResourceGroupReference resource_group: The resource group for this VPN
          gateway.
    :attr str resource_type: The resource type.
    :attr SubnetReference subnet:
    :attr VPCReference vpc: The VPC this VPN gateway resides in.
    """

    def __init__(
        self,
        connections: List['VPNGatewayConnectionReference'],
        created_at: datetime,
        crn: str,
        health_reasons: List['VPNGatewayHealthReason'],
        health_state: str,
        href: str,
        id: str,
        lifecycle_reasons: List['VPNGatewayLifecycleReason'],
        lifecycle_state: str,
        members: List['VPNGatewayMember'],
        name: str,
        resource_group: 'ResourceGroupReference',
        resource_type: str,
        subnet: 'SubnetReference',
        vpc: 'VPCReference',
    ) -> None:
        """
        Initialize a VPNGateway object.

        :param List[VPNGatewayConnectionReference] connections: Connections for
               this VPN gateway.
        :param datetime created_at: The date and time that this VPN gateway was
               created.
        :param str crn: The VPN gateway's CRN.
        :param List[VPNGatewayHealthReason] health_reasons: The reasons for the
               current VPN gateway health_state (if any):
               - `cannot_create_vpc_route`: VPN cannot create route (check for conflict)
               - `cannot_reserve_ip_address`: IP address exhaustion (release addresses on
               the VPN's
                 subnet)
               - `internal_error`: Internal error (contact IBM support)
               The enumerated reason code values for this property will expand in the
               future. When processing this property, check for and log unknown values.
               Optionally halt processing and surface the error, or bypass the resource on
               which the unexpected reason code was encountered.
        :param str health_state: The health of this resource.
               - `ok`: No abnormal behavior detected
               - `degraded`: Experiencing compromised performance, capacity, or
               connectivity
               - `faulted`: Completely unreachable, inoperative, or otherwise entirely
               incapacitated
               - `inapplicable`: The health state does not apply because of the current
               lifecycle state. A resource with a lifecycle state of `failed` or
               `deleting` will have a health state of `inapplicable`. A `pending` resource
               may also have this state.
        :param str href: The VPN gateway's canonical URL.
        :param str id: The unique identifier for this VPN gateway.
        :param List[VPNGatewayLifecycleReason] lifecycle_reasons: The reasons for
               the current VPN gateway lifecycle_state (if any):
               - `resource_suspended_by_provider`: The resource has been suspended
               (contact IBM
                 support)
               The enumerated reason code values for this property will expand in the
               future. When processing this property, check for and log unknown values.
               Optionally halt processing and surface the error, or bypass the resource on
               which the unexpected reason code was encountered.
        :param str lifecycle_state: The lifecycle state of the VPN gateway.
        :param List[VPNGatewayMember] members: Collection of VPN gateway members.
        :param str name: The name for this VPN gateway. The name is unique across
               all VPN gateways in the VPC.
        :param ResourceGroupReference resource_group: The resource group for this
               VPN gateway.
        :param str resource_type: The resource type.
        :param SubnetReference subnet:
        :param VPCReference vpc: The VPC this VPN gateway resides in.
        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['VPNGatewayRouteMode', 'VPNGatewayPolicyMode'])
        )
        raise Exception(msg)

    class HealthStateEnum(str, Enum):
        """
        The health of this resource.
        - `ok`: No abnormal behavior detected
        - `degraded`: Experiencing compromised performance, capacity, or connectivity
        - `faulted`: Completely unreachable, inoperative, or otherwise entirely
        incapacitated
        - `inapplicable`: The health state does not apply because of the current lifecycle
        state. A resource with a lifecycle state of `failed` or `deleting` will have a
        health state of `inapplicable`. A `pending` resource may also have this state.
        """

        DEGRADED = 'degraded'
        FAULTED = 'faulted'
        INAPPLICABLE = 'inapplicable'
        OK = 'ok'


    class LifecycleStateEnum(str, Enum):
        """
        The lifecycle state of the VPN gateway.
        """

        DELETING = 'deleting'
        FAILED = 'failed'
        PENDING = 'pending'
        STABLE = 'stable'
        SUSPENDED = 'suspended'
        UPDATING = 'updating'
        WAITING = 'waiting'


    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        VPN_GATEWAY = 'vpn_gateway'



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:
            if isinstance(self.first, dict):
                _dict['first'] = self.first
            else:
                _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:
            if isinstance(self.next, dict):
                _dict['next'] = self.next
            else:
                _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 v in self.vpn_gateways:
                if isinstance(v, dict):
                    vpn_gateways_list.append(v)
                else:
                    vpn_gateways_list.append(v.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) The IKE policy. If absent,
          [auto-negotiation is
          used](https://cloud.ibm.com/docs/vpc?topic=vpc-using-vpn&interface=ui#ike-auto-negotiation-phase-1).
    :attr IPsecPolicyReference ipsec_policy: (optional) The IPsec policy. If absent,
          [auto-negotiation is
          used](https://cloud.ibm.com/docs/vpc?topic=vpc-using-vpn&interface=ui#ipsec-auto-negotiation-phase-2).
    :attr str mode: The mode of the VPN gateway.
    :attr str name: The name for this VPN gateway connection. The name is unique
          across all connections for the VPN gateway.
    :attr str peer_address: The IP address of the peer VPN gateway.
    :attr str psk: The pre-shared key.
    :attr str resource_type: The resource type.
    :attr str status: The status of a VPN gateway connection.
    :attr List[VPNGatewayConnectionStatusReason] status_reasons: The reasons for the
          current VPN gateway connection status (if any):
          - `cannot_authenticate_connection`: Failed to authenticate a connection because
          of
            mismatched IKE ID and PSK (check IKE ID and PSK in peer VPN configuration)
          - `internal_error`: Internal error (contact IBM support)
          - `ike_policy_mismatch`: None of the proposed IKE crypto suites was acceptable
          (check
             the IKE policies on both sides of the VPN)
          - `ike_v1_id_local_remote_cidr_mismatch`: Invalid IKE ID or mismatched local
          CIDRs and
            remote CIDRs in IKE V1 (check the IKE ID or the local CIDRs and remote CIDRs
          in IKE
            V1 configuration)
          - `ike_v2_local_remote_cidr_mismatch`: Mismatched local CIDRs and remote CIDRs
          in IKE
            V2 (check the local CIDRs and remote CIDRs in IKE V2 configuration)
          - `ipsec_policy_mismatch`: None of the proposed IPsec crypto suites was
          acceptable
            (check the IPsec policies on both sides of the VPN)
          - `peer_not_responding`: No response from peer (check network ACL configuration,
          peer
            availability, and on-premise firewall configuration)
          The enumerated reason code values for this property will expand in the future.
          When processing this property, check for and log unknown values. Optionally halt
          processing and surface the error, or bypass the resource on which the unexpected
          reason code was encountered.
    """

    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,
        status_reasons: List['VPNGatewayConnectionStatusReason'],
        *,
        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 name for this VPN gateway connection. The name is
               unique across all connections for the VPN gateway.
        :param str peer_address: The IP address of the peer VPN gateway.
        :param str psk: The pre-shared key.
        :param str resource_type: The resource type.
        :param str status: The status of a VPN gateway connection.
        :param List[VPNGatewayConnectionStatusReason] status_reasons: The reasons
               for the current VPN gateway connection status (if any):
               - `cannot_authenticate_connection`: Failed to authenticate a connection
               because of
                 mismatched IKE ID and PSK (check IKE ID and PSK in peer VPN
               configuration)
               - `internal_error`: Internal error (contact IBM support)
               - `ike_policy_mismatch`: None of the proposed IKE crypto suites was
               acceptable (check
                  the IKE policies on both sides of the VPN)
               - `ike_v1_id_local_remote_cidr_mismatch`: Invalid IKE ID or mismatched
               local CIDRs and
                 remote CIDRs in IKE V1 (check the IKE ID or the local CIDRs and remote
               CIDRs in IKE
                 V1 configuration)
               - `ike_v2_local_remote_cidr_mismatch`: Mismatched local CIDRs and remote
               CIDRs in IKE
                 V2 (check the local CIDRs and remote CIDRs in IKE V2 configuration)
               - `ipsec_policy_mismatch`: None of the proposed IPsec crypto suites was
               acceptable
                 (check the IPsec policies on both sides of the VPN)
               - `peer_not_responding`: No response from peer (check network ACL
               configuration, peer
                 availability, and on-premise firewall configuration)
               The enumerated reason code values for this property will expand in the
               future. When processing this property, check for and log unknown values.
               Optionally halt processing and surface the error, or bypass the resource on
               which the unexpected reason code was encountered.
        :param IKEPolicyReference ike_policy: (optional) The IKE policy. If absent,
               [auto-negotiation is
               used](https://cloud.ibm.com/docs/vpc?topic=vpc-using-vpn&interface=ui#ike-auto-negotiation-phase-1).
        :param IPsecPolicyReference ipsec_policy: (optional) The IPsec policy. If
               absent, [auto-negotiation is
               used](https://cloud.ibm.com/docs/vpc?topic=vpc-using-vpn&interface=ui#ipsec-auto-negotiation-phase-2).
        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['VPNGatewayConnectionStaticRouteMode', 'VPNGatewayConnectionPolicyMode'])
        )
        raise Exception(msg)

    class AuthenticationModeEnum(str, Enum):
        """
        The authentication mode. Only `psk` is currently supported.
        """

        PSK = 'psk'


    class ModeEnum(str, Enum):
        """
        The mode of the VPN gateway.
        """

        POLICY = 'policy'
        ROUTE = 'route'


    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        VPN_GATEWAY_CONNECTION = 'vpn_gateway_connection'


    class StatusEnum(str, Enum):
        """
        The status of a VPN gateway connection.
        """

        DOWN = 'down'
        UP = 'up'



class VPNGatewayConnectionCollection:
    """
    Collection of VPN gateway connections in a VPN gateway.

    :attr List[VPNGatewayConnection] connections: Array of VPN gateway connections.
    """

    def __init__(
        self,
        connections: List['VPNGatewayConnection'],
    ) -> None:
        """
        Initialize a VPNGatewayConnectionCollection object.

        :param List[VPNGatewayConnection] connections: Array of VPN gateway
               connections.
        """
        self.connections = connections

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPNGatewayConnectionCollection':
        """Initialize a VPNGatewayConnectionCollection object from a json dictionary."""
        args = {}
        if 'connections' in _dict:
            args['connections'] = _dict.get('connections')
        else:
            raise ValueError('Required property \'connections\' not present in VPNGatewayConnectionCollection JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPNGatewayConnectionCollection object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'connections') and self.connections is not None:
            connections_list = []
            for v in self.connections:
                if isinstance(v, dict):
                    connections_list.append(v)
                else:
                    connections_list.append(v.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 VPNGatewayConnectionDPDPatch:
    """
    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 VPNGatewayConnectionDPDPatch 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) -> 'VPNGatewayConnectionDPDPatch':
        """Initialize a VPNGatewayConnectionDPDPatch 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 VPNGatewayConnectionDPDPatch object from 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 VPNGatewayConnectionDPDPatch object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPNGatewayConnectionDPDPatch') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPNGatewayConnectionDPDPatch') -> 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 VPNGatewayConnectionIKEPolicyPatch:
    """
    The IKE policy to use. Specify `null` to remove any existing policy, [resulting in
    auto-negotiation](https://cloud.ibm.com/docs/vpc?topic=vpc-using-vpn&interface=ui#ike-auto-negotiation-phase-1).

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a VPNGatewayConnectionIKEPolicyPatch object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['VPNGatewayConnectionIKEPolicyPatchIKEPolicyIdentityById', 'VPNGatewayConnectionIKEPolicyPatchIKEPolicyIdentityByHref'])
        )
        raise Exception(msg)


class VPNGatewayConnectionIKEPolicyPrototype:
    """
    The IKE policy to use. If unspecified, [auto-negotiation will be
    used](https://cloud.ibm.com/docs/vpc?topic=vpc-using-vpn&interface=ui#ike-auto-negotiation-phase-1).

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a VPNGatewayConnectionIKEPolicyPrototype object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['VPNGatewayConnectionIKEPolicyPrototypeIKEPolicyIdentityById', 'VPNGatewayConnectionIKEPolicyPrototypeIKEPolicyIdentityByHref'])
        )
        raise Exception(msg)


class VPNGatewayConnectionIPsecPolicyPatch:
    """
    The IPsec policy to use. Specify `null` to remove any existing policy, [resulting in
    auto-negotiation](https://cloud.ibm.com/docs/vpc?topic=vpc-using-vpn&interface=ui#ipsec-auto-negotiation-phase-2).

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a VPNGatewayConnectionIPsecPolicyPatch object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['VPNGatewayConnectionIPsecPolicyPatchIPsecPolicyIdentityById', 'VPNGatewayConnectionIPsecPolicyPatchIPsecPolicyIdentityByHref'])
        )
        raise Exception(msg)


class VPNGatewayConnectionIPsecPolicyPrototype:
    """
    The IPsec policy to use. If unspecified, [auto-negotiation will be
    used](https://cloud.ibm.com/docs/vpc?topic=vpc-using-vpn&interface=ui#ipsec-auto-negotiation-phase-2).

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a VPNGatewayConnectionIPsecPolicyPrototype object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['VPNGatewayConnectionIPsecPolicyPrototypeIPsecPolicyIdentityById', 'VPNGatewayConnectionIPsecPolicyPrototypeIPsecPolicyIdentityByHref'])
        )
        raise Exception(msg)


class VPNGatewayConnectionLocalCIDRs:
    """
    VPNGatewayConnectionLocalCIDRs.

    :attr List[str] local_cidrs: (optional) The local CIDRs for this resource.
    """

    def __init__(
        self,
        *,
        local_cidrs: List[str] = None,
    ) -> None:
        """
        Initialize a VPNGatewayConnectionLocalCIDRs object.

        :param List[str] local_cidrs: (optional) The 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 VPNGatewayConnectionDPDPatch dead_peer_detection: (optional) The Dead Peer
          Detection settings.
    :attr VPNGatewayConnectionIKEPolicyPatch ike_policy: (optional) The IKE policy
          to use. Specify `null` to remove any existing policy, [resulting in
          auto-negotiation](https://cloud.ibm.com/docs/vpc?topic=vpc-using-vpn&interface=ui#ike-auto-negotiation-phase-1).
    :attr VPNGatewayConnectionIPsecPolicyPatch ipsec_policy: (optional) The IPsec
          policy to use. Specify `null` to remove any existing policy, [resulting in
          auto-negotiation](https://cloud.ibm.com/docs/vpc?topic=vpc-using-vpn&interface=ui#ipsec-auto-negotiation-phase-2).
    :attr str name: (optional) The name for this VPN gateway connection. The name
          must not be used by another connection for the VPN gateway.
    :attr str peer_address: (optional) The IP address of the peer VPN gateway.
    :attr str psk: (optional) The pre-shared key.
    """

    def __init__(
        self,
        *,
        admin_state_up: bool = None,
        dead_peer_detection: 'VPNGatewayConnectionDPDPatch' = None,
        ike_policy: 'VPNGatewayConnectionIKEPolicyPatch' = None,
        ipsec_policy: 'VPNGatewayConnectionIPsecPolicyPatch' = 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 VPNGatewayConnectionDPDPatch dead_peer_detection: (optional) The
               Dead Peer Detection settings.
        :param VPNGatewayConnectionIKEPolicyPatch ike_policy: (optional) The IKE
               policy to use. Specify `null` to remove any existing policy, [resulting in
               auto-negotiation](https://cloud.ibm.com/docs/vpc?topic=vpc-using-vpn&interface=ui#ike-auto-negotiation-phase-1).
        :param VPNGatewayConnectionIPsecPolicyPatch ipsec_policy: (optional) The
               IPsec policy to use. Specify `null` to remove any existing policy,
               [resulting in
               auto-negotiation](https://cloud.ibm.com/docs/vpc?topic=vpc-using-vpn&interface=ui#ipsec-auto-negotiation-phase-2).
        :param str name: (optional) The name for this VPN gateway connection. The
               name must not be used by another connection for the VPN gateway.
        :param str peer_address: (optional) The IP address of the peer VPN gateway.
        :param str psk: (optional) The pre-shared key.
        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['VPNGatewayConnectionPatchVPNGatewayConnectionStaticRouteModePatch'])
        )
        raise Exception(msg)


class VPNGatewayConnectionPeerCIDRs:
    """
    VPNGatewayConnectionPeerCIDRs.

    :attr List[str] peer_cidrs: (optional) The peer CIDRs for this resource.
    """

    def __init__(
        self,
        *,
        peer_cidrs: List[str] = None,
    ) -> None:
        """
        Initialize a VPNGatewayConnectionPeerCIDRs object.

        :param List[str] peer_cidrs: (optional) The 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 VPNGatewayConnectionIKEPolicyPrototype ike_policy: (optional) The IKE
          policy to use. If unspecified, [auto-negotiation will be
          used](https://cloud.ibm.com/docs/vpc?topic=vpc-using-vpn&interface=ui#ike-auto-negotiation-phase-1).
    :attr VPNGatewayConnectionIPsecPolicyPrototype ipsec_policy: (optional) The
          IPsec policy to use. If unspecified, [auto-negotiation will be
          used](https://cloud.ibm.com/docs/vpc?topic=vpc-using-vpn&interface=ui#ipsec-auto-negotiation-phase-2).
    :attr str name: (optional) The name for this VPN gateway connection. The name
          must not be used by another connection for the VPN gateway. If unspecified, the
          name will be a hyphenated list of randomly-selected words.
    :attr str peer_address: The IP address of the peer VPN gateway.
    :attr str psk: The pre-shared key.
    """

    def __init__(
        self,
        peer_address: str,
        psk: str,
        *,
        admin_state_up: bool = None,
        dead_peer_detection: 'VPNGatewayConnectionDPDPrototype' = None,
        ike_policy: 'VPNGatewayConnectionIKEPolicyPrototype' = None,
        ipsec_policy: 'VPNGatewayConnectionIPsecPolicyPrototype' = 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 pre-shared 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 VPNGatewayConnectionIKEPolicyPrototype ike_policy: (optional) The
               IKE policy to use. If unspecified, [auto-negotiation will be
               used](https://cloud.ibm.com/docs/vpc?topic=vpc-using-vpn&interface=ui#ike-auto-negotiation-phase-1).
        :param VPNGatewayConnectionIPsecPolicyPrototype ipsec_policy: (optional)
               The IPsec policy to use. If unspecified, [auto-negotiation will be
               used](https://cloud.ibm.com/docs/vpc?topic=vpc-using-vpn&interface=ui#ipsec-auto-negotiation-phase-2).
        :param str name: (optional) The name for this VPN gateway connection. The
               name must not be used by another connection for the VPN gateway. 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(['VPNGatewayConnectionPrototypeVPNGatewayConnectionStaticRouteModePrototype', 'VPNGatewayConnectionPrototypeVPNGatewayConnectionPolicyModePrototype'])
        )
        raise Exception(msg)


class VPNGatewayConnectionReference:
    """
    VPNGatewayConnectionReference.

    :attr VPNGatewayConnectionReferenceDeleted deleted: (optional) If present, this
          property indicates the referenced resource has been deleted, and provides
          some supplementary information.
    :attr str href: The VPN connection's canonical URL.
    :attr str id: The unique identifier for this VPN gateway connection.
    :attr str name: The name for this VPN gateway connection. The name is unique
          across all connections for the VPN gateway.
    :attr str resource_type: The resource type.
    """

    def __init__(
        self,
        href: str,
        id: str,
        name: str,
        resource_type: str,
        *,
        deleted: 'VPNGatewayConnectionReferenceDeleted' = None,
    ) -> None:
        """
        Initialize a VPNGatewayConnectionReference object.

        :param str href: The VPN connection's canonical URL.
        :param str id: The unique identifier for this VPN gateway connection.
        :param str name: The name for this VPN gateway connection. The name is
               unique across all connections for the VPN gateway.
        :param str resource_type: The resource type.
        :param VPNGatewayConnectionReferenceDeleted deleted: (optional) If present,
               this property indicates the referenced resource has been deleted, and
               provides
               some supplementary information.
        """
        self.deleted = deleted
        self.href = href
        self.id = id
        self.name = name
        self.resource_type = resource_type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPNGatewayConnectionReference':
        """Initialize a VPNGatewayConnectionReference object from a json dictionary."""
        args = {}
        if 'deleted' in _dict:
            args['deleted'] = VPNGatewayConnectionReferenceDeleted.from_dict(_dict.get('deleted'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in VPNGatewayConnectionReference JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in VPNGatewayConnectionReference JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in VPNGatewayConnectionReference JSON')
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError('Required property \'resource_type\' not present in VPNGatewayConnectionReference JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPNGatewayConnectionReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'deleted') and self.deleted is not None:
            if isinstance(self.deleted, dict):
                _dict['deleted'] = self.deleted
            else:
                _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'resource_type') and self.resource_type is not None:
            _dict['resource_type'] = self.resource_type
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VPNGatewayConnectionReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPNGatewayConnectionReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPNGatewayConnectionReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        VPN_GATEWAY_CONNECTION = 'vpn_gateway_connection'



class VPNGatewayConnectionReferenceDeleted:
    """
    If present, this property indicates the referenced resource has been deleted, and
    provides some supplementary information.

    :attr str more_info: Link to documentation about deleted resources.
    """

    def __init__(
        self,
        more_info: str,
    ) -> None:
        """
        Initialize a VPNGatewayConnectionReferenceDeleted object.

        :param str more_info: Link to documentation about deleted resources.
        """
        self.more_info = more_info

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPNGatewayConnectionReferenceDeleted':
        """Initialize a VPNGatewayConnectionReferenceDeleted object from a json dictionary."""
        args = {}
        if 'more_info' in _dict:
            args['more_info'] = _dict.get('more_info')
        else:
            raise ValueError('Required property \'more_info\' not present in VPNGatewayConnectionReferenceDeleted JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPNGatewayConnectionReferenceDeleted object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'more_info') and self.more_info is not None:
            _dict['more_info'] = self.more_info
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VPNGatewayConnectionReferenceDeleted object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPNGatewayConnectionReferenceDeleted') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPNGatewayConnectionReferenceDeleted') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VPNGatewayConnectionStaticRouteModeTunnel:
    """
    VPNGatewayConnectionStaticRouteModeTunnel.

    :attr IP public_ip: The IP address of the VPN gateway member in which the tunnel
          resides.
    :attr str status: The status of the VPN Tunnel.
    :attr List[VPNGatewayConnectionTunnelStatusReason] status_reasons: The reasons
          for the current VPN gateway connection tunnels status (if any):
          - `cannot_authenticate_connection`: Failed to authenticate a connection because
          of
            mismatched IKE ID and PSK (check IKE ID and PSK in peer VPN configuration)
          - `internal_error`: Internal error (contact IBM support)
          - `ike_policy_mismatch`: None of the proposed IKE crypto suites was acceptable
          (check
             the IKE policies on both sides of the VPN)
          - `ike_v1_id_local_remote_cidr_mismatch`: Invalid IKE ID or mismatched local
          CIDRs and
            remote CIDRs in IKE V1 (check the IKE ID or the local CIDRs and remote CIDRs
          in IKE
            V1 configuration)
          - `ike_v2_local_remote_cidr_mismatch`: Mismatched local CIDRs and remote CIDRs
          in IKE
            V2 (check the local CIDRs and remote CIDRs in IKE V2 configuration)
          - `ipsec_policy_mismatch`: None of the proposed IPsec crypto suites was
          acceptable
            (check the IPsec policies on both sides of the VPN)
          - `peer_not_responding`: No response from peer (check network ACL configuration,
          peer
            availability, and on-premise firewall configuration)
          The enumerated reason code values for this property will expand in the future.
          When processing this property, check for and log unknown values. Optionally halt
          processing and surface the error, or bypass the resource on which the unexpected
          reason code was encountered.
    """

    def __init__(
        self,
        public_ip: 'IP',
        status: str,
        status_reasons: List['VPNGatewayConnectionTunnelStatusReason'],
    ) -> None:
        """
        Initialize a VPNGatewayConnectionStaticRouteModeTunnel object.

        :param IP public_ip: The IP address of the VPN gateway member in which the
               tunnel resides.
        :param str status: The status of the VPN Tunnel.
        :param List[VPNGatewayConnectionTunnelStatusReason] status_reasons: The
               reasons for the current VPN gateway connection tunnels status (if any):
               - `cannot_authenticate_connection`: Failed to authenticate a connection
               because of
                 mismatched IKE ID and PSK (check IKE ID and PSK in peer VPN
               configuration)
               - `internal_error`: Internal error (contact IBM support)
               - `ike_policy_mismatch`: None of the proposed IKE crypto suites was
               acceptable (check
                  the IKE policies on both sides of the VPN)
               - `ike_v1_id_local_remote_cidr_mismatch`: Invalid IKE ID or mismatched
               local CIDRs and
                 remote CIDRs in IKE V1 (check the IKE ID or the local CIDRs and remote
               CIDRs in IKE
                 V1 configuration)
               - `ike_v2_local_remote_cidr_mismatch`: Mismatched local CIDRs and remote
               CIDRs in IKE
                 V2 (check the local CIDRs and remote CIDRs in IKE V2 configuration)
               - `ipsec_policy_mismatch`: None of the proposed IPsec crypto suites was
               acceptable
                 (check the IPsec policies on both sides of the VPN)
               - `peer_not_responding`: No response from peer (check network ACL
               configuration, peer
                 availability, and on-premise firewall configuration)
               The enumerated reason code values for this property will expand in the
               future. When processing this property, check for and log unknown values.
               Optionally halt processing and surface the error, or bypass the resource on
               which the unexpected reason code was encountered.
        """
        self.public_ip = public_ip
        self.status = status
        self.status_reasons = status_reasons

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPNGatewayConnectionStaticRouteModeTunnel':
        """Initialize a VPNGatewayConnectionStaticRouteModeTunnel object from a json dictionary."""
        args = {}
        if 'public_ip' in _dict:
            args['public_ip'] = IP.from_dict(_dict.get('public_ip'))
        else:
            raise ValueError('Required property \'public_ip\' not present in VPNGatewayConnectionStaticRouteModeTunnel JSON')
        if 'status' in _dict:
            args['status'] = _dict.get('status')
        else:
            raise ValueError('Required property \'status\' not present in VPNGatewayConnectionStaticRouteModeTunnel JSON')
        if 'status_reasons' in _dict:
            args['status_reasons'] = [VPNGatewayConnectionTunnelStatusReason.from_dict(v) for v in _dict.get('status_reasons')]
        else:
            raise ValueError('Required property \'status_reasons\' not present in VPNGatewayConnectionStaticRouteModeTunnel JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPNGatewayConnectionStaticRouteModeTunnel object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'public_ip') and self.public_ip is not None:
            if isinstance(self.public_ip, dict):
                _dict['public_ip'] = self.public_ip
            else:
                _dict['public_ip'] = self.public_ip.to_dict()
        if hasattr(self, 'status') and self.status is not None:
            _dict['status'] = self.status
        if hasattr(self, 'status_reasons') and self.status_reasons is not None:
            status_reasons_list = []
            for v in self.status_reasons:
                if isinstance(v, dict):
                    status_reasons_list.append(v)
                else:
                    status_reasons_list.append(v.to_dict())
            _dict['status_reasons'] = status_reasons_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 VPNGatewayConnectionStaticRouteModeTunnel object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPNGatewayConnectionStaticRouteModeTunnel') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPNGatewayConnectionStaticRouteModeTunnel') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class StatusEnum(str, Enum):
        """
        The status of the VPN Tunnel.
        """

        DOWN = 'down'
        UP = 'up'



class VPNGatewayConnectionStatusReason:
    """
    VPNGatewayConnectionStatusReason.

    :attr str code: A snake case string succinctly identifying the status reason.
    :attr str message: An explanation of the reason for this VPN gateway
          connection's status.
    :attr str more_info: (optional) Link to documentation about this status reason.
    """

    def __init__(
        self,
        code: str,
        message: str,
        *,
        more_info: str = None,
    ) -> None:
        """
        Initialize a VPNGatewayConnectionStatusReason object.

        :param str code: A snake case string succinctly identifying the status
               reason.
        :param str message: An explanation of the reason for this VPN gateway
               connection's status.
        :param str more_info: (optional) Link to documentation about this status
               reason.
        """
        self.code = code
        self.message = message
        self.more_info = more_info

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPNGatewayConnectionStatusReason':
        """Initialize a VPNGatewayConnectionStatusReason object from a json dictionary."""
        args = {}
        if 'code' in _dict:
            args['code'] = _dict.get('code')
        else:
            raise ValueError('Required property \'code\' not present in VPNGatewayConnectionStatusReason JSON')
        if 'message' in _dict:
            args['message'] = _dict.get('message')
        else:
            raise ValueError('Required property \'message\' not present in VPNGatewayConnectionStatusReason JSON')
        if 'more_info' in _dict:
            args['more_info'] = _dict.get('more_info')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPNGatewayConnectionStatusReason object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'code') and self.code is not None:
            _dict['code'] = self.code
        if hasattr(self, 'message') and self.message is not None:
            _dict['message'] = self.message
        if hasattr(self, 'more_info') and self.more_info is not None:
            _dict['more_info'] = self.more_info
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VPNGatewayConnectionStatusReason object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPNGatewayConnectionStatusReason') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPNGatewayConnectionStatusReason') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class CodeEnum(str, Enum):
        """
        A snake case string succinctly identifying the status reason.
        """

        CANNOT_AUTHENTICATE_CONNECTION = 'cannot_authenticate_connection'
        IKE_POLICY_MISMATCH = 'ike_policy_mismatch'
        IKE_V1_ID_LOCAL_REMOTE_CIDR_MISMATCH = 'ike_v1_id_local_remote_cidr_mismatch'
        IKE_V2_LOCAL_REMOTE_CIDR_MISMATCH = 'ike_v2_local_remote_cidr_mismatch'
        INTERNAL_ERROR = 'internal_error'
        IPSEC_POLICY_MISMATCH = 'ipsec_policy_mismatch'
        PEER_NOT_RESPONDING = 'peer_not_responding'



class VPNGatewayConnectionTunnelStatusReason:
    """
    VPNGatewayConnectionTunnelStatusReason.

    :attr str code: A snake case string succinctly identifying the status reason.
    :attr str message: An explanation of the reason for this VPN gateway connection
          tunnel's status.
    :attr str more_info: (optional) Link to documentation about this status reason.
    """

    def __init__(
        self,
        code: str,
        message: str,
        *,
        more_info: str = None,
    ) -> None:
        """
        Initialize a VPNGatewayConnectionTunnelStatusReason object.

        :param str code: A snake case string succinctly identifying the status
               reason.
        :param str message: An explanation of the reason for this VPN gateway
               connection tunnel's status.
        :param str more_info: (optional) Link to documentation about this status
               reason.
        """
        self.code = code
        self.message = message
        self.more_info = more_info

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPNGatewayConnectionTunnelStatusReason':
        """Initialize a VPNGatewayConnectionTunnelStatusReason object from a json dictionary."""
        args = {}
        if 'code' in _dict:
            args['code'] = _dict.get('code')
        else:
            raise ValueError('Required property \'code\' not present in VPNGatewayConnectionTunnelStatusReason JSON')
        if 'message' in _dict:
            args['message'] = _dict.get('message')
        else:
            raise ValueError('Required property \'message\' not present in VPNGatewayConnectionTunnelStatusReason JSON')
        if 'more_info' in _dict:
            args['more_info'] = _dict.get('more_info')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPNGatewayConnectionTunnelStatusReason object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'code') and self.code is not None:
            _dict['code'] = self.code
        if hasattr(self, 'message') and self.message is not None:
            _dict['message'] = self.message
        if hasattr(self, 'more_info') and self.more_info is not None:
            _dict['more_info'] = self.more_info
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VPNGatewayConnectionTunnelStatusReason object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPNGatewayConnectionTunnelStatusReason') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPNGatewayConnectionTunnelStatusReason') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class CodeEnum(str, Enum):
        """
        A snake case string succinctly identifying the status reason.
        """

        CANNOT_AUTHENTICATE_CONNECTION = 'cannot_authenticate_connection'
        IKE_POLICY_MISMATCH = 'ike_policy_mismatch'
        IKE_V1_ID_LOCAL_REMOTE_CIDR_MISMATCH = 'ike_v1_id_local_remote_cidr_mismatch'
        IKE_V2_LOCAL_REMOTE_CIDR_MISMATCH = 'ike_v2_local_remote_cidr_mismatch'
        INTERNAL_ERROR = 'internal_error'
        IPSEC_POLICY_MISMATCH = 'ipsec_policy_mismatch'
        PEER_NOT_RESPONDING = 'peer_not_responding'



class VPNGatewayHealthReason:
    """
    VPNGatewayHealthReason.

    :attr str code: A snake case string succinctly identifying the reason for this
          health state.
    :attr str message: An explanation of the reason for this health state.
    :attr str more_info: (optional) Link to documentation about the reason for this
          health state.
    """

    def __init__(
        self,
        code: str,
        message: str,
        *,
        more_info: str = None,
    ) -> None:
        """
        Initialize a VPNGatewayHealthReason object.

        :param str code: A snake case string succinctly identifying the reason for
               this health state.
        :param str message: An explanation of the reason for this health state.
        :param str more_info: (optional) Link to documentation about the reason for
               this health state.
        """
        self.code = code
        self.message = message
        self.more_info = more_info

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPNGatewayHealthReason':
        """Initialize a VPNGatewayHealthReason object from a json dictionary."""
        args = {}
        if 'code' in _dict:
            args['code'] = _dict.get('code')
        else:
            raise ValueError('Required property \'code\' not present in VPNGatewayHealthReason JSON')
        if 'message' in _dict:
            args['message'] = _dict.get('message')
        else:
            raise ValueError('Required property \'message\' not present in VPNGatewayHealthReason JSON')
        if 'more_info' in _dict:
            args['more_info'] = _dict.get('more_info')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPNGatewayHealthReason object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'code') and self.code is not None:
            _dict['code'] = self.code
        if hasattr(self, 'message') and self.message is not None:
            _dict['message'] = self.message
        if hasattr(self, 'more_info') and self.more_info is not None:
            _dict['more_info'] = self.more_info
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VPNGatewayHealthReason object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPNGatewayHealthReason') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPNGatewayHealthReason') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class CodeEnum(str, Enum):
        """
        A snake case string succinctly identifying the reason for this health state.
        """

        CANNOT_CREATE_VPC_ROUTE = 'cannot_create_vpc_route'
        CANNOT_RESERVE_IP_ADDRESS = 'cannot_reserve_ip_address'
        INTERNAL_ERROR = 'internal_error'



class VPNGatewayLifecycleReason:
    """
    VPNGatewayLifecycleReason.

    :attr str code: A snake case string succinctly identifying the reason for this
          lifecycle state.
    :attr str message: An explanation of the reason for this lifecycle state.
    :attr str more_info: (optional) Link to documentation about the reason for this
          lifecycle state.
    """

    def __init__(
        self,
        code: str,
        message: str,
        *,
        more_info: str = None,
    ) -> None:
        """
        Initialize a VPNGatewayLifecycleReason object.

        :param str code: A snake case string succinctly identifying the reason for
               this lifecycle state.
        :param str message: An explanation of the reason for this lifecycle state.
        :param str more_info: (optional) Link to documentation about the reason for
               this lifecycle state.
        """
        self.code = code
        self.message = message
        self.more_info = more_info

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPNGatewayLifecycleReason':
        """Initialize a VPNGatewayLifecycleReason object from a json dictionary."""
        args = {}
        if 'code' in _dict:
            args['code'] = _dict.get('code')
        else:
            raise ValueError('Required property \'code\' not present in VPNGatewayLifecycleReason JSON')
        if 'message' in _dict:
            args['message'] = _dict.get('message')
        else:
            raise ValueError('Required property \'message\' not present in VPNGatewayLifecycleReason JSON')
        if 'more_info' in _dict:
            args['more_info'] = _dict.get('more_info')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPNGatewayLifecycleReason object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'code') and self.code is not None:
            _dict['code'] = self.code
        if hasattr(self, 'message') and self.message is not None:
            _dict['message'] = self.message
        if hasattr(self, 'more_info') and self.more_info is not None:
            _dict['more_info'] = self.more_info
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VPNGatewayLifecycleReason object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPNGatewayLifecycleReason') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPNGatewayLifecycleReason') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class CodeEnum(str, Enum):
        """
        A snake case string succinctly identifying the reason for this lifecycle state.
        """

        RESOURCE_SUSPENDED_BY_PROVIDER = 'resource_suspended_by_provider'



class VPNGatewayMember:
    """
    VPNGatewayMember.

    :attr List[VPNGatewayMemberHealthReason] health_reasons: The reasons for the
          current VPN gateway member health_state (if any):
          - `cannot_reserve_ip_address`: IP address exhaustion (release addresses on the
          VPN's
            subnet)
          - `internal_error`: Internal error (contact IBM support)
          The enumerated reason code values for this property will expand in the future.
          When processing this property, check for and log unknown values. Optionally halt
          processing and surface the error, or bypass the resource on which the unexpected
          reason code was encountered.
    :attr str health_state: The health of this resource.
          - `ok`: No abnormal behavior detected
          - `degraded`: Experiencing compromised performance, capacity, or connectivity
          - `faulted`: Completely unreachable, inoperative, or otherwise entirely
          incapacitated
          - `inapplicable`: The health state does not apply because of the current
          lifecycle state. A resource with a lifecycle state of `failed` or `deleting`
          will have a health state of `inapplicable`. A `pending` resource may also have
          this state.
    :attr List[VPNGatewayMemberLifecycleReason] lifecycle_reasons: The reasons for
          the current VPN gateway member lifecycle_state (if any):
          - `resource_suspended_by_provider`: The resource has been suspended (contact IBM
            support)
          The enumerated reason code values for this property will expand in the future.
          When processing this property, check for and log unknown values. Optionally halt
          processing and surface the error, or bypass the resource on which the unexpected
          reason code was encountered.
    :attr str lifecycle_state: The lifecycle state of the VPN gateway member.
    :attr ReservedIPReference private_ip: The reserved IP address assigned to the
          VPN gateway member.
          This property will be present only when the VPN gateway status is `available`.
    :attr IP public_ip: The public IP address assigned to the VPN gateway member.
    :attr str role: The high availability role assigned to the VPN gateway member.
    """

    def __init__(
        self,
        health_reasons: List['VPNGatewayMemberHealthReason'],
        health_state: str,
        lifecycle_reasons: List['VPNGatewayMemberLifecycleReason'],
        lifecycle_state: str,
        private_ip: 'ReservedIPReference',
        public_ip: 'IP',
        role: str,
    ) -> None:
        """
        Initialize a VPNGatewayMember object.

        :param List[VPNGatewayMemberHealthReason] health_reasons: The reasons for
               the current VPN gateway member health_state (if any):
               - `cannot_reserve_ip_address`: IP address exhaustion (release addresses on
               the VPN's
                 subnet)
               - `internal_error`: Internal error (contact IBM support)
               The enumerated reason code values for this property will expand in the
               future. When processing this property, check for and log unknown values.
               Optionally halt processing and surface the error, or bypass the resource on
               which the unexpected reason code was encountered.
        :param str health_state: The health of this resource.
               - `ok`: No abnormal behavior detected
               - `degraded`: Experiencing compromised performance, capacity, or
               connectivity
               - `faulted`: Completely unreachable, inoperative, or otherwise entirely
               incapacitated
               - `inapplicable`: The health state does not apply because of the current
               lifecycle state. A resource with a lifecycle state of `failed` or
               `deleting` will have a health state of `inapplicable`. A `pending` resource
               may also have this state.
        :param List[VPNGatewayMemberLifecycleReason] lifecycle_reasons: The reasons
               for the current VPN gateway member lifecycle_state (if any):
               - `resource_suspended_by_provider`: The resource has been suspended
               (contact IBM
                 support)
               The enumerated reason code values for this property will expand in the
               future. When processing this property, check for and log unknown values.
               Optionally halt processing and surface the error, or bypass the resource on
               which the unexpected reason code was encountered.
        :param str lifecycle_state: The lifecycle state of the VPN gateway member.
        :param ReservedIPReference private_ip: The reserved IP address assigned to
               the VPN gateway member.
               This property will be present only when the VPN gateway status is
               `available`.
        :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.
        """
        self.health_reasons = health_reasons
        self.health_state = health_state
        self.lifecycle_reasons = lifecycle_reasons
        self.lifecycle_state = lifecycle_state
        self.private_ip = private_ip
        self.public_ip = public_ip
        self.role = role

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPNGatewayMember':
        """Initialize a VPNGatewayMember object from a json dictionary."""
        args = {}
        if 'health_reasons' in _dict:
            args['health_reasons'] = [VPNGatewayMemberHealthReason.from_dict(v) for v in _dict.get('health_reasons')]
        else:
            raise ValueError('Required property \'health_reasons\' not present in VPNGatewayMember JSON')
        if 'health_state' in _dict:
            args['health_state'] = _dict.get('health_state')
        else:
            raise ValueError('Required property \'health_state\' not present in VPNGatewayMember JSON')
        if 'lifecycle_reasons' in _dict:
            args['lifecycle_reasons'] = [VPNGatewayMemberLifecycleReason.from_dict(v) for v in _dict.get('lifecycle_reasons')]
        else:
            raise ValueError('Required property \'lifecycle_reasons\' not present in VPNGatewayMember JSON')
        if 'lifecycle_state' in _dict:
            args['lifecycle_state'] = _dict.get('lifecycle_state')
        else:
            raise ValueError('Required property \'lifecycle_state\' not present in VPNGatewayMember JSON')
        if 'private_ip' in _dict:
            args['private_ip'] = ReservedIPReference.from_dict(_dict.get('private_ip'))
        else:
            raise ValueError('Required property \'private_ip\' not present in VPNGatewayMember JSON')
        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')
        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, 'health_reasons') and self.health_reasons is not None:
            health_reasons_list = []
            for v in self.health_reasons:
                if isinstance(v, dict):
                    health_reasons_list.append(v)
                else:
                    health_reasons_list.append(v.to_dict())
            _dict['health_reasons'] = health_reasons_list
        if hasattr(self, 'health_state') and self.health_state is not None:
            _dict['health_state'] = self.health_state
        if hasattr(self, 'lifecycle_reasons') and self.lifecycle_reasons is not None:
            lifecycle_reasons_list = []
            for v in self.lifecycle_reasons:
                if isinstance(v, dict):
                    lifecycle_reasons_list.append(v)
                else:
                    lifecycle_reasons_list.append(v.to_dict())
            _dict['lifecycle_reasons'] = lifecycle_reasons_list
        if hasattr(self, 'lifecycle_state') and self.lifecycle_state is not None:
            _dict['lifecycle_state'] = self.lifecycle_state
        if hasattr(self, 'private_ip') and self.private_ip is not None:
            if isinstance(self.private_ip, dict):
                _dict['private_ip'] = self.private_ip
            else:
                _dict['private_ip'] = self.private_ip.to_dict()
        if hasattr(self, 'public_ip') and self.public_ip is not None:
            if isinstance(self.public_ip, dict):
                _dict['public_ip'] = self.public_ip
            else:
                _dict['public_ip'] = self.public_ip.to_dict()
        if hasattr(self, 'role') and self.role is not None:
            _dict['role'] = self.role
        return _dict

    def _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 HealthStateEnum(str, Enum):
        """
        The health of this resource.
        - `ok`: No abnormal behavior detected
        - `degraded`: Experiencing compromised performance, capacity, or connectivity
        - `faulted`: Completely unreachable, inoperative, or otherwise entirely
        incapacitated
        - `inapplicable`: The health state does not apply because of the current lifecycle
        state. A resource with a lifecycle state of `failed` or `deleting` will have a
        health state of `inapplicable`. A `pending` resource may also have this state.
        """

        DEGRADED = 'degraded'
        FAULTED = 'faulted'
        INAPPLICABLE = 'inapplicable'
        OK = 'ok'


    class LifecycleStateEnum(str, Enum):
        """
        The lifecycle state of the VPN gateway member.
        """

        DELETING = 'deleting'
        FAILED = 'failed'
        PENDING = 'pending'
        STABLE = 'stable'
        SUSPENDED = 'suspended'
        UPDATING = 'updating'
        WAITING = 'waiting'


    class RoleEnum(str, Enum):
        """
        The high availability role assigned to the VPN gateway member.
        """

        ACTIVE = 'active'
        STANDBY = 'standby'



class VPNGatewayMemberHealthReason:
    """
    VPNGatewayMemberHealthReason.

    :attr str code: A snake case string succinctly identifying the reason for this
          health state.
    :attr str message: An explanation of the reason for this health state.
    :attr str more_info: (optional) Link to documentation about the reason for this
          health state.
    """

    def __init__(
        self,
        code: str,
        message: str,
        *,
        more_info: str = None,
    ) -> None:
        """
        Initialize a VPNGatewayMemberHealthReason object.

        :param str code: A snake case string succinctly identifying the reason for
               this health state.
        :param str message: An explanation of the reason for this health state.
        :param str more_info: (optional) Link to documentation about the reason for
               this health state.
        """
        self.code = code
        self.message = message
        self.more_info = more_info

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPNGatewayMemberHealthReason':
        """Initialize a VPNGatewayMemberHealthReason object from a json dictionary."""
        args = {}
        if 'code' in _dict:
            args['code'] = _dict.get('code')
        else:
            raise ValueError('Required property \'code\' not present in VPNGatewayMemberHealthReason JSON')
        if 'message' in _dict:
            args['message'] = _dict.get('message')
        else:
            raise ValueError('Required property \'message\' not present in VPNGatewayMemberHealthReason JSON')
        if 'more_info' in _dict:
            args['more_info'] = _dict.get('more_info')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPNGatewayMemberHealthReason object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'code') and self.code is not None:
            _dict['code'] = self.code
        if hasattr(self, 'message') and self.message is not None:
            _dict['message'] = self.message
        if hasattr(self, 'more_info') and self.more_info is not None:
            _dict['more_info'] = self.more_info
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VPNGatewayMemberHealthReason object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPNGatewayMemberHealthReason') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPNGatewayMemberHealthReason') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class CodeEnum(str, Enum):
        """
        A snake case string succinctly identifying the reason for this health state.
        """

        CANNOT_RESERVE_IP_ADDRESS = 'cannot_reserve_ip_address'
        INTERNAL_ERROR = 'internal_error'



class VPNGatewayMemberLifecycleReason:
    """
    VPNGatewayMemberLifecycleReason.

    :attr str code: A snake case string succinctly identifying the reason for this
          lifecycle state.
    :attr str message: An explanation of the reason for this lifecycle state.
    :attr str more_info: (optional) Link to documentation about the reason for this
          lifecycle state.
    """

    def __init__(
        self,
        code: str,
        message: str,
        *,
        more_info: str = None,
    ) -> None:
        """
        Initialize a VPNGatewayMemberLifecycleReason object.

        :param str code: A snake case string succinctly identifying the reason for
               this lifecycle state.
        :param str message: An explanation of the reason for this lifecycle state.
        :param str more_info: (optional) Link to documentation about the reason for
               this lifecycle state.
        """
        self.code = code
        self.message = message
        self.more_info = more_info

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPNGatewayMemberLifecycleReason':
        """Initialize a VPNGatewayMemberLifecycleReason object from a json dictionary."""
        args = {}
        if 'code' in _dict:
            args['code'] = _dict.get('code')
        else:
            raise ValueError('Required property \'code\' not present in VPNGatewayMemberLifecycleReason JSON')
        if 'message' in _dict:
            args['message'] = _dict.get('message')
        else:
            raise ValueError('Required property \'message\' not present in VPNGatewayMemberLifecycleReason JSON')
        if 'more_info' in _dict:
            args['more_info'] = _dict.get('more_info')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPNGatewayMemberLifecycleReason object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'code') and self.code is not None:
            _dict['code'] = self.code
        if hasattr(self, 'message') and self.message is not None:
            _dict['message'] = self.message
        if hasattr(self, 'more_info') and self.more_info is not None:
            _dict['more_info'] = self.more_info
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VPNGatewayMemberLifecycleReason object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPNGatewayMemberLifecycleReason') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPNGatewayMemberLifecycleReason') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class CodeEnum(str, Enum):
        """
        A snake case string succinctly identifying the reason for this lifecycle state.
        """

        RESOURCE_SUSPENDED_BY_PROVIDER = 'resource_suspended_by_provider'



class VPNGatewayPatch:
    """
    VPNGatewayPatch.

    :attr str name: (optional) The name for this VPN gateway. The name must not be
          used by another VPN gateway in the VPC.
    """

    def __init__(
        self,
        *,
        name: str = None,
    ) -> None:
        """
        Initialize a VPNGatewayPatch object.

        :param str name: (optional) The name for this VPN gateway. The name must
               not be used by another VPN gateway in the VPC.
        """
        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 name for this VPN gateway. The name must not be
          used by another VPN gateway in the VPC. 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) will be
          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 name for this VPN gateway. The name must
               not be used by another VPN gateway in the 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) will be
               used.
        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['VPNGatewayPrototypeVPNGatewayRouteModePrototype', 'VPNGatewayPrototypeVPNGatewayPolicyModePrototype'])
        )
        raise Exception(msg)


class VPNGatewayReferenceDeleted:
    """
    If present, this property indicates the referenced resource has been deleted, and
    provides some supplementary information.

    :attr str more_info: Link to documentation about deleted resources.
    """

    def __init__(
        self,
        more_info: str,
    ) -> None:
        """
        Initialize a VPNGatewayReferenceDeleted object.

        :param str more_info: Link to documentation about deleted resources.
        """
        self.more_info = more_info

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPNGatewayReferenceDeleted':
        """Initialize a VPNGatewayReferenceDeleted object from a json dictionary."""
        args = {}
        if 'more_info' in _dict:
            args['more_info'] = _dict.get('more_info')
        else:
            raise ValueError('Required property \'more_info\' not present in VPNGatewayReferenceDeleted JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPNGatewayReferenceDeleted object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'more_info') and self.more_info is not None:
            _dict['more_info'] = self.more_info
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VPNGatewayReferenceDeleted object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPNGatewayReferenceDeleted') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPNGatewayReferenceDeleted') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VPNServer:
    """
    VPNServer.

    :attr CertificateInstanceReference certificate: The certificate instance for
          this VPN server.
    :attr List[VPNServerAuthentication] client_authentication: The methods used to
          authenticate VPN clients to this VPN server. VPN clients must authenticate
          against all specified methods.
    :attr bool client_auto_delete: Indicates whether disconnected VPN clients will
          be automatically deleted after
          `client_auto_delete_timeout` hours have passed. At present, this is always
          `true`, but may be modifiable in the future.
    :attr int client_auto_delete_timeout: If `client_auto_delete` is `true`, the
          hours after which disconnected VPN clients will be automatically deleted. If the
          value is `0`, disconnected VPN clients will be deleted immediately. This value
          may be modifiable in the future.
    :attr List[IP] client_dns_server_ips: The DNS server addresses that will be
          provided to VPN clients that are connected to this VPN server.
    :attr int client_idle_timeout: The seconds a VPN client can be idle before this
          VPN server will disconnect it.  If `0`, the server will not disconnect idle
          clients.
    :attr str client_ip_pool: The VPN client IPv4 address pool, expressed in CIDR
          format.
    :attr datetime created_at: The date and time that the VPN server was created.
    :attr str crn: The CRN for this VPN server.
    :attr bool enable_split_tunneling: Indicates whether the split tunneling is
          enabled on this VPN server.
    :attr List[VPNServerHealthReason] health_reasons: The reasons for the current
          VPN server health_state (if any):
          - `cannot_access_client_certificate`: VPN server's client certificate is
          inaccessible
            (verify certificate exists and that IAM policies grant `VPN server for VPC`
          access to
            `Secrets Manager`)
          - `cannot_access_server_certificate`: VPN server's server certificate is
          inaccessible
            (verify certificate exists and that IAM policies grant `VPN server for VPC`
          access to
            `Secrets Manager`)
          - `cannot_create_vpc_route`: VPN cannot create route (check for conflict)
          - `cannot_reserve_ip_address`: IP address exhaustion (release addresses on the
          VPN's
            subnet)
          - `internal_error`: Internal error (contact IBM support)
          The enumerated reason code values for this property will expand in the future.
          When processing this property, check for and log unknown values. Optionally halt
          processing and surface the error, or bypass the resource on which the unexpected
          reason code was encountered.
    :attr str health_state: The health of this resource.
          - `ok`: No abnormal behavior detected
          - `degraded`: Experiencing compromised performance, capacity, or connectivity
          - `faulted`: Completely unreachable, inoperative, or otherwise entirely
          incapacitated
          - `inapplicable`: The health state does not apply because of the current
          lifecycle state. A resource with a lifecycle state of `failed` or `deleting`
          will have a health state of `inapplicable`. A `pending` resource may also have
          this state.
    :attr str hostname: Fully qualified domain name assigned to this VPN server.
    :attr str href: The URL for this VPN server.
    :attr str id: The unique identifier for this VPN server.
    :attr List[VPNServerLifecycleReason] lifecycle_reasons: The reasons for the
          current VPN server lifecycle_state (if any):
          - `resource_suspended_by_provider`: The resource has been suspended (contact IBM
            support)
          The enumerated reason code values for this property will expand in the future.
          When processing this property, check for and log unknown values. Optionally halt
          processing and surface the error, or bypass the resource on which the unexpected
          reason code was encountered.
    :attr str lifecycle_state: The lifecycle state of the VPN server.
    :attr str name: The name for this VPN server. The name is unique across all VPN
          servers in the VPC.
    :attr int port: The port number used by this VPN server.
    :attr List[ReservedIPReference] private_ips: The reserved IPs bound to this VPN
          server.
    :attr str protocol: The transport protocol used by this VPN server.
    :attr ResourceGroupReference resource_group: The resource group for this VPN
          server.
    :attr str resource_type: The resource type.
    :attr List[SecurityGroupReference] security_groups: The security groups
          targeting this VPN server.
    :attr List[SubnetReference] subnets: The subnets this VPN server is provisioned
          in.
    :attr VPCReference vpc: The VPC this VPN server resides in.
    """

    def __init__(
        self,
        certificate: 'CertificateInstanceReference',
        client_authentication: List['VPNServerAuthentication'],
        client_auto_delete: bool,
        client_auto_delete_timeout: int,
        client_dns_server_ips: List['IP'],
        client_idle_timeout: int,
        client_ip_pool: str,
        created_at: datetime,
        crn: str,
        enable_split_tunneling: bool,
        health_reasons: List['VPNServerHealthReason'],
        health_state: str,
        hostname: str,
        href: str,
        id: str,
        lifecycle_reasons: List['VPNServerLifecycleReason'],
        lifecycle_state: str,
        name: str,
        port: int,
        private_ips: List['ReservedIPReference'],
        protocol: str,
        resource_group: 'ResourceGroupReference',
        resource_type: str,
        security_groups: List['SecurityGroupReference'],
        subnets: List['SubnetReference'],
        vpc: 'VPCReference',
    ) -> None:
        """
        Initialize a VPNServer object.

        :param CertificateInstanceReference certificate: The certificate instance
               for this VPN server.
        :param List[VPNServerAuthentication] client_authentication: The methods
               used to authenticate VPN clients to this VPN server. VPN clients must
               authenticate against all specified methods.
        :param bool client_auto_delete: Indicates whether disconnected VPN clients
               will be automatically deleted after
               `client_auto_delete_timeout` hours have passed. At present, this is always
               `true`, but may be modifiable in the future.
        :param int client_auto_delete_timeout: If `client_auto_delete` is `true`,
               the hours after which disconnected VPN clients will be automatically
               deleted. If the value is `0`, disconnected VPN clients will be deleted
               immediately. This value may be modifiable in the future.
        :param List[IP] client_dns_server_ips: The DNS server addresses that will
               be provided to VPN clients that are connected to this VPN server.
        :param int client_idle_timeout: The seconds a VPN client can be idle before
               this VPN server will disconnect it.  If `0`, the server will not disconnect
               idle clients.
        :param str client_ip_pool: The VPN client IPv4 address pool, expressed in
               CIDR format.
        :param datetime created_at: The date and time that the VPN server was
               created.
        :param str crn: The CRN for this VPN server.
        :param bool enable_split_tunneling: Indicates whether the split tunneling
               is enabled on this VPN server.
        :param List[VPNServerHealthReason] health_reasons: The reasons for the
               current VPN server health_state (if any):
               - `cannot_access_client_certificate`: VPN server's client certificate is
               inaccessible
                 (verify certificate exists and that IAM policies grant `VPN server for
               VPC` access to
                 `Secrets Manager`)
               - `cannot_access_server_certificate`: VPN server's server certificate is
               inaccessible
                 (verify certificate exists and that IAM policies grant `VPN server for
               VPC` access to
                 `Secrets Manager`)
               - `cannot_create_vpc_route`: VPN cannot create route (check for conflict)
               - `cannot_reserve_ip_address`: IP address exhaustion (release addresses on
               the VPN's
                 subnet)
               - `internal_error`: Internal error (contact IBM support)
               The enumerated reason code values for this property will expand in the
               future. When processing this property, check for and log unknown values.
               Optionally halt processing and surface the error, or bypass the resource on
               which the unexpected reason code was encountered.
        :param str health_state: The health of this resource.
               - `ok`: No abnormal behavior detected
               - `degraded`: Experiencing compromised performance, capacity, or
               connectivity
               - `faulted`: Completely unreachable, inoperative, or otherwise entirely
               incapacitated
               - `inapplicable`: The health state does not apply because of the current
               lifecycle state. A resource with a lifecycle state of `failed` or
               `deleting` will have a health state of `inapplicable`. A `pending` resource
               may also have this state.
        :param str hostname: Fully qualified domain name assigned to this VPN
               server.
        :param str href: The URL for this VPN server.
        :param str id: The unique identifier for this VPN server.
        :param List[VPNServerLifecycleReason] lifecycle_reasons: The reasons for
               the current VPN server lifecycle_state (if any):
               - `resource_suspended_by_provider`: The resource has been suspended
               (contact IBM
                 support)
               The enumerated reason code values for this property will expand in the
               future. When processing this property, check for and log unknown values.
               Optionally halt processing and surface the error, or bypass the resource on
               which the unexpected reason code was encountered.
        :param str lifecycle_state: The lifecycle state of the VPN server.
        :param str name: The name for this VPN server. The name is unique across
               all VPN servers in the VPC.
        :param int port: The port number used by this VPN server.
        :param List[ReservedIPReference] private_ips: The reserved IPs bound to
               this VPN server.
        :param str protocol: The transport protocol used by this VPN server.
        :param ResourceGroupReference resource_group: The resource group for this
               VPN server.
        :param str resource_type: The resource type.
        :param List[SecurityGroupReference] security_groups: The security groups
               targeting this VPN server.
        :param List[SubnetReference] subnets: The subnets this VPN server is
               provisioned in.
        :param VPCReference vpc: The VPC this VPN server resides in.
        """
        self.certificate = certificate
        self.client_authentication = client_authentication
        self.client_auto_delete = client_auto_delete
        self.client_auto_delete_timeout = client_auto_delete_timeout
        self.client_dns_server_ips = client_dns_server_ips
        self.client_idle_timeout = client_idle_timeout
        self.client_ip_pool = client_ip_pool
        self.created_at = created_at
        self.crn = crn
        self.enable_split_tunneling = enable_split_tunneling
        self.health_reasons = health_reasons
        self.health_state = health_state
        self.hostname = hostname
        self.href = href
        self.id = id
        self.lifecycle_reasons = lifecycle_reasons
        self.lifecycle_state = lifecycle_state
        self.name = name
        self.port = port
        self.private_ips = private_ips
        self.protocol = protocol
        self.resource_group = resource_group
        self.resource_type = resource_type
        self.security_groups = security_groups
        self.subnets = subnets
        self.vpc = vpc

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPNServer':
        """Initialize a VPNServer object from a json dictionary."""
        args = {}
        if 'certificate' in _dict:
            args['certificate'] = CertificateInstanceReference.from_dict(_dict.get('certificate'))
        else:
            raise ValueError('Required property \'certificate\' not present in VPNServer JSON')
        if 'client_authentication' in _dict:
            args['client_authentication'] = _dict.get('client_authentication')
        else:
            raise ValueError('Required property \'client_authentication\' not present in VPNServer JSON')
        if 'client_auto_delete' in _dict:
            args['client_auto_delete'] = _dict.get('client_auto_delete')
        else:
            raise ValueError('Required property \'client_auto_delete\' not present in VPNServer JSON')
        if 'client_auto_delete_timeout' in _dict:
            args['client_auto_delete_timeout'] = _dict.get('client_auto_delete_timeout')
        else:
            raise ValueError('Required property \'client_auto_delete_timeout\' not present in VPNServer JSON')
        if 'client_dns_server_ips' in _dict:
            args['client_dns_server_ips'] = [IP.from_dict(v) for v in _dict.get('client_dns_server_ips')]
        else:
            raise ValueError('Required property \'client_dns_server_ips\' not present in VPNServer JSON')
        if 'client_idle_timeout' in _dict:
            args['client_idle_timeout'] = _dict.get('client_idle_timeout')
        else:
            raise ValueError('Required property \'client_idle_timeout\' not present in VPNServer JSON')
        if 'client_ip_pool' in _dict:
            args['client_ip_pool'] = _dict.get('client_ip_pool')
        else:
            raise ValueError('Required property \'client_ip_pool\' not present in VPNServer 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 VPNServer JSON')
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError('Required property \'crn\' not present in VPNServer JSON')
        if 'enable_split_tunneling' in _dict:
            args['enable_split_tunneling'] = _dict.get('enable_split_tunneling')
        else:
            raise ValueError('Required property \'enable_split_tunneling\' not present in VPNServer JSON')
        if 'health_reasons' in _dict:
            args['health_reasons'] = [VPNServerHealthReason.from_dict(v) for v in _dict.get('health_reasons')]
        else:
            raise ValueError('Required property \'health_reasons\' not present in VPNServer JSON')
        if 'health_state' in _dict:
            args['health_state'] = _dict.get('health_state')
        else:
            raise ValueError('Required property \'health_state\' not present in VPNServer JSON')
        if 'hostname' in _dict:
            args['hostname'] = _dict.get('hostname')
        else:
            raise ValueError('Required property \'hostname\' not present in VPNServer JSON')
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in VPNServer JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in VPNServer JSON')
        if 'lifecycle_reasons' in _dict:
            args['lifecycle_reasons'] = [VPNServerLifecycleReason.from_dict(v) for v in _dict.get('lifecycle_reasons')]
        else:
            raise ValueError('Required property \'lifecycle_reasons\' not present in VPNServer JSON')
        if 'lifecycle_state' in _dict:
            args['lifecycle_state'] = _dict.get('lifecycle_state')
        else:
            raise ValueError('Required property \'lifecycle_state\' not present in VPNServer JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in VPNServer JSON')
        if 'port' in _dict:
            args['port'] = _dict.get('port')
        else:
            raise ValueError('Required property \'port\' not present in VPNServer JSON')
        if 'private_ips' in _dict:
            args['private_ips'] = [ReservedIPReference.from_dict(v) for v in _dict.get('private_ips')]
        else:
            raise ValueError('Required property \'private_ips\' not present in VPNServer JSON')
        if 'protocol' in _dict:
            args['protocol'] = _dict.get('protocol')
        else:
            raise ValueError('Required property \'protocol\' not present in VPNServer 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 VPNServer JSON')
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError('Required property \'resource_type\' not present in VPNServer JSON')
        if 'security_groups' in _dict:
            args['security_groups'] = [SecurityGroupReference.from_dict(v) for v in _dict.get('security_groups')]
        else:
            raise ValueError('Required property \'security_groups\' not present in VPNServer JSON')
        if 'subnets' in _dict:
            args['subnets'] = [SubnetReference.from_dict(v) for v in _dict.get('subnets')]
        else:
            raise ValueError('Required property \'subnets\' not present in VPNServer JSON')
        if 'vpc' in _dict:
            args['vpc'] = VPCReference.from_dict(_dict.get('vpc'))
        else:
            raise ValueError('Required property \'vpc\' not present in VPNServer JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPNServer object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'certificate') and self.certificate is not None:
            if isinstance(self.certificate, dict):
                _dict['certificate'] = self.certificate
            else:
                _dict['certificate'] = self.certificate.to_dict()
        if hasattr(self, 'client_authentication') and self.client_authentication is not None:
            client_authentication_list = []
            for v in self.client_authentication:
                if isinstance(v, dict):
                    client_authentication_list.append(v)
                else:
                    client_authentication_list.append(v.to_dict())
            _dict['client_authentication'] = client_authentication_list
        if hasattr(self, 'client_auto_delete') and self.client_auto_delete is not None:
            _dict['client_auto_delete'] = self.client_auto_delete
        if hasattr(self, 'client_auto_delete_timeout') and self.client_auto_delete_timeout is not None:
            _dict['client_auto_delete_timeout'] = self.client_auto_delete_timeout
        if hasattr(self, 'client_dns_server_ips') and self.client_dns_server_ips is not None:
            client_dns_server_ips_list = []
            for v in self.client_dns_server_ips:
                if isinstance(v, dict):
                    client_dns_server_ips_list.append(v)
                else:
                    client_dns_server_ips_list.append(v.to_dict())
            _dict['client_dns_server_ips'] = client_dns_server_ips_list
        if hasattr(self, 'client_idle_timeout') and self.client_idle_timeout is not None:
            _dict['client_idle_timeout'] = self.client_idle_timeout
        if hasattr(self, 'client_ip_pool') and self.client_ip_pool is not None:
            _dict['client_ip_pool'] = self.client_ip_pool
        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, 'enable_split_tunneling') and self.enable_split_tunneling is not None:
            _dict['enable_split_tunneling'] = self.enable_split_tunneling
        if hasattr(self, 'health_reasons') and self.health_reasons is not None:
            health_reasons_list = []
            for v in self.health_reasons:
                if isinstance(v, dict):
                    health_reasons_list.append(v)
                else:
                    health_reasons_list.append(v.to_dict())
            _dict['health_reasons'] = health_reasons_list
        if hasattr(self, 'health_state') and self.health_state is not None:
            _dict['health_state'] = self.health_state
        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, 'lifecycle_reasons') and self.lifecycle_reasons is not None:
            lifecycle_reasons_list = []
            for v in self.lifecycle_reasons:
                if isinstance(v, dict):
                    lifecycle_reasons_list.append(v)
                else:
                    lifecycle_reasons_list.append(v.to_dict())
            _dict['lifecycle_reasons'] = lifecycle_reasons_list
        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, 'port') and self.port is not None:
            _dict['port'] = self.port
        if hasattr(self, 'private_ips') and self.private_ips is not None:
            private_ips_list = []
            for v in self.private_ips:
                if isinstance(v, dict):
                    private_ips_list.append(v)
                else:
                    private_ips_list.append(v.to_dict())
            _dict['private_ips'] = private_ips_list
        if hasattr(self, 'protocol') and self.protocol is not None:
            _dict['protocol'] = self.protocol
        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, '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:
            security_groups_list = []
            for v in self.security_groups:
                if isinstance(v, dict):
                    security_groups_list.append(v)
                else:
                    security_groups_list.append(v.to_dict())
            _dict['security_groups'] = security_groups_list
        if hasattr(self, 'subnets') and self.subnets is not None:
            subnets_list = []
            for v in self.subnets:
                if isinstance(v, dict):
                    subnets_list.append(v)
                else:
                    subnets_list.append(v.to_dict())
            _dict['subnets'] = subnets_list
        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()
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VPNServer object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPNServer') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPNServer') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class HealthStateEnum(str, Enum):
        """
        The health of this resource.
        - `ok`: No abnormal behavior detected
        - `degraded`: Experiencing compromised performance, capacity, or connectivity
        - `faulted`: Completely unreachable, inoperative, or otherwise entirely
        incapacitated
        - `inapplicable`: The health state does not apply because of the current lifecycle
        state. A resource with a lifecycle state of `failed` or `deleting` will have a
        health state of `inapplicable`. A `pending` resource may also have this state.
        """

        DEGRADED = 'degraded'
        FAULTED = 'faulted'
        INAPPLICABLE = 'inapplicable'
        OK = 'ok'


    class LifecycleStateEnum(str, Enum):
        """
        The lifecycle state of the VPN server.
        """

        DELETING = 'deleting'
        FAILED = 'failed'
        PENDING = 'pending'
        STABLE = 'stable'
        SUSPENDED = 'suspended'
        UPDATING = 'updating'
        WAITING = 'waiting'


    class ProtocolEnum(str, Enum):
        """
        The transport protocol used by this VPN server.
        """

        TCP = 'tcp'
        UDP = 'udp'


    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        VPN_SERVER = 'vpn_server'



class VPNServerAuthentication:
    """
    An authentication method for this VPN server.

    :attr str method: The type of authentication.
    """

    def __init__(
        self,
        method: str,
    ) -> None:
        """
        Initialize a VPNServerAuthentication object.

        :param str method: The type of authentication.
        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['VPNServerAuthenticationByUsername', 'VPNServerAuthenticationByCertificate'])
        )
        raise Exception(msg)

    class MethodEnum(str, Enum):
        """
        The type of authentication.
        """

        CERTIFICATE = 'certificate'
        USERNAME = 'username'



class VPNServerAuthenticationByUsernameIdProvider:
    """
    The type of identity provider to be used by VPN client.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a VPNServerAuthenticationByUsernameIdProvider object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['VPNServerAuthenticationByUsernameIdProviderByIAM'])
        )
        raise Exception(msg)


class VPNServerAuthenticationPrototype:
    """
    An authentication method for this VPN server.

    :attr str method: The type of authentication.
    """

    def __init__(
        self,
        method: str,
    ) -> None:
        """
        Initialize a VPNServerAuthenticationPrototype object.

        :param str method: The type of authentication.
        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['VPNServerAuthenticationPrototypeVPNServerAuthenticationByUsernamePrototype', 'VPNServerAuthenticationPrototypeVPNServerAuthenticationByCertificatePrototype'])
        )
        raise Exception(msg)

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPNServerAuthenticationPrototype':
        """Initialize a VPNServerAuthenticationPrototype 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 'VPNServerAuthenticationPrototype'. The discriminator value should map to a valid subclass: {1}".format(
            ", ".join(['VPNServerAuthenticationPrototypeVPNServerAuthenticationByUsernamePrototype', 'VPNServerAuthenticationPrototypeVPNServerAuthenticationByCertificatePrototype'])
        )
        raise Exception(msg)

    @classmethod
    def _from_dict(cls, _dict: Dict):
        """Initialize a VPNServerAuthenticationPrototype object from a json dictionary."""
        return cls.from_dict(_dict)

    @classmethod
    def _get_class_by_discriminator(cls, _dict: Dict) -> object:
        mapping = {}
        mapping['certificate'] = 'VPNServerAuthenticationPrototypeVPNServerAuthenticationByCertificatePrototype'
        mapping['username'] = 'VPNServerAuthenticationPrototypeVPNServerAuthenticationByUsernamePrototype'
        disc_value = _dict.get('method')
        if disc_value is None:
            raise ValueError('Discriminator property \'method\' not found in VPNServerAuthenticationPrototype 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 MethodEnum(str, Enum):
        """
        The type of authentication.
        """

        CERTIFICATE = 'certificate'
        USERNAME = 'username'



class VPNServerClient:
    """
    VPNServerClient.

    :attr IP client_ip: The IP address assigned to this VPN client from
          `client_ip_pool`.
    :attr str common_name: (optional) The common name of client certificate that the
          VPN client provided when connecting to the server.
          This property will be present only when the `certificate` client authentication
          method is enabled on the VPN server.
    :attr datetime created_at: The date and time that the VPN client was created.
    :attr datetime disconnected_at: (optional) The date and time that the VPN client
          was disconnected.
          This property will be present only when the client `status` is `disconnected`.
    :attr str href: The URL for this VPN client.
    :attr str id: The unique identifier for this VPN client.
    :attr IP remote_ip: The remote IP address of this VPN client.
    :attr int remote_port: The remote port of this VPN client.
    :attr str resource_type: The resource type.
    :attr str status: The status of the VPN client:
          - `connected`: the VPN client is `connected` to this VPN server.
          - `disconnected`: the VPN client is `disconnected` from this VPN server.
          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 VPN client on which the
          unexpected property value was encountered.
    :attr str username: (optional) The username that this VPN client provided when
          connecting to the VPN server.
          This property will be present only when the `username` client authentication
          method is enabled on the VPN server.
    """

    def __init__(
        self,
        client_ip: 'IP',
        created_at: datetime,
        href: str,
        id: str,
        remote_ip: 'IP',
        remote_port: int,
        resource_type: str,
        status: str,
        *,
        common_name: str = None,
        disconnected_at: datetime = None,
        username: str = None,
    ) -> None:
        """
        Initialize a VPNServerClient object.

        :param IP client_ip: The IP address assigned to this VPN client from
               `client_ip_pool`.
        :param datetime created_at: The date and time that the VPN client was
               created.
        :param str href: The URL for this VPN client.
        :param str id: The unique identifier for this VPN client.
        :param IP remote_ip: The remote IP address of this VPN client.
        :param int remote_port: The remote port of this VPN client.
        :param str resource_type: The resource type.
        :param str status: The status of the VPN client:
               - `connected`: the VPN client is `connected` to this VPN server.
               - `disconnected`: the VPN client is `disconnected` from this VPN server.
               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 VPN client
               on which the unexpected property value was encountered.
        :param str common_name: (optional) The common name of client certificate
               that the VPN client provided when connecting to the server.
               This property will be present only when the `certificate` client
               authentication method is enabled on the VPN server.
        :param datetime disconnected_at: (optional) The date and time that the VPN
               client was disconnected.
               This property will be present only when the client `status` is
               `disconnected`.
        :param str username: (optional) The username that this VPN client provided
               when connecting to the VPN server.
               This property will be present only when the `username` client
               authentication method is enabled on the VPN server.
        """
        self.client_ip = client_ip
        self.common_name = common_name
        self.created_at = created_at
        self.disconnected_at = disconnected_at
        self.href = href
        self.id = id
        self.remote_ip = remote_ip
        self.remote_port = remote_port
        self.resource_type = resource_type
        self.status = status
        self.username = username

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPNServerClient':
        """Initialize a VPNServerClient object from a json dictionary."""
        args = {}
        if 'client_ip' in _dict:
            args['client_ip'] = IP.from_dict(_dict.get('client_ip'))
        else:
            raise ValueError('Required property \'client_ip\' not present in VPNServerClient JSON')
        if 'common_name' in _dict:
            args['common_name'] = _dict.get('common_name')
        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 VPNServerClient JSON')
        if 'disconnected_at' in _dict:
            args['disconnected_at'] = string_to_datetime(_dict.get('disconnected_at'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in VPNServerClient JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in VPNServerClient JSON')
        if 'remote_ip' in _dict:
            args['remote_ip'] = IP.from_dict(_dict.get('remote_ip'))
        else:
            raise ValueError('Required property \'remote_ip\' not present in VPNServerClient JSON')
        if 'remote_port' in _dict:
            args['remote_port'] = _dict.get('remote_port')
        else:
            raise ValueError('Required property \'remote_port\' not present in VPNServerClient JSON')
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError('Required property \'resource_type\' not present in VPNServerClient JSON')
        if 'status' in _dict:
            args['status'] = _dict.get('status')
        else:
            raise ValueError('Required property \'status\' not present in VPNServerClient JSON')
        if 'username' in _dict:
            args['username'] = _dict.get('username')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPNServerClient object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'client_ip') and self.client_ip is not None:
            if isinstance(self.client_ip, dict):
                _dict['client_ip'] = self.client_ip
            else:
                _dict['client_ip'] = self.client_ip.to_dict()
        if hasattr(self, 'common_name') and self.common_name is not None:
            _dict['common_name'] = self.common_name
        if hasattr(self, 'created_at') and self.created_at is not None:
            _dict['created_at'] = datetime_to_string(self.created_at)
        if hasattr(self, 'disconnected_at') and self.disconnected_at is not None:
            _dict['disconnected_at'] = datetime_to_string(self.disconnected_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, 'remote_ip') and self.remote_ip is not None:
            if isinstance(self.remote_ip, dict):
                _dict['remote_ip'] = self.remote_ip
            else:
                _dict['remote_ip'] = self.remote_ip.to_dict()
        if hasattr(self, 'remote_port') and self.remote_port is not None:
            _dict['remote_port'] = self.remote_port
        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, 'username') and self.username is not None:
            _dict['username'] = self.username
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VPNServerClient object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPNServerClient') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPNServerClient') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        VPN_SERVER_CLIENT = 'vpn_server_client'


    class StatusEnum(str, Enum):
        """
        The status of the VPN client:
        - `connected`: the VPN client is `connected` to this VPN server.
        - `disconnected`: the VPN client is `disconnected` from this VPN server.
        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 VPN client on which the unexpected
        property value was encountered.
        """

        CONNECTED = 'connected'
        DISCONNECTED = 'disconnected'



class VPNServerClientCollection:
    """
    VPNServerClientCollection.

    :attr List[VPNServerClient] clients: Collection of VPN clients.
    :attr VPNServerClientCollectionFirst 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 VPNServerClientCollectionNext 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,
        clients: List['VPNServerClient'],
        first: 'VPNServerClientCollectionFirst',
        limit: int,
        total_count: int,
        *,
        next: 'VPNServerClientCollectionNext' = None,
    ) -> None:
        """
        Initialize a VPNServerClientCollection object.

        :param List[VPNServerClient] clients: Collection of VPN clients.
        :param VPNServerClientCollectionFirst 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 VPNServerClientCollectionNext next: (optional) A link to the next
               page of resources. This property is present for all pages
               except the last page.
        """
        self.clients = clients
        self.first = first
        self.limit = limit
        self.next = next
        self.total_count = total_count

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPNServerClientCollection':
        """Initialize a VPNServerClientCollection object from a json dictionary."""
        args = {}
        if 'clients' in _dict:
            args['clients'] = [VPNServerClient.from_dict(v) for v in _dict.get('clients')]
        else:
            raise ValueError('Required property \'clients\' not present in VPNServerClientCollection JSON')
        if 'first' in _dict:
            args['first'] = VPNServerClientCollectionFirst.from_dict(_dict.get('first'))
        else:
            raise ValueError('Required property \'first\' not present in VPNServerClientCollection JSON')
        if 'limit' in _dict:
            args['limit'] = _dict.get('limit')
        else:
            raise ValueError('Required property \'limit\' not present in VPNServerClientCollection JSON')
        if 'next' in _dict:
            args['next'] = VPNServerClientCollectionNext.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 VPNServerClientCollection JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPNServerClientCollection object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'clients') and self.clients is not None:
            clients_list = []
            for v in self.clients:
                if isinstance(v, dict):
                    clients_list.append(v)
                else:
                    clients_list.append(v.to_dict())
            _dict['clients'] = clients_list
        if hasattr(self, 'first') and self.first is not None:
            if isinstance(self.first, dict):
                _dict['first'] = self.first
            else:
                _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:
            if isinstance(self.next, dict):
                _dict['next'] = self.next
            else:
                _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 VPNServerClientCollection object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPNServerClientCollection') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPNServerClientCollection') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VPNServerClientCollectionFirst:
    """
    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 VPNServerClientCollectionFirst object.

        :param str href: The URL for a page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPNServerClientCollectionFirst':
        """Initialize a VPNServerClientCollectionFirst object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in VPNServerClientCollectionFirst JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPNServerClientCollectionFirst object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(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 VPNServerClientCollectionFirst object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPNServerClientCollectionFirst') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPNServerClientCollectionFirst') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VPNServerClientCollectionNext:
    """
    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 VPNServerClientCollectionNext object.

        :param str href: The URL for a page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPNServerClientCollectionNext':
        """Initialize a VPNServerClientCollectionNext object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in VPNServerClientCollectionNext JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPNServerClientCollectionNext object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(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 VPNServerClientCollectionNext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPNServerClientCollectionNext') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPNServerClientCollectionNext') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VPNServerCollection:
    """
    VPNServerCollection.

    :attr VPNServerCollectionFirst 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 VPNServerCollectionNext 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[VPNServer] vpn_servers: Collection of VPN servers.
    """

    def __init__(
        self,
        first: 'VPNServerCollectionFirst',
        limit: int,
        total_count: int,
        vpn_servers: List['VPNServer'],
        *,
        next: 'VPNServerCollectionNext' = None,
    ) -> None:
        """
        Initialize a VPNServerCollection object.

        :param VPNServerCollectionFirst 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[VPNServer] vpn_servers: Collection of VPN servers.
        :param VPNServerCollectionNext 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_servers = vpn_servers

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPNServerCollection':
        """Initialize a VPNServerCollection object from a json dictionary."""
        args = {}
        if 'first' in _dict:
            args['first'] = VPNServerCollectionFirst.from_dict(_dict.get('first'))
        else:
            raise ValueError('Required property \'first\' not present in VPNServerCollection JSON')
        if 'limit' in _dict:
            args['limit'] = _dict.get('limit')
        else:
            raise ValueError('Required property \'limit\' not present in VPNServerCollection JSON')
        if 'next' in _dict:
            args['next'] = VPNServerCollectionNext.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 VPNServerCollection JSON')
        if 'vpn_servers' in _dict:
            args['vpn_servers'] = [VPNServer.from_dict(v) for v in _dict.get('vpn_servers')]
        else:
            raise ValueError('Required property \'vpn_servers\' not present in VPNServerCollection JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPNServerCollection object from 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:
            if isinstance(self.first, dict):
                _dict['first'] = self.first
            else:
                _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:
            if isinstance(self.next, dict):
                _dict['next'] = self.next
            else:
                _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_servers') and self.vpn_servers is not None:
            vpn_servers_list = []
            for v in self.vpn_servers:
                if isinstance(v, dict):
                    vpn_servers_list.append(v)
                else:
                    vpn_servers_list.append(v.to_dict())
            _dict['vpn_servers'] = vpn_servers_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 VPNServerCollection object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPNServerCollection') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPNServerCollection') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VPNServerCollectionFirst:
    """
    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 VPNServerCollectionFirst object.

        :param str href: The URL for a page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPNServerCollectionFirst':
        """Initialize a VPNServerCollectionFirst object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in VPNServerCollectionFirst JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPNServerCollectionFirst object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(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 VPNServerCollectionFirst object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPNServerCollectionFirst') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPNServerCollectionFirst') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VPNServerCollectionNext:
    """
    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 VPNServerCollectionNext object.

        :param str href: The URL for a page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPNServerCollectionNext':
        """Initialize a VPNServerCollectionNext object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in VPNServerCollectionNext JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPNServerCollectionNext object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(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 VPNServerCollectionNext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPNServerCollectionNext') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPNServerCollectionNext') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VPNServerHealthReason:
    """
    VPNServerHealthReason.

    :attr str code: A snake case string succinctly identifying the reason for this
          health state.
    :attr str message: An explanation of the reason for this health state.
    :attr str more_info: (optional) Link to documentation about the reason for this
          health state.
    """

    def __init__(
        self,
        code: str,
        message: str,
        *,
        more_info: str = None,
    ) -> None:
        """
        Initialize a VPNServerHealthReason object.

        :param str code: A snake case string succinctly identifying the reason for
               this health state.
        :param str message: An explanation of the reason for this health state.
        :param str more_info: (optional) Link to documentation about the reason for
               this health state.
        """
        self.code = code
        self.message = message
        self.more_info = more_info

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPNServerHealthReason':
        """Initialize a VPNServerHealthReason object from a json dictionary."""
        args = {}
        if 'code' in _dict:
            args['code'] = _dict.get('code')
        else:
            raise ValueError('Required property \'code\' not present in VPNServerHealthReason JSON')
        if 'message' in _dict:
            args['message'] = _dict.get('message')
        else:
            raise ValueError('Required property \'message\' not present in VPNServerHealthReason JSON')
        if 'more_info' in _dict:
            args['more_info'] = _dict.get('more_info')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPNServerHealthReason object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'code') and self.code is not None:
            _dict['code'] = self.code
        if hasattr(self, 'message') and self.message is not None:
            _dict['message'] = self.message
        if hasattr(self, 'more_info') and self.more_info is not None:
            _dict['more_info'] = self.more_info
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VPNServerHealthReason object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPNServerHealthReason') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPNServerHealthReason') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class CodeEnum(str, Enum):
        """
        A snake case string succinctly identifying the reason for this health state.
        """

        CANNOT_ACCESS_CLIENT_CERTIFICATE = 'cannot_access_client_certificate'
        CANNOT_ACCESS_SERVER_CERTIFICATE = 'cannot_access_server_certificate'
        CANNOT_CREATE_VPC_ROUTE = 'cannot_create_vpc_route'
        CANNOT_RESERVE_IP_ADDRESS = 'cannot_reserve_ip_address'
        INTERNAL_ERROR = 'internal_error'



class VPNServerLifecycleReason:
    """
    VPNServerLifecycleReason.

    :attr str code: A snake case string succinctly identifying the reason for this
          lifecycle state.
    :attr str message: An explanation of the reason for this lifecycle state.
    :attr str more_info: (optional) Link to documentation about the reason for this
          lifecycle state.
    """

    def __init__(
        self,
        code: str,
        message: str,
        *,
        more_info: str = None,
    ) -> None:
        """
        Initialize a VPNServerLifecycleReason object.

        :param str code: A snake case string succinctly identifying the reason for
               this lifecycle state.
        :param str message: An explanation of the reason for this lifecycle state.
        :param str more_info: (optional) Link to documentation about the reason for
               this lifecycle state.
        """
        self.code = code
        self.message = message
        self.more_info = more_info

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPNServerLifecycleReason':
        """Initialize a VPNServerLifecycleReason object from a json dictionary."""
        args = {}
        if 'code' in _dict:
            args['code'] = _dict.get('code')
        else:
            raise ValueError('Required property \'code\' not present in VPNServerLifecycleReason JSON')
        if 'message' in _dict:
            args['message'] = _dict.get('message')
        else:
            raise ValueError('Required property \'message\' not present in VPNServerLifecycleReason JSON')
        if 'more_info' in _dict:
            args['more_info'] = _dict.get('more_info')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPNServerLifecycleReason object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'code') and self.code is not None:
            _dict['code'] = self.code
        if hasattr(self, 'message') and self.message is not None:
            _dict['message'] = self.message
        if hasattr(self, 'more_info') and self.more_info is not None:
            _dict['more_info'] = self.more_info
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VPNServerLifecycleReason object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPNServerLifecycleReason') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPNServerLifecycleReason') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class CodeEnum(str, Enum):
        """
        A snake case string succinctly identifying the reason for this lifecycle state.
        """

        RESOURCE_SUSPENDED_BY_PROVIDER = 'resource_suspended_by_provider'



class VPNServerPatch:
    """
    VPNServerPatch.

    :attr CertificateInstanceIdentity certificate: (optional) The certificate
          instance for this VPN server.
    :attr List[VPNServerAuthenticationPrototype] client_authentication: (optional)
          The authentication methods to use to authenticate VPN client on this VPN server
          (replacing any existing methods).
    :attr List[IP] client_dns_server_ips: (optional) The DNS server addresses that
          will be provided to VPN clients connected to this VPN server (replacing any
          existing addresses).
    :attr int client_idle_timeout: (optional) The seconds a VPN client can be idle
          before this VPN server will disconnect it.  If `0`, the server will not
          disconnect idle clients.
    :attr str client_ip_pool: (optional) The VPN client IPv4 address pool, 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 client IP address pool's CIDR must be between
          `/9` (8,388,608 addresses) and `/22` (1024 addresses). A CIDR block that
          contains twice the number of IP addresses that are required to enable the
          maximum number of concurrent connections is recommended.
    :attr bool enable_split_tunneling: (optional) Indicates whether the split
          tunneling is enabled on this VPN server.
    :attr str name: (optional) The name for this VPN server. The name must not be
          used by another VPN server in the VPC.
    :attr int port: (optional) The port number used by this VPN server.
    :attr str protocol: (optional) The transport protocol used by this VPN server.
    :attr List[SubnetIdentity] subnets: (optional) The subnets to provision this VPN
          server in (replacing the existing subnets).
    """

    def __init__(
        self,
        *,
        certificate: 'CertificateInstanceIdentity' = None,
        client_authentication: List['VPNServerAuthenticationPrototype'] = None,
        client_dns_server_ips: List['IP'] = None,
        client_idle_timeout: int = None,
        client_ip_pool: str = None,
        enable_split_tunneling: bool = None,
        name: str = None,
        port: int = None,
        protocol: str = None,
        subnets: List['SubnetIdentity'] = None,
    ) -> None:
        """
        Initialize a VPNServerPatch object.

        :param CertificateInstanceIdentity certificate: (optional) The certificate
               instance for this VPN server.
        :param List[VPNServerAuthenticationPrototype] client_authentication:
               (optional) The authentication methods to use to authenticate VPN client on
               this VPN server
               (replacing any existing methods).
        :param List[IP] client_dns_server_ips: (optional) The DNS server addresses
               that will be provided to VPN clients connected to this VPN server
               (replacing any existing addresses).
        :param int client_idle_timeout: (optional) The seconds a VPN client can be
               idle before this VPN server will disconnect it.  If `0`, the server will
               not disconnect idle clients.
        :param str client_ip_pool: (optional) The VPN client IPv4 address pool,
               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 client IP address pool's CIDR must be between
               `/9` (8,388,608 addresses) and `/22` (1024 addresses). A CIDR block that
               contains twice the number of IP addresses that are required to enable the
               maximum number of concurrent connections is recommended.
        :param bool enable_split_tunneling: (optional) Indicates whether the split
               tunneling is enabled on this VPN server.
        :param str name: (optional) The name for this VPN server. The name must not
               be used by another VPN server in the VPC.
        :param int port: (optional) The port number used by this VPN server.
        :param str protocol: (optional) The transport protocol used by this VPN
               server.
        :param List[SubnetIdentity] subnets: (optional) The subnets to provision
               this VPN server in (replacing the existing subnets).
        """
        self.certificate = certificate
        self.client_authentication = client_authentication
        self.client_dns_server_ips = client_dns_server_ips
        self.client_idle_timeout = client_idle_timeout
        self.client_ip_pool = client_ip_pool
        self.enable_split_tunneling = enable_split_tunneling
        self.name = name
        self.port = port
        self.protocol = protocol
        self.subnets = subnets

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPNServerPatch':
        """Initialize a VPNServerPatch object from a json dictionary."""
        args = {}
        if 'certificate' in _dict:
            args['certificate'] = _dict.get('certificate')
        if 'client_authentication' in _dict:
            args['client_authentication'] = [VPNServerAuthenticationPrototype.from_dict(v) for v in _dict.get('client_authentication')]
        if 'client_dns_server_ips' in _dict:
            args['client_dns_server_ips'] = [IP.from_dict(v) for v in _dict.get('client_dns_server_ips')]
        if 'client_idle_timeout' in _dict:
            args['client_idle_timeout'] = _dict.get('client_idle_timeout')
        if 'client_ip_pool' in _dict:
            args['client_ip_pool'] = _dict.get('client_ip_pool')
        if 'enable_split_tunneling' in _dict:
            args['enable_split_tunneling'] = _dict.get('enable_split_tunneling')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        if 'port' in _dict:
            args['port'] = _dict.get('port')
        if 'protocol' in _dict:
            args['protocol'] = _dict.get('protocol')
        if 'subnets' in _dict:
            args['subnets'] = _dict.get('subnets')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPNServerPatch object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'certificate') and self.certificate is not None:
            if isinstance(self.certificate, dict):
                _dict['certificate'] = self.certificate
            else:
                _dict['certificate'] = self.certificate.to_dict()
        if hasattr(self, 'client_authentication') and self.client_authentication is not None:
            client_authentication_list = []
            for v in self.client_authentication:
                if isinstance(v, dict):
                    client_authentication_list.append(v)
                else:
                    client_authentication_list.append(v.to_dict())
            _dict['client_authentication'] = client_authentication_list
        if hasattr(self, 'client_dns_server_ips') and self.client_dns_server_ips is not None:
            client_dns_server_ips_list = []
            for v in self.client_dns_server_ips:
                if isinstance(v, dict):
                    client_dns_server_ips_list.append(v)
                else:
                    client_dns_server_ips_list.append(v.to_dict())
            _dict['client_dns_server_ips'] = client_dns_server_ips_list
        if hasattr(self, 'client_idle_timeout') and self.client_idle_timeout is not None:
            _dict['client_idle_timeout'] = self.client_idle_timeout
        if hasattr(self, 'client_ip_pool') and self.client_ip_pool is not None:
            _dict['client_ip_pool'] = self.client_ip_pool
        if hasattr(self, 'enable_split_tunneling') and self.enable_split_tunneling is not None:
            _dict['enable_split_tunneling'] = self.enable_split_tunneling
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        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, 'subnets') and self.subnets is not None:
            subnets_list = []
            for v in self.subnets:
                if isinstance(v, dict):
                    subnets_list.append(v)
                else:
                    subnets_list.append(v.to_dict())
            _dict['subnets'] = subnets_list
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VPNServerPatch object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPNServerPatch') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPNServerPatch') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ProtocolEnum(str, Enum):
        """
        The transport protocol used by this VPN server.
        """

        TCP = 'tcp'
        UDP = 'udp'



class VPNServerReferenceDeleted:
    """
    If present, this property indicates the referenced resource has been deleted, and
    provides some supplementary information.

    :attr str more_info: Link to documentation about deleted resources.
    """

    def __init__(
        self,
        more_info: str,
    ) -> None:
        """
        Initialize a VPNServerReferenceDeleted object.

        :param str more_info: Link to documentation about deleted resources.
        """
        self.more_info = more_info

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPNServerReferenceDeleted':
        """Initialize a VPNServerReferenceDeleted object from a json dictionary."""
        args = {}
        if 'more_info' in _dict:
            args['more_info'] = _dict.get('more_info')
        else:
            raise ValueError('Required property \'more_info\' not present in VPNServerReferenceDeleted JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPNServerReferenceDeleted object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'more_info') and self.more_info is not None:
            _dict['more_info'] = self.more_info
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VPNServerReferenceDeleted object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPNServerReferenceDeleted') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPNServerReferenceDeleted') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VPNServerRoute:
    """
    VPNServerRoute.

    :attr str action: The action to perform with a packet matching the VPN route:
          - `translate`: translate the source IP address to one of the private IP
          addresses of the VPN server.
          - `deliver`: deliver the packet into the VPC.
          - `drop`: drop the packet
          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 VPN route on which the
          unexpected property value was encountered.
    :attr datetime created_at: The date and time that the VPN route was created.
    :attr str destination: The destination for this VPN route in the VPN server. If
          an incoming packet does not match any destination, it will be dropped.
    :attr List[VPNServerRouteHealthReason] health_reasons: The reasons for the
          current VPN server route health_state (if any):
          - `internal_error`: Internal error (contact IBM support)
          The enumerated reason code values for this property will expand in the future.
          When processing this property, check for and log unknown values. Optionally halt
          processing and surface the error, or bypass the resource on which the unexpected
          reason code was encountered.
    :attr str health_state: The health of this resource.
          - `ok`: No abnormal behavior detected
          - `degraded`: Experiencing compromised performance, capacity, or connectivity
          - `faulted`: Completely unreachable, inoperative, or otherwise entirely
          incapacitated
          - `inapplicable`: The health state does not apply because of the current
          lifecycle state. A resource with a lifecycle state of `failed` or `deleting`
          will have a health state of `inapplicable`. A `pending` resource may also have
          this state.
    :attr str href: The URL for this VPN route.
    :attr str id: The unique identifier for this VPN route.
    :attr List[VPNServerRouteLifecycleReason] lifecycle_reasons: The reasons for the
          current VPN server route lifecycle_state (if any):
          - `resource_suspended_by_provider`: The resource has been suspended (contact IBM
            support)
          The enumerated reason code values for this property will expand in the future.
          When processing this property, check for and log unknown values. Optionally halt
          processing and surface the error, or bypass the resource on which the unexpected
          reason code was encountered.
    :attr str lifecycle_state: The lifecycle state of the VPN route.
    :attr str name: The name for this VPN route. The name is unique across all
          routes for a VPN server.
    :attr str resource_type: The resource type.
    """

    def __init__(
        self,
        action: str,
        created_at: datetime,
        destination: str,
        health_reasons: List['VPNServerRouteHealthReason'],
        health_state: str,
        href: str,
        id: str,
        lifecycle_reasons: List['VPNServerRouteLifecycleReason'],
        lifecycle_state: str,
        name: str,
        resource_type: str,
    ) -> None:
        """
        Initialize a VPNServerRoute object.

        :param str action: The action to perform with a packet matching the VPN
               route:
               - `translate`: translate the source IP address to one of the private IP
               addresses of the VPN server.
               - `deliver`: deliver the packet into the VPC.
               - `drop`: drop the packet
               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 VPN route
               on which the unexpected property value was encountered.
        :param datetime created_at: The date and time that the VPN route was
               created.
        :param str destination: The destination for this VPN route in the VPN
               server. If an incoming packet does not match any destination, it will be
               dropped.
        :param List[VPNServerRouteHealthReason] health_reasons: The reasons for the
               current VPN server route health_state (if any):
               - `internal_error`: Internal error (contact IBM support)
               The enumerated reason code values for this property will expand in the
               future. When processing this property, check for and log unknown values.
               Optionally halt processing and surface the error, or bypass the resource on
               which the unexpected reason code was encountered.
        :param str health_state: The health of this resource.
               - `ok`: No abnormal behavior detected
               - `degraded`: Experiencing compromised performance, capacity, or
               connectivity
               - `faulted`: Completely unreachable, inoperative, or otherwise entirely
               incapacitated
               - `inapplicable`: The health state does not apply because of the current
               lifecycle state. A resource with a lifecycle state of `failed` or
               `deleting` will have a health state of `inapplicable`. A `pending` resource
               may also have this state.
        :param str href: The URL for this VPN route.
        :param str id: The unique identifier for this VPN route.
        :param List[VPNServerRouteLifecycleReason] lifecycle_reasons: The reasons
               for the current VPN server route lifecycle_state (if any):
               - `resource_suspended_by_provider`: The resource has been suspended
               (contact IBM
                 support)
               The enumerated reason code values for this property will expand in the
               future. When processing this property, check for and log unknown values.
               Optionally halt processing and surface the error, or bypass the resource on
               which the unexpected reason code was encountered.
        :param str lifecycle_state: The lifecycle state of the VPN route.
        :param str name: The name for this VPN route. The name is unique across all
               routes for a VPN server.
        :param str resource_type: The resource type.
        """
        self.action = action
        self.created_at = created_at
        self.destination = destination
        self.health_reasons = health_reasons
        self.health_state = health_state
        self.href = href
        self.id = id
        self.lifecycle_reasons = lifecycle_reasons
        self.lifecycle_state = lifecycle_state
        self.name = name
        self.resource_type = resource_type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPNServerRoute':
        """Initialize a VPNServerRoute object from a json dictionary."""
        args = {}
        if 'action' in _dict:
            args['action'] = _dict.get('action')
        else:
            raise ValueError('Required property \'action\' not present in VPNServerRoute 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 VPNServerRoute JSON')
        if 'destination' in _dict:
            args['destination'] = _dict.get('destination')
        else:
            raise ValueError('Required property \'destination\' not present in VPNServerRoute JSON')
        if 'health_reasons' in _dict:
            args['health_reasons'] = [VPNServerRouteHealthReason.from_dict(v) for v in _dict.get('health_reasons')]
        else:
            raise ValueError('Required property \'health_reasons\' not present in VPNServerRoute JSON')
        if 'health_state' in _dict:
            args['health_state'] = _dict.get('health_state')
        else:
            raise ValueError('Required property \'health_state\' not present in VPNServerRoute JSON')
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in VPNServerRoute JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in VPNServerRoute JSON')
        if 'lifecycle_reasons' in _dict:
            args['lifecycle_reasons'] = [VPNServerRouteLifecycleReason.from_dict(v) for v in _dict.get('lifecycle_reasons')]
        else:
            raise ValueError('Required property \'lifecycle_reasons\' not present in VPNServerRoute JSON')
        if 'lifecycle_state' in _dict:
            args['lifecycle_state'] = _dict.get('lifecycle_state')
        else:
            raise ValueError('Required property \'lifecycle_state\' not present in VPNServerRoute JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in VPNServerRoute JSON')
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError('Required property \'resource_type\' not present in VPNServerRoute JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPNServerRoute object from 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, 'destination') and self.destination is not None:
            _dict['destination'] = self.destination
        if hasattr(self, 'health_reasons') and self.health_reasons is not None:
            health_reasons_list = []
            for v in self.health_reasons:
                if isinstance(v, dict):
                    health_reasons_list.append(v)
                else:
                    health_reasons_list.append(v.to_dict())
            _dict['health_reasons'] = health_reasons_list
        if hasattr(self, 'health_state') and self.health_state is not None:
            _dict['health_state'] = self.health_state
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'lifecycle_reasons') and self.lifecycle_reasons is not None:
            lifecycle_reasons_list = []
            for v in self.lifecycle_reasons:
                if isinstance(v, dict):
                    lifecycle_reasons_list.append(v)
                else:
                    lifecycle_reasons_list.append(v.to_dict())
            _dict['lifecycle_reasons'] = lifecycle_reasons_list
        if hasattr(self, 'lifecycle_state') and self.lifecycle_state is not None:
            _dict['lifecycle_state'] = self.lifecycle_state
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'resource_type') and self.resource_type is not None:
            _dict['resource_type'] = self.resource_type
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VPNServerRoute object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPNServerRoute') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPNServerRoute') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ActionEnum(str, Enum):
        """
        The action to perform with a packet matching the VPN route:
        - `translate`: translate the source IP address to one of the private IP addresses
        of the VPN server.
        - `deliver`: deliver the packet into the VPC.
        - `drop`: drop the packet
        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 VPN route on which the unexpected
        property value was encountered.
        """

        DELIVER = 'deliver'
        DROP = 'drop'
        TRANSLATE = 'translate'


    class HealthStateEnum(str, Enum):
        """
        The health of this resource.
        - `ok`: No abnormal behavior detected
        - `degraded`: Experiencing compromised performance, capacity, or connectivity
        - `faulted`: Completely unreachable, inoperative, or otherwise entirely
        incapacitated
        - `inapplicable`: The health state does not apply because of the current lifecycle
        state. A resource with a lifecycle state of `failed` or `deleting` will have a
        health state of `inapplicable`. A `pending` resource may also have this state.
        """

        DEGRADED = 'degraded'
        FAULTED = 'faulted'
        INAPPLICABLE = 'inapplicable'
        OK = 'ok'


    class LifecycleStateEnum(str, Enum):
        """
        The lifecycle state of the VPN route.
        """

        DELETING = 'deleting'
        FAILED = 'failed'
        PENDING = 'pending'
        STABLE = 'stable'
        SUSPENDED = 'suspended'
        UPDATING = 'updating'
        WAITING = 'waiting'


    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        VPN_SERVER_ROUTE = 'vpn_server_route'



class VPNServerRouteCollection:
    """
    VPNServerRouteCollection.

    :attr VPNServerRouteCollectionFirst 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 VPNServerRouteCollectionNext next: (optional) A link to the next page of
          resources. This property is present for all pages
          except the last page.
    :attr List[VPNServerRoute] routes: Collection of VPN routes.
    :attr int total_count: The total number of resources across all pages.
    """

    def __init__(
        self,
        first: 'VPNServerRouteCollectionFirst',
        limit: int,
        routes: List['VPNServerRoute'],
        total_count: int,
        *,
        next: 'VPNServerRouteCollectionNext' = None,
    ) -> None:
        """
        Initialize a VPNServerRouteCollection object.

        :param VPNServerRouteCollectionFirst 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[VPNServerRoute] routes: Collection of VPN routes.
        :param int total_count: The total number of resources across all pages.
        :param VPNServerRouteCollectionNext next: (optional) A link to the next
               page of resources. This property is present for all pages
               except the last page.
        """
        self.first = first
        self.limit = limit
        self.next = next
        self.routes = routes
        self.total_count = total_count

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPNServerRouteCollection':
        """Initialize a VPNServerRouteCollection object from a json dictionary."""
        args = {}
        if 'first' in _dict:
            args['first'] = VPNServerRouteCollectionFirst.from_dict(_dict.get('first'))
        else:
            raise ValueError('Required property \'first\' not present in VPNServerRouteCollection JSON')
        if 'limit' in _dict:
            args['limit'] = _dict.get('limit')
        else:
            raise ValueError('Required property \'limit\' not present in VPNServerRouteCollection JSON')
        if 'next' in _dict:
            args['next'] = VPNServerRouteCollectionNext.from_dict(_dict.get('next'))
        if 'routes' in _dict:
            args['routes'] = [VPNServerRoute.from_dict(v) for v in _dict.get('routes')]
        else:
            raise ValueError('Required property \'routes\' not present in VPNServerRouteCollection JSON')
        if 'total_count' in _dict:
            args['total_count'] = _dict.get('total_count')
        else:
            raise ValueError('Required property \'total_count\' not present in VPNServerRouteCollection JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPNServerRouteCollection object from 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:
            if isinstance(self.first, dict):
                _dict['first'] = self.first
            else:
                _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:
            if isinstance(self.next, dict):
                _dict['next'] = self.next
            else:
                _dict['next'] = self.next.to_dict()
        if hasattr(self, 'routes') and self.routes is not None:
            routes_list = []
            for v in self.routes:
                if isinstance(v, dict):
                    routes_list.append(v)
                else:
                    routes_list.append(v.to_dict())
            _dict['routes'] = routes_list
        if hasattr(self, 'total_count') and self.total_count is not None:
            _dict['total_count'] = self.total_count
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VPNServerRouteCollection object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPNServerRouteCollection') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPNServerRouteCollection') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VPNServerRouteCollectionFirst:
    """
    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 VPNServerRouteCollectionFirst object.

        :param str href: The URL for a page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPNServerRouteCollectionFirst':
        """Initialize a VPNServerRouteCollectionFirst object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in VPNServerRouteCollectionFirst JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPNServerRouteCollectionFirst object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(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 VPNServerRouteCollectionFirst object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPNServerRouteCollectionFirst') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPNServerRouteCollectionFirst') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VPNServerRouteCollectionNext:
    """
    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 VPNServerRouteCollectionNext object.

        :param str href: The URL for a page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPNServerRouteCollectionNext':
        """Initialize a VPNServerRouteCollectionNext object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in VPNServerRouteCollectionNext JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPNServerRouteCollectionNext object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(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 VPNServerRouteCollectionNext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPNServerRouteCollectionNext') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPNServerRouteCollectionNext') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VPNServerRouteHealthReason:
    """
    VPNServerRouteHealthReason.

    :attr str code: A snake case string succinctly identifying the reason for this
          health state.
    :attr str message: An explanation of the reason for this health state.
    :attr str more_info: (optional) Link to documentation about the reason for this
          health state.
    """

    def __init__(
        self,
        code: str,
        message: str,
        *,
        more_info: str = None,
    ) -> None:
        """
        Initialize a VPNServerRouteHealthReason object.

        :param str code: A snake case string succinctly identifying the reason for
               this health state.
        :param str message: An explanation of the reason for this health state.
        :param str more_info: (optional) Link to documentation about the reason for
               this health state.
        """
        self.code = code
        self.message = message
        self.more_info = more_info

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPNServerRouteHealthReason':
        """Initialize a VPNServerRouteHealthReason object from a json dictionary."""
        args = {}
        if 'code' in _dict:
            args['code'] = _dict.get('code')
        else:
            raise ValueError('Required property \'code\' not present in VPNServerRouteHealthReason JSON')
        if 'message' in _dict:
            args['message'] = _dict.get('message')
        else:
            raise ValueError('Required property \'message\' not present in VPNServerRouteHealthReason JSON')
        if 'more_info' in _dict:
            args['more_info'] = _dict.get('more_info')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPNServerRouteHealthReason object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'code') and self.code is not None:
            _dict['code'] = self.code
        if hasattr(self, 'message') and self.message is not None:
            _dict['message'] = self.message
        if hasattr(self, 'more_info') and self.more_info is not None:
            _dict['more_info'] = self.more_info
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VPNServerRouteHealthReason object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPNServerRouteHealthReason') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPNServerRouteHealthReason') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class CodeEnum(str, Enum):
        """
        A snake case string succinctly identifying the reason for this health state.
        """

        INTERNAL_ERROR = 'internal_error'



class VPNServerRouteLifecycleReason:
    """
    VPNServerRouteLifecycleReason.

    :attr str code: A snake case string succinctly identifying the reason for this
          lifecycle state.
    :attr str message: An explanation of the reason for this lifecycle state.
    :attr str more_info: (optional) Link to documentation about the reason for this
          lifecycle state.
    """

    def __init__(
        self,
        code: str,
        message: str,
        *,
        more_info: str = None,
    ) -> None:
        """
        Initialize a VPNServerRouteLifecycleReason object.

        :param str code: A snake case string succinctly identifying the reason for
               this lifecycle state.
        :param str message: An explanation of the reason for this lifecycle state.
        :param str more_info: (optional) Link to documentation about the reason for
               this lifecycle state.
        """
        self.code = code
        self.message = message
        self.more_info = more_info

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPNServerRouteLifecycleReason':
        """Initialize a VPNServerRouteLifecycleReason object from a json dictionary."""
        args = {}
        if 'code' in _dict:
            args['code'] = _dict.get('code')
        else:
            raise ValueError('Required property \'code\' not present in VPNServerRouteLifecycleReason JSON')
        if 'message' in _dict:
            args['message'] = _dict.get('message')
        else:
            raise ValueError('Required property \'message\' not present in VPNServerRouteLifecycleReason JSON')
        if 'more_info' in _dict:
            args['more_info'] = _dict.get('more_info')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPNServerRouteLifecycleReason object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'code') and self.code is not None:
            _dict['code'] = self.code
        if hasattr(self, 'message') and self.message is not None:
            _dict['message'] = self.message
        if hasattr(self, 'more_info') and self.more_info is not None:
            _dict['more_info'] = self.more_info
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VPNServerRouteLifecycleReason object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPNServerRouteLifecycleReason') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPNServerRouteLifecycleReason') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class CodeEnum(str, Enum):
        """
        A snake case string succinctly identifying the reason for this lifecycle state.
        """

        RESOURCE_SUSPENDED_BY_PROVIDER = 'resource_suspended_by_provider'



class VPNServerRoutePatch:
    """
    VPNServerRoutePatch.

    :attr str name: (optional) The name for this VPN server route. The name must not
          be used by another route for the VPN server.
    """

    def __init__(
        self,
        *,
        name: str = None,
    ) -> None:
        """
        Initialize a VPNServerRoutePatch object.

        :param str name: (optional) The name for this VPN server route. The name
               must not be used by another route for the VPN server.
        """
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPNServerRoutePatch':
        """Initialize a VPNServerRoutePatch 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 VPNServerRoutePatch object from 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 VPNServerRoutePatch object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPNServerRoutePatch') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPNServerRoutePatch') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VirtualNetworkInterface:
    """
    VirtualNetworkInterface.

    :attr bool auto_delete: Indicates whether this virtual network interface will be
          automatically deleted when
          `target` is deleted.
    :attr datetime created_at: The date and time that the virtual network interface
          was created.
    :attr str crn: The CRN for this virtual network interface.
    :attr str href: The URL for this virtual network interface.
    :attr str id: The unique identifier for this virtual network interface.
    :attr str lifecycle_state: The lifecycle state of the virtual network interface.
    :attr str name: The name for this virtual network interface. The name is unique
          across all virtual network interfaces in the VPC.
    :attr ReservedIPReference primary_ip: The reserved IP for this virtual network
          interface.
    :attr ResourceGroupReference resource_group: The resource group for this virtual
          network interface.
    :attr str resource_type: The resource type.
    :attr List[SecurityGroupReference] security_groups: The security groups for this
          virtual network interface.
    :attr SubnetReference subnet: The associated subnet.
    :attr VirtualNetworkInterfaceTarget target: (optional) The target of this
          virtual network interface.
          If absent, this virtual network interface is not attached to a target.
    :attr VPCReference vpc: The VPC this virtual network interface resides in.
    :attr ZoneReference zone: The zone this virtual network interface resides in.
    """

    def __init__(
        self,
        auto_delete: bool,
        created_at: datetime,
        crn: str,
        href: str,
        id: str,
        lifecycle_state: str,
        name: str,
        primary_ip: 'ReservedIPReference',
        resource_group: 'ResourceGroupReference',
        resource_type: str,
        security_groups: List['SecurityGroupReference'],
        subnet: 'SubnetReference',
        vpc: 'VPCReference',
        zone: 'ZoneReference',
        *,
        target: 'VirtualNetworkInterfaceTarget' = None,
    ) -> None:
        """
        Initialize a VirtualNetworkInterface object.

        :param bool auto_delete: Indicates whether this virtual network interface
               will be automatically deleted when
               `target` is deleted.
        :param datetime created_at: The date and time that the virtual network
               interface was created.
        :param str crn: The CRN for this virtual network interface.
        :param str href: The URL for this virtual network interface.
        :param str id: The unique identifier for this virtual network interface.
        :param str lifecycle_state: The lifecycle state of the virtual network
               interface.
        :param str name: The name for this virtual network interface. The name is
               unique across all virtual network interfaces in the VPC.
        :param ReservedIPReference primary_ip: The reserved IP for this virtual
               network interface.
        :param ResourceGroupReference resource_group: The resource group for this
               virtual network interface.
        :param str resource_type: The resource type.
        :param List[SecurityGroupReference] security_groups: The security groups
               for this virtual network interface.
        :param SubnetReference subnet: The associated subnet.
        :param VPCReference vpc: The VPC this virtual network interface resides in.
        :param ZoneReference zone: The zone this virtual network interface resides
               in.
        :param VirtualNetworkInterfaceTarget target: (optional) The target of this
               virtual network interface.
               If absent, this virtual network interface is not attached to a target.
        """
        self.auto_delete = auto_delete
        self.created_at = created_at
        self.crn = crn
        self.href = href
        self.id = id
        self.lifecycle_state = lifecycle_state
        self.name = name
        self.primary_ip = primary_ip
        self.resource_group = resource_group
        self.resource_type = resource_type
        self.security_groups = security_groups
        self.subnet = subnet
        self.target = target
        self.vpc = vpc
        self.zone = zone

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VirtualNetworkInterface':
        """Initialize a VirtualNetworkInterface object from a json dictionary."""
        args = {}
        if 'auto_delete' in _dict:
            args['auto_delete'] = _dict.get('auto_delete')
        else:
            raise ValueError('Required property \'auto_delete\' not present in VirtualNetworkInterface 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 VirtualNetworkInterface JSON')
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError('Required property \'crn\' not present in VirtualNetworkInterface JSON')
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in VirtualNetworkInterface JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in VirtualNetworkInterface JSON')
        if 'lifecycle_state' in _dict:
            args['lifecycle_state'] = _dict.get('lifecycle_state')
        else:
            raise ValueError('Required property \'lifecycle_state\' not present in VirtualNetworkInterface JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in VirtualNetworkInterface JSON')
        if 'primary_ip' in _dict:
            args['primary_ip'] = ReservedIPReference.from_dict(_dict.get('primary_ip'))
        else:
            raise ValueError('Required property \'primary_ip\' not present in VirtualNetworkInterface 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 VirtualNetworkInterface JSON')
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError('Required property \'resource_type\' not present in VirtualNetworkInterface JSON')
        if 'security_groups' in _dict:
            args['security_groups'] = [SecurityGroupReference.from_dict(v) for v in _dict.get('security_groups')]
        else:
            raise ValueError('Required property \'security_groups\' not present in VirtualNetworkInterface JSON')
        if 'subnet' in _dict:
            args['subnet'] = SubnetReference.from_dict(_dict.get('subnet'))
        else:
            raise ValueError('Required property \'subnet\' not present in VirtualNetworkInterface JSON')
        if 'target' in _dict:
            args['target'] = _dict.get('target')
        if 'vpc' in _dict:
            args['vpc'] = VPCReference.from_dict(_dict.get('vpc'))
        else:
            raise ValueError('Required property \'vpc\' not present in VirtualNetworkInterface JSON')
        if 'zone' in _dict:
            args['zone'] = ZoneReference.from_dict(_dict.get('zone'))
        else:
            raise ValueError('Required property \'zone\' not present in VirtualNetworkInterface JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VirtualNetworkInterface object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'auto_delete') and self.auto_delete is not None:
            _dict['auto_delete'] = self.auto_delete
        if hasattr(self, 'created_at') and self.created_at is not None:
            _dict['created_at'] = datetime_to_string(self.created_at)
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'lifecycle_state') and self.lifecycle_state is not None:
            _dict['lifecycle_state'] = self.lifecycle_state
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'primary_ip') and self.primary_ip is not None:
            if isinstance(self.primary_ip, dict):
                _dict['primary_ip'] = self.primary_ip
            else:
                _dict['primary_ip'] = self.primary_ip.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, '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:
            security_groups_list = []
            for v in self.security_groups:
                if isinstance(v, dict):
                    security_groups_list.append(v)
                else:
                    security_groups_list.append(v.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()
        if hasattr(self, 'target') and self.target is not None:
            if isinstance(self.target, dict):
                _dict['target'] = self.target
            else:
                _dict['target'] = self.target.to_dict()
        if hasattr(self, 'vpc') and self.vpc is not None:
            if isinstance(self.vpc, dict):
                _dict['vpc'] = self.vpc
            else:
                _dict['vpc'] = self.vpc.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 VirtualNetworkInterface object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VirtualNetworkInterface') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VirtualNetworkInterface') -> 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 virtual network interface.
        """

        DELETING = 'deleting'
        FAILED = 'failed'
        PENDING = 'pending'
        STABLE = 'stable'
        SUSPENDED = 'suspended'
        UPDATING = 'updating'
        WAITING = 'waiting'


    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        VIRTUAL_NETWORK_INTERFACE = 'virtual_network_interface'



class VirtualNetworkInterfaceCollection:
    """
    VirtualNetworkInterfaceCollection.

    :attr VirtualNetworkInterfaceCollectionFirst 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 VirtualNetworkInterfaceCollectionNext 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[VirtualNetworkInterface] virtual_network_interfaces: Collection of
          virtual network interfaces.
    """

    def __init__(
        self,
        first: 'VirtualNetworkInterfaceCollectionFirst',
        limit: int,
        total_count: int,
        virtual_network_interfaces: List['VirtualNetworkInterface'],
        *,
        next: 'VirtualNetworkInterfaceCollectionNext' = None,
    ) -> None:
        """
        Initialize a VirtualNetworkInterfaceCollection object.

        :param VirtualNetworkInterfaceCollectionFirst 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[VirtualNetworkInterface] virtual_network_interfaces: Collection
               of virtual network interfaces.
        :param VirtualNetworkInterfaceCollectionNext 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.virtual_network_interfaces = virtual_network_interfaces

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VirtualNetworkInterfaceCollection':
        """Initialize a VirtualNetworkInterfaceCollection object from a json dictionary."""
        args = {}
        if 'first' in _dict:
            args['first'] = VirtualNetworkInterfaceCollectionFirst.from_dict(_dict.get('first'))
        else:
            raise ValueError('Required property \'first\' not present in VirtualNetworkInterfaceCollection JSON')
        if 'limit' in _dict:
            args['limit'] = _dict.get('limit')
        else:
            raise ValueError('Required property \'limit\' not present in VirtualNetworkInterfaceCollection JSON')
        if 'next' in _dict:
            args['next'] = VirtualNetworkInterfaceCollectionNext.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 VirtualNetworkInterfaceCollection JSON')
        if 'virtual_network_interfaces' in _dict:
            args['virtual_network_interfaces'] = [VirtualNetworkInterface.from_dict(v) for v in _dict.get('virtual_network_interfaces')]
        else:
            raise ValueError('Required property \'virtual_network_interfaces\' not present in VirtualNetworkInterfaceCollection JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VirtualNetworkInterfaceCollection object from 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:
            if isinstance(self.first, dict):
                _dict['first'] = self.first
            else:
                _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:
            if isinstance(self.next, dict):
                _dict['next'] = self.next
            else:
                _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, 'virtual_network_interfaces') and self.virtual_network_interfaces is not None:
            virtual_network_interfaces_list = []
            for v in self.virtual_network_interfaces:
                if isinstance(v, dict):
                    virtual_network_interfaces_list.append(v)
                else:
                    virtual_network_interfaces_list.append(v.to_dict())
            _dict['virtual_network_interfaces'] = virtual_network_interfaces_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 VirtualNetworkInterfaceCollection object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VirtualNetworkInterfaceCollection') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VirtualNetworkInterfaceCollection') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VirtualNetworkInterfaceCollectionFirst:
    """
    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 VirtualNetworkInterfaceCollectionFirst object.

        :param str href: The URL for a page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VirtualNetworkInterfaceCollectionFirst':
        """Initialize a VirtualNetworkInterfaceCollectionFirst object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in VirtualNetworkInterfaceCollectionFirst JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VirtualNetworkInterfaceCollectionFirst object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(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 VirtualNetworkInterfaceCollectionFirst object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VirtualNetworkInterfaceCollectionFirst') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VirtualNetworkInterfaceCollectionFirst') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VirtualNetworkInterfaceCollectionNext:
    """
    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 VirtualNetworkInterfaceCollectionNext object.

        :param str href: The URL for a page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VirtualNetworkInterfaceCollectionNext':
        """Initialize a VirtualNetworkInterfaceCollectionNext object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in VirtualNetworkInterfaceCollectionNext JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VirtualNetworkInterfaceCollectionNext object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(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 VirtualNetworkInterfaceCollectionNext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VirtualNetworkInterfaceCollectionNext') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VirtualNetworkInterfaceCollectionNext') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VirtualNetworkInterfacePatch:
    """
    VirtualNetworkInterfacePatch.

    :attr str name: (optional) The name for this virtual network interface. The name
          is unique across all virtual network interfaces in the VPC.
    """

    def __init__(
        self,
        *,
        name: str = None,
    ) -> None:
        """
        Initialize a VirtualNetworkInterfacePatch object.

        :param str name: (optional) The name for this virtual network interface.
               The name is unique across all virtual network interfaces in the VPC.
        """
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VirtualNetworkInterfacePatch':
        """Initialize a VirtualNetworkInterfacePatch 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 VirtualNetworkInterfacePatch object from 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 VirtualNetworkInterfacePatch object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VirtualNetworkInterfacePatch') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VirtualNetworkInterfacePatch') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VirtualNetworkInterfacePrimaryIPPrototype:
    """
    VirtualNetworkInterfacePrimaryIPPrototype.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a VirtualNetworkInterfacePrimaryIPPrototype object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['VirtualNetworkInterfacePrimaryIPPrototypeReservedIPIdentityVirtualNetworkInterfacePrimaryIPContext', 'VirtualNetworkInterfacePrimaryIPPrototypeReservedIPPrototypeVirtualNetworkInterfacePrimaryIPContext'])
        )
        raise Exception(msg)


class VirtualNetworkInterfaceReferenceAttachmentContext:
    """
    VirtualNetworkInterfaceReferenceAttachmentContext.

    :attr str crn: The CRN for this virtual network interface.
    :attr str href: The URL for this virtual network interface.
    :attr str id: The unique identifier for this virtual network interface.
    :attr str name: The name for this virtual network interface. The name is unique
          across all virtual network interfaces in the VPC.
    :attr str resource_type: The resource type.
    """

    def __init__(
        self,
        crn: str,
        href: str,
        id: str,
        name: str,
        resource_type: str,
    ) -> None:
        """
        Initialize a VirtualNetworkInterfaceReferenceAttachmentContext object.

        :param str crn: The CRN for this virtual network interface.
        :param str href: The URL for this virtual network interface.
        :param str id: The unique identifier for this virtual network interface.
        :param str name: The name for this virtual network interface. The name is
               unique across all virtual network interfaces in the VPC.
        :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) -> 'VirtualNetworkInterfaceReferenceAttachmentContext':
        """Initialize a VirtualNetworkInterfaceReferenceAttachmentContext object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError('Required property \'crn\' not present in VirtualNetworkInterfaceReferenceAttachmentContext JSON')
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in VirtualNetworkInterfaceReferenceAttachmentContext JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in VirtualNetworkInterfaceReferenceAttachmentContext JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in VirtualNetworkInterfaceReferenceAttachmentContext JSON')
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError('Required property \'resource_type\' not present in VirtualNetworkInterfaceReferenceAttachmentContext JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VirtualNetworkInterfaceReferenceAttachmentContext object from 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 VirtualNetworkInterfaceReferenceAttachmentContext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VirtualNetworkInterfaceReferenceAttachmentContext') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VirtualNetworkInterfaceReferenceAttachmentContext') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        VIRTUAL_NETWORK_INTERFACE = 'virtual_network_interface'



class VirtualNetworkInterfaceReferenceDeleted:
    """
    If present, this property indicates the referenced resource has been deleted, and
    provides some supplementary information.

    :attr str more_info: Link to documentation about deleted resources.
    """

    def __init__(
        self,
        more_info: str,
    ) -> None:
        """
        Initialize a VirtualNetworkInterfaceReferenceDeleted object.

        :param str more_info: Link to documentation about deleted resources.
        """
        self.more_info = more_info

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VirtualNetworkInterfaceReferenceDeleted':
        """Initialize a VirtualNetworkInterfaceReferenceDeleted object from a json dictionary."""
        args = {}
        if 'more_info' in _dict:
            args['more_info'] = _dict.get('more_info')
        else:
            raise ValueError('Required property \'more_info\' not present in VirtualNetworkInterfaceReferenceDeleted JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VirtualNetworkInterfaceReferenceDeleted object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'more_info') and self.more_info is not None:
            _dict['more_info'] = self.more_info
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VirtualNetworkInterfaceReferenceDeleted object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VirtualNetworkInterfaceReferenceDeleted') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VirtualNetworkInterfaceReferenceDeleted') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VirtualNetworkInterfaceTarget:
    """
    A virtual network interface target.
    The resource types that can be virtual network interface targets are expected to
    expand in the future. When iterating over virtual network interface targets, do not
    assume that every target resource will be from a known set of resource types.
    Optionally halt processing and surface an error, or bypass resources of unrecognized
    types.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a VirtualNetworkInterfaceTarget object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['VirtualNetworkInterfaceTargetShareMountTargetReference'])
        )
        raise Exception(msg)


class Volume:
    """
    Volume.

    :attr bool active: Indicates whether a running virtual server instance has an
          attachment to this volume.
    :attr str attachment_state: The attachment state of the volume
          - `unattached`: Not attached to any virtual server instances
          - `attached`: Attached to a virtual server instance (even if the instance is
          stopped)
          - `unusable`: Not able to be attached to any virtual server instances.
    :attr int bandwidth: The maximum bandwidth (in megabits per second) for the
          volume.
    :attr bool busy: Indicates whether this volume is performing an operation that
          must be serialized. This must be `false` to perform an operation that is
          specified to require serialization.
    :attr int capacity: The capacity to use for 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) 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 List[VolumeHealthReason] health_reasons: The reasons for the current
          `health_state` (if any).
          The enumerated reason code values for this property will expand in the future.
          When processing this property, check for and log unknown values. Optionally halt
          processing and surface the error, or bypass the resource on which the unexpected
          reason code was encountered.
    :attr str health_state: The health of this resource.
          - `ok`: No abnormal behavior detected
          - `degraded`: Experiencing compromised performance, capacity, or connectivity
          - `faulted`: Completely unreachable, inoperative, or otherwise entirely
          incapacitated
          - `inapplicable`: The health state does not apply because of the current
          lifecycle state. A resource with a lifecycle state of `failed` or `deleting`
          will have a health state of `inapplicable`. A `pending` resource may also have
          this state.
    :attr str href: The URL for this volume.
    :attr str id: The unique identifier for this volume.
    :attr int iops: The maximum I/O operations per second (IOPS) for this volume.
    :attr str name: The name for this volume. The name is unique across all volumes
          in the region.
    :attr OperatingSystem operating_system: (optional) The operating system
          associated with this volume. If absent, this volume was not
          created from an image, or the image did not include an operating system.
    :attr VolumeProfileReference profile: The
          [profile](https://cloud.ibm.com/docs/vpc?topic=vpc-block-storage-profiles) for
          this volume.
    :attr ResourceGroupReference resource_group: The resource group for this volume.
    :attr str resource_type: The resource type.
    :attr ImageReference source_image: (optional) The image from which this volume
          was created (this may be
          [deleted](https://cloud.ibm.com/apidocs/vpc#deleted-resources)).
          If absent, this volume was not created from an image.
    :attr SnapshotReference source_snapshot: (optional) The snapshot from which this
          volume was cloned.
    :attr str status: The status of the volume.
          The enumerated values for this property will expand in the future. When
          processing this property, check for and log unknown values. Optionally halt
          processing and surface the error, or bypass the volume on which the unexpected
          property value was encountered.
    :attr List[VolumeStatusReason] status_reasons: The reasons for the current
          status (if any).
          The enumerated reason code values for this property will expand in the future.
          When processing this property, check for and log unknown values. Optionally halt
          processing and surface the error, or bypass the resource on which the unexpected
          reason code was encountered.
    :attr List[str] user_tags: The [user
          tags](https://cloud.ibm.com/apidocs/tagging#types-of-tags) associated with this
          volume.
    :attr List[VolumeAttachmentReferenceVolumeContext] volume_attachments: The
          volume attachments for this volume.
    :attr ZoneReference zone: The zone this volume resides in.
    """

    def __init__(
        self,
        active: bool,
        attachment_state: str,
        bandwidth: int,
        busy: bool,
        capacity: int,
        created_at: datetime,
        crn: str,
        encryption: str,
        health_reasons: List['VolumeHealthReason'],
        health_state: str,
        href: str,
        id: str,
        iops: int,
        name: str,
        profile: 'VolumeProfileReference',
        resource_group: 'ResourceGroupReference',
        resource_type: str,
        status: str,
        status_reasons: List['VolumeStatusReason'],
        user_tags: List[str],
        volume_attachments: List['VolumeAttachmentReferenceVolumeContext'],
        zone: 'ZoneReference',
        *,
        encryption_key: 'EncryptionKeyReference' = None,
        operating_system: 'OperatingSystem' = None,
        source_image: 'ImageReference' = None,
        source_snapshot: 'SnapshotReference' = None,
    ) -> None:
        """
        Initialize a Volume object.

        :param bool active: Indicates whether a running virtual server instance has
               an attachment to this volume.
        :param str attachment_state: The attachment state of the volume
               - `unattached`: Not attached to any virtual server instances
               - `attached`: Attached to a virtual server instance (even if the instance
               is stopped)
               - `unusable`: Not able to be attached to any virtual server instances.
        :param int bandwidth: The maximum bandwidth (in megabits per second) for
               the volume.
        :param bool busy: Indicates whether this volume is performing an operation
               that must be serialized. This must be `false` to perform an operation that
               is specified to require serialization.
        :param int capacity: The capacity to use for 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 List[VolumeHealthReason] health_reasons: The reasons for the current
               `health_state` (if any).
               The enumerated reason code values for this property will expand in the
               future. When processing this property, check for and log unknown values.
               Optionally halt processing and surface the error, or bypass the resource on
               which the unexpected reason code was encountered.
        :param str health_state: The health of this resource.
               - `ok`: No abnormal behavior detected
               - `degraded`: Experiencing compromised performance, capacity, or
               connectivity
               - `faulted`: Completely unreachable, inoperative, or otherwise entirely
               incapacitated
               - `inapplicable`: The health state does not apply because of the current
               lifecycle state. A resource with a lifecycle state of `failed` or
               `deleting` will have a health state of `inapplicable`. A `pending` resource
               may also have this state.
        :param str href: The URL for this volume.
        :param str id: The unique identifier for this volume.
        :param int iops: The maximum I/O operations per second (IOPS) for this
               volume.
        :param str name: The name for this volume. The name is unique across all
               volumes in the region.
        :param VolumeProfileReference profile: The
               [profile](https://cloud.ibm.com/docs/vpc?topic=vpc-block-storage-profiles)
               for
               this volume.
        :param ResourceGroupReference resource_group: The resource group for this
               volume.
        :param str resource_type: The resource type.
        :param str status: The status of the volume.
               The enumerated values for this property will expand in the future. When
               processing this property, check for and log unknown values. Optionally halt
               processing and surface the error, or bypass the volume on which the
               unexpected property value was encountered.
        :param List[VolumeStatusReason] status_reasons: The reasons for the current
               status (if any).
               The enumerated reason code values for this property will expand in the
               future. When processing this property, check for and log unknown values.
               Optionally halt processing and surface the error, or bypass the resource on
               which the unexpected reason code was encountered.
        :param List[str] user_tags: The [user
               tags](https://cloud.ibm.com/apidocs/tagging#types-of-tags) associated with
               this volume.
        :param List[VolumeAttachmentReferenceVolumeContext] volume_attachments: The
               volume attachments for this volume.
        :param ZoneReference zone: The zone this volume resides in.
        :param EncryptionKeyReference encryption_key: (optional) 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`.
        :param OperatingSystem operating_system: (optional) The operating system
               associated with this volume. If absent, this volume was not
               created from an image, or the image did not include an operating system.
        :param ImageReference source_image: (optional) The image from which this
               volume was created (this may be
               [deleted](https://cloud.ibm.com/apidocs/vpc#deleted-resources)).
               If absent, this volume was not created from an image.
        :param SnapshotReference source_snapshot: (optional) The snapshot from
               which this volume was cloned.
        """
        self.active = active
        self.attachment_state = attachment_state
        self.bandwidth = bandwidth
        self.busy = busy
        self.capacity = capacity
        self.created_at = created_at
        self.crn = crn
        self.encryption = encryption
        self.encryption_key = encryption_key
        self.health_reasons = health_reasons
        self.health_state = health_state
        self.href = href
        self.id = id
        self.iops = iops
        self.name = name
        self.operating_system = operating_system
        self.profile = profile
        self.resource_group = resource_group
        self.resource_type = resource_type
        self.source_image = source_image
        self.source_snapshot = source_snapshot
        self.status = status
        self.status_reasons = status_reasons
        self.user_tags = user_tags
        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 'active' in _dict:
            args['active'] = _dict.get('active')
        else:
            raise ValueError('Required property \'active\' not present in Volume JSON')
        if 'attachment_state' in _dict:
            args['attachment_state'] = _dict.get('attachment_state')
        else:
            raise ValueError('Required property \'attachment_state\' not present in Volume JSON')
        if 'bandwidth' in _dict:
            args['bandwidth'] = _dict.get('bandwidth')
        else:
            raise ValueError('Required property \'bandwidth\' not present in Volume JSON')
        if 'busy' in _dict:
            args['busy'] = _dict.get('busy')
        else:
            raise ValueError('Required property \'busy\' not present in Volume JSON')
        if 'capacity' in _dict:
            args['capacity'] = _dict.get('capacity')
        else:
            raise ValueError('Required property \'capacity\' not present in Volume JSON')
        if '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 'health_reasons' in _dict:
            args['health_reasons'] = [VolumeHealthReason.from_dict(v) for v in _dict.get('health_reasons')]
        else:
            raise ValueError('Required property \'health_reasons\' not present in Volume JSON')
        if 'health_state' in _dict:
            args['health_state'] = _dict.get('health_state')
        else:
            raise ValueError('Required property \'health_state\' not present in Volume JSON')
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in Volume JSON')
        if '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 'operating_system' in _dict:
            args['operating_system'] = OperatingSystem.from_dict(_dict.get('operating_system'))
        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 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError('Required property \'resource_type\' not present in Volume JSON')
        if 'source_image' in _dict:
            args['source_image'] = ImageReference.from_dict(_dict.get('source_image'))
        if 'source_snapshot' in _dict:
            args['source_snapshot'] = SnapshotReference.from_dict(_dict.get('source_snapshot'))
        if 'status' in _dict:
            args['status'] = _dict.get('status')
        else:
            raise ValueError('Required property \'status\' not present in Volume JSON')
        if 'status_reasons' in _dict:
            args['status_reasons'] = [VolumeStatusReason.from_dict(v) for v in _dict.get('status_reasons')]
        else:
            raise ValueError('Required property \'status_reasons\' not present in Volume JSON')
        if 'user_tags' in _dict:
            args['user_tags'] = _dict.get('user_tags')
        else:
            raise ValueError('Required property \'user_tags\' not present in Volume JSON')
        if 'volume_attachments' in _dict:
            args['volume_attachments'] = [VolumeAttachmentReferenceVolumeContext.from_dict(v) for v 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, 'active') and self.active is not None:
            _dict['active'] = self.active
        if hasattr(self, 'attachment_state') and self.attachment_state is not None:
            _dict['attachment_state'] = self.attachment_state
        if hasattr(self, 'bandwidth') and self.bandwidth is not None:
            _dict['bandwidth'] = self.bandwidth
        if hasattr(self, 'busy') and self.busy is not None:
            _dict['busy'] = self.busy
        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:
            if isinstance(self.encryption_key, dict):
                _dict['encryption_key'] = self.encryption_key
            else:
                _dict['encryption_key'] = self.encryption_key.to_dict()
        if hasattr(self, 'health_reasons') and self.health_reasons is not None:
            health_reasons_list = []
            for v in self.health_reasons:
                if isinstance(v, dict):
                    health_reasons_list.append(v)
                else:
                    health_reasons_list.append(v.to_dict())
            _dict['health_reasons'] = health_reasons_list
        if hasattr(self, 'health_state') and self.health_state is not None:
            _dict['health_state'] = self.health_state
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, '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, '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()
        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, 'resource_type') and self.resource_type is not None:
            _dict['resource_type'] = self.resource_type
        if hasattr(self, 'source_image') and self.source_image is not None:
            if isinstance(self.source_image, dict):
                _dict['source_image'] = self.source_image
            else:
                _dict['source_image'] = self.source_image.to_dict()
        if hasattr(self, 'source_snapshot') and self.source_snapshot is not None:
            if isinstance(self.source_snapshot, dict):
                _dict['source_snapshot'] = self.source_snapshot
            else:
                _dict['source_snapshot'] = self.source_snapshot.to_dict()
        if hasattr(self, 'status') and self.status is not None:
            _dict['status'] = self.status
        if hasattr(self, 'status_reasons') and self.status_reasons is not None:
            status_reasons_list = []
            for v in self.status_reasons:
                if isinstance(v, dict):
                    status_reasons_list.append(v)
                else:
                    status_reasons_list.append(v.to_dict())
            _dict['status_reasons'] = status_reasons_list
        if hasattr(self, 'user_tags') and self.user_tags is not None:
            _dict['user_tags'] = self.user_tags
        if hasattr(self, 'volume_attachments') and self.volume_attachments is not None:
            volume_attachments_list = []
            for v in self.volume_attachments:
                if isinstance(v, dict):
                    volume_attachments_list.append(v)
                else:
                    volume_attachments_list.append(v.to_dict())
            _dict['volume_attachments'] = volume_attachments_list
        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 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 AttachmentStateEnum(str, Enum):
        """
        The attachment state of the volume
        - `unattached`: Not attached to any virtual server instances
        - `attached`: Attached to a virtual server instance (even if the instance is
        stopped)
        - `unusable`: Not able to be attached to any virtual server instances.
        """

        ATTACHED = 'attached'
        UNATTACHED = 'unattached'
        UNUSABLE = 'unusable'


    class EncryptionEnum(str, Enum):
        """
        The type of encryption used on the volume.
        """

        PROVIDER_MANAGED = 'provider_managed'
        USER_MANAGED = 'user_managed'


    class HealthStateEnum(str, Enum):
        """
        The health of this resource.
        - `ok`: No abnormal behavior detected
        - `degraded`: Experiencing compromised performance, capacity, or connectivity
        - `faulted`: Completely unreachable, inoperative, or otherwise entirely
        incapacitated
        - `inapplicable`: The health state does not apply because of the current lifecycle
        state. A resource with a lifecycle state of `failed` or `deleting` will have a
        health state of `inapplicable`. A `pending` resource may also have this state.
        """

        DEGRADED = 'degraded'
        FAULTED = 'faulted'
        INAPPLICABLE = 'inapplicable'
        OK = 'ok'


    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        VOLUME = 'volume'


    class StatusEnum(str, Enum):
        """
        The status of the volume.
        The enumerated values for this property will expand in the future. When processing
        this property, check for and log unknown values. Optionally halt processing and
        surface the error, or bypass the volume on which the unexpected property value was
        encountered.
        """

        AVAILABLE = 'available'
        FAILED = 'failed'
        PENDING = 'pending'
        PENDING_DELETION = 'pending_deletion'
        UNUSABLE = 'unusable'
        UPDATING = 'updating'



class VolumeAttachment:
    """
    VolumeAttachment.

    :attr int bandwidth: The maximum bandwidth (in megabits per second) for the
          volume when attached to this instance. This may be lower than the volume
          bandwidth depending on the configuration of the instance.
    :attr datetime created_at: The date and time that the volume was attached.
    :attr bool delete_volume_on_instance_delete: Indicates whether deleting the
          instance will also delete the attached volume.
    :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 name for this volume attachment. The name is unique across
          all volume attachments on the instance.
    :attr str status: The status of this volume attachment.
    :attr str type: The type of volume attachment.
    :attr VolumeReferenceVolumeAttachmentContext volume: (optional) The attached
          volume.
          This property will be absent if the volume has not yet been provisioned.
    """

    def __init__(
        self,
        bandwidth: int,
        created_at: datetime,
        delete_volume_on_instance_delete: bool,
        href: str,
        id: str,
        name: str,
        status: str,
        type: str,
        *,
        device: 'VolumeAttachmentDevice' = None,
        volume: 'VolumeReferenceVolumeAttachmentContext' = None,
    ) -> None:
        """
        Initialize a VolumeAttachment object.

        :param int bandwidth: The maximum bandwidth (in megabits per second) for
               the volume when attached to this instance. This may be lower than the
               volume bandwidth depending on the configuration of the instance.
        :param datetime created_at: The date and time that the volume was attached.
        :param bool delete_volume_on_instance_delete: Indicates whether deleting
               the instance will also delete the attached volume.
        :param str href: The URL for this volume attachment.
        :param str id: The unique identifier for this volume attachment.
        :param str name: The name for this volume attachment. The name is unique
               across all volume attachments on the instance.
        :param str status: The status of 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`.
        :param VolumeReferenceVolumeAttachmentContext volume: (optional) The
               attached volume.
               This property will be absent if the volume has not yet been provisioned.
        """
        self.bandwidth = bandwidth
        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 'bandwidth' in _dict:
            args['bandwidth'] = _dict.get('bandwidth')
        else:
            raise ValueError('Required property \'bandwidth\' not present in VolumeAttachment JSON')
        if 'created_at' in _dict:
            args['created_at'] = string_to_datetime(_dict.get('created_at'))
        else:
            raise ValueError('Required property \'created_at\' not present in VolumeAttachment JSON')
        if 'delete_volume_on_instance_delete' in _dict:
            args['delete_volume_on_instance_delete'] = _dict.get('delete_volume_on_instance_delete')
        else:
            raise ValueError('Required property \'delete_volume_on_instance_delete\' not present in VolumeAttachment JSON')
        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'] = VolumeReferenceVolumeAttachmentContext.from_dict(_dict.get('volume'))
        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, 'bandwidth') and self.bandwidth is not None:
            _dict['bandwidth'] = self.bandwidth
        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:
            if isinstance(self.device, dict):
                _dict['device'] = self.device
            else:
                _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:
            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 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(v) for v 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:
            volume_attachments_list = []
            for v in self.volume_attachments:
                if isinstance(v, dict):
                    volume_attachments_list.append(v)
                else:
                    volume_attachments_list.append(v.to_dict())
            _dict['volume_attachments'] = volume_attachments_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 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) Indicates whether
          deleting the instance will also delete the attached volume.
    :attr str name: (optional) The name for this volume attachment. The name must
          not be used by another volume attachment on the instance.
    """

    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) Indicates whether
               deleting the instance will also delete the attached volume.
        :param str name: (optional) The name for this volume attachment. The name
               must not be used by another volume attachment on the instance.
        """
        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 VolumeAttachmentPrototype:
    """
    VolumeAttachmentPrototype.

    :attr bool delete_volume_on_instance_delete: (optional) Indicates whether
          deleting the instance will also delete the attached volume.
    :attr str name: (optional) The name for this volume attachment. The name must
          not be used by another volume attachment on the instance. If unspecified, the
          name will be a hyphenated list of randomly-selected words.
    :attr VolumeAttachmentPrototypeVolume volume: An existing volume to attach to
          the instance, or a prototype object for a new volume.
    """

    def __init__(
        self,
        volume: 'VolumeAttachmentPrototypeVolume',
        *,
        delete_volume_on_instance_delete: bool = None,
        name: str = None,
    ) -> None:
        """
        Initialize a VolumeAttachmentPrototype object.

        :param VolumeAttachmentPrototypeVolume volume: An existing volume to attach
               to the instance, or a prototype object for a new volume.
        :param bool delete_volume_on_instance_delete: (optional) Indicates whether
               deleting the instance will also delete the attached volume.
        :param str name: (optional) The name for this volume attachment. The name
               must not be used by another volume attachment on the instance. If
               unspecified, the name will be a hyphenated list of randomly-selected words.
        """
        self.delete_volume_on_instance_delete = delete_volume_on_instance_delete
        self.name = name
        self.volume = volume

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VolumeAttachmentPrototype':
        """Initialize a VolumeAttachmentPrototype 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 VolumeAttachmentPrototype JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VolumeAttachmentPrototype object from 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 VolumeAttachmentPrototype object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VolumeAttachmentPrototype') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VolumeAttachmentPrototype') -> 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) Indicates whether
          deleting the instance will also delete the attached volume.
    :attr str name: (optional) The name for this volume attachment. The name must
          not be used by another volume attachment on the instance. If unspecified, the
          name will be a hyphenated list of randomly-selected words.
    :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) Indicates whether
               deleting the instance will also delete the attached volume.
        :param str name: (optional) The name for this volume attachment. The name
               must not be used by another volume attachment on the instance. If
               unspecified, the name will be a hyphenated list of randomly-selected words.
        """
        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:
            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 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 VolumeAttachmentPrototypeInstanceBySourceSnapshotContext:
    """
    VolumeAttachmentPrototypeInstanceBySourceSnapshotContext.

    :attr bool delete_volume_on_instance_delete: (optional) Indicates whether
          deleting the instance will also delete the attached volume.
    :attr str name: (optional) The name for this volume attachment. The name must
          not be used by another volume attachment on the instance. If unspecified, the
          name will be a hyphenated list of randomly-selected words.
    :attr VolumePrototypeInstanceBySourceSnapshotContext volume: A prototype object
          for a new volume from a snapshot.
    """

    def __init__(
        self,
        volume: 'VolumePrototypeInstanceBySourceSnapshotContext',
        *,
        delete_volume_on_instance_delete: bool = None,
        name: str = None,
    ) -> None:
        """
        Initialize a VolumeAttachmentPrototypeInstanceBySourceSnapshotContext object.

        :param VolumePrototypeInstanceBySourceSnapshotContext volume: A prototype
               object for a new volume from a snapshot.
        :param bool delete_volume_on_instance_delete: (optional) Indicates whether
               deleting the instance will also delete the attached volume.
        :param str name: (optional) The name for this volume attachment. The name
               must not be used by another volume attachment on the instance. If
               unspecified, the name will be a hyphenated list of randomly-selected words.
        """
        self.delete_volume_on_instance_delete = delete_volume_on_instance_delete
        self.name = name
        self.volume = volume

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VolumeAttachmentPrototypeInstanceBySourceSnapshotContext':
        """Initialize a VolumeAttachmentPrototypeInstanceBySourceSnapshotContext 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'] = VolumePrototypeInstanceBySourceSnapshotContext.from_dict(_dict.get('volume'))
        else:
            raise ValueError('Required property \'volume\' not present in VolumeAttachmentPrototypeInstanceBySourceSnapshotContext JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VolumeAttachmentPrototypeInstanceBySourceSnapshotContext object from 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 VolumeAttachmentPrototypeInstanceBySourceSnapshotContext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VolumeAttachmentPrototypeInstanceBySourceSnapshotContext') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VolumeAttachmentPrototypeInstanceBySourceSnapshotContext') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VolumeAttachmentPrototypeInstanceByVolumeContext:
    """
    VolumeAttachmentPrototypeInstanceByVolumeContext.

    :attr bool delete_volume_on_instance_delete: (optional) Indicates whether
          deleting the instance will also delete the attached volume.
    :attr str name: (optional) The name for this volume attachment. The name must
          not be used by another volume attachment on the instance. If unspecified, the
          name will be a hyphenated list of randomly-selected words.
    :attr VolumeIdentity volume: An existing volume to attach.
    """

    def __init__(
        self,
        volume: 'VolumeIdentity',
        *,
        delete_volume_on_instance_delete: bool = None,
        name: str = None,
    ) -> None:
        """
        Initialize a VolumeAttachmentPrototypeInstanceByVolumeContext object.

        :param VolumeIdentity volume: An existing volume to attach.
        :param bool delete_volume_on_instance_delete: (optional) Indicates whether
               deleting the instance will also delete the attached volume.
        :param str name: (optional) The name for this volume attachment. The name
               must not be used by another volume attachment on the instance. If
               unspecified, the name will be a hyphenated list of randomly-selected words.
        """
        self.delete_volume_on_instance_delete = delete_volume_on_instance_delete
        self.name = name
        self.volume = volume

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VolumeAttachmentPrototypeInstanceByVolumeContext':
        """Initialize a VolumeAttachmentPrototypeInstanceByVolumeContext 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 VolumeAttachmentPrototypeInstanceByVolumeContext JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VolumeAttachmentPrototypeInstanceByVolumeContext object from 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 VolumeAttachmentPrototypeInstanceByVolumeContext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VolumeAttachmentPrototypeInstanceByVolumeContext') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VolumeAttachmentPrototypeInstanceByVolumeContext') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VolumeAttachmentPrototypeVolume:
    """
    An existing volume to attach to the instance, or a prototype object for a new volume.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a VolumeAttachmentPrototypeVolume object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['VolumeAttachmentPrototypeVolumeVolumeIdentity', 'VolumeAttachmentPrototypeVolumeVolumePrototypeInstanceContext'])
        )
        raise Exception(msg)


class VolumeAttachmentReferenceInstanceContext:
    """
    VolumeAttachmentReferenceInstanceContext.

    :attr VolumeAttachmentReferenceInstanceContextDeleted deleted: (optional) If
          present, this property indicates the referenced resource has been deleted, and
          provides
          some supplementary information.
    :attr VolumeAttachmentDevice device: (optional) Information about how the volume
          is exposed to the instance operating system.
          This property may be absent if the volume attachment's `status` is not
          `attached`.
    :attr str href: The URL for this volume attachment.
    :attr str id: The unique identifier for this volume attachment.
    :attr str name: The name for this volume attachment. The name is unique across
          all volume attachments on the instance.
    :attr VolumeReferenceVolumeAttachmentContext volume: (optional) The attached
          volume.
          This property will be absent if the volume has not yet been provisioned.
    """

    def __init__(
        self,
        href: str,
        id: str,
        name: str,
        *,
        deleted: 'VolumeAttachmentReferenceInstanceContextDeleted' = None,
        device: 'VolumeAttachmentDevice' = None,
        volume: 'VolumeReferenceVolumeAttachmentContext' = 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 name for this volume attachment. The name is unique
               across all volume attachments on the instance.
        :param VolumeAttachmentReferenceInstanceContextDeleted deleted: (optional)
               If present, this property indicates the referenced resource has been
               deleted, and provides
               some supplementary information.
        :param VolumeAttachmentDevice device: (optional) Information about how the
               volume is exposed to the instance operating system.
               This property may be absent if the volume attachment's `status` is not
               `attached`.
        :param VolumeReferenceVolumeAttachmentContext volume: (optional) The
               attached volume.
               This property will be absent if the volume has not yet been provisioned.
        """
        self.deleted = deleted
        self.device = device
        self.href = href
        self.id = id
        self.name = name
        self.volume = volume

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VolumeAttachmentReferenceInstanceContext':
        """Initialize a VolumeAttachmentReferenceInstanceContext object from a json dictionary."""
        args = {}
        if 'deleted' in _dict:
            args['deleted'] = VolumeAttachmentReferenceInstanceContextDeleted.from_dict(_dict.get('deleted'))
        if 'device' in _dict:
            args['device'] = VolumeAttachmentDevice.from_dict(_dict.get('device'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in VolumeAttachmentReferenceInstanceContext JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in VolumeAttachmentReferenceInstanceContext JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in VolumeAttachmentReferenceInstanceContext JSON')
        if 'volume' in _dict:
            args['volume'] = VolumeReferenceVolumeAttachmentContext.from_dict(_dict.get('volume'))
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VolumeAttachmentReferenceInstanceContext object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'deleted') and self.deleted is not None:
            if isinstance(self.deleted, dict):
                _dict['deleted'] = self.deleted
            else:
                _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'device') and self.device is not None:
            if isinstance(self.device, dict):
                _dict['device'] = self.device
            else:
                _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:
            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 VolumeAttachmentReferenceInstanceContext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VolumeAttachmentReferenceInstanceContext') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VolumeAttachmentReferenceInstanceContext') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VolumeAttachmentReferenceInstanceContextDeleted:
    """
    If present, this property indicates the referenced resource has been deleted, and
    provides some supplementary information.

    :attr str more_info: Link to documentation about deleted resources.
    """

    def __init__(
        self,
        more_info: str,
    ) -> None:
        """
        Initialize a VolumeAttachmentReferenceInstanceContextDeleted object.

        :param str more_info: Link to documentation about deleted resources.
        """
        self.more_info = more_info

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VolumeAttachmentReferenceInstanceContextDeleted':
        """Initialize a VolumeAttachmentReferenceInstanceContextDeleted object from a json dictionary."""
        args = {}
        if 'more_info' in _dict:
            args['more_info'] = _dict.get('more_info')
        else:
            raise ValueError('Required property \'more_info\' not present in VolumeAttachmentReferenceInstanceContextDeleted JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VolumeAttachmentReferenceInstanceContextDeleted object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'more_info') and self.more_info is not None:
            _dict['more_info'] = self.more_info
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VolumeAttachmentReferenceInstanceContextDeleted object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VolumeAttachmentReferenceInstanceContextDeleted') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VolumeAttachmentReferenceInstanceContextDeleted') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VolumeAttachmentReferenceVolumeContext:
    """
    VolumeAttachmentReferenceVolumeContext.

    :attr bool delete_volume_on_instance_delete: Indicates whether deleting the
          instance will also delete the attached volume.
    :attr VolumeAttachmentReferenceVolumeContextDeleted deleted: (optional) If
          present, this property indicates the referenced resource has been deleted, and
          provides
          some supplementary information.
    :attr VolumeAttachmentDevice device: (optional) Information about how the volume
          is exposed to the instance operating system.
          This property may be absent if the volume attachment's `status` is not
          `attached`.
    :attr str href: The URL for this volume attachment.
    :attr str id: The unique identifier for this volume attachment.
    :attr InstanceReference instance: The attached instance.
    :attr str name: The name for this volume attachment. The name is unique across
          all volume attachments on the instance.
    :attr str type: The type of volume attachment.
    """

    def __init__(
        self,
        delete_volume_on_instance_delete: bool,
        href: str,
        id: str,
        instance: 'InstanceReference',
        name: str,
        type: str,
        *,
        deleted: 'VolumeAttachmentReferenceVolumeContextDeleted' = None,
        device: 'VolumeAttachmentDevice' = None,
    ) -> None:
        """
        Initialize a VolumeAttachmentReferenceVolumeContext object.

        :param bool delete_volume_on_instance_delete: Indicates whether deleting
               the instance will also delete the attached volume.
        :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 name for this volume attachment. The name is unique
               across all volume attachments on the instance.
        :param str type: The type of volume attachment.
        :param VolumeAttachmentReferenceVolumeContextDeleted deleted: (optional) If
               present, this property indicates the referenced resource has been deleted,
               and provides
               some supplementary information.
        :param VolumeAttachmentDevice device: (optional) Information about how the
               volume is exposed to the instance operating system.
               This property may be absent if the volume attachment's `status` is not
               `attached`.
        """
        self.delete_volume_on_instance_delete = delete_volume_on_instance_delete
        self.deleted = deleted
        self.device = device
        self.href = href
        self.id = id
        self.instance = instance
        self.name = name
        self.type = type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VolumeAttachmentReferenceVolumeContext':
        """Initialize a VolumeAttachmentReferenceVolumeContext object from a json dictionary."""
        args = {}
        if 'delete_volume_on_instance_delete' in _dict:
            args['delete_volume_on_instance_delete'] = _dict.get('delete_volume_on_instance_delete')
        else:
            raise ValueError('Required property \'delete_volume_on_instance_delete\' not present in VolumeAttachmentReferenceVolumeContext JSON')
        if 'deleted' in _dict:
            args['deleted'] = VolumeAttachmentReferenceVolumeContextDeleted.from_dict(_dict.get('deleted'))
        if 'device' in _dict:
            args['device'] = VolumeAttachmentDevice.from_dict(_dict.get('device'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in VolumeAttachmentReferenceVolumeContext JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in VolumeAttachmentReferenceVolumeContext JSON')
        if 'instance' in _dict:
            args['instance'] = InstanceReference.from_dict(_dict.get('instance'))
        else:
            raise ValueError('Required property \'instance\' not present in VolumeAttachmentReferenceVolumeContext JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in VolumeAttachmentReferenceVolumeContext JSON')
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in VolumeAttachmentReferenceVolumeContext JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VolumeAttachmentReferenceVolumeContext object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'delete_volume_on_instance_delete') and self.delete_volume_on_instance_delete is not None:
            _dict['delete_volume_on_instance_delete'] = self.delete_volume_on_instance_delete
        if hasattr(self, 'deleted') and self.deleted is not None:
            if isinstance(self.deleted, dict):
                _dict['deleted'] = self.deleted
            else:
                _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'device') and self.device is not None:
            if isinstance(self.device, dict):
                _dict['device'] = self.device
            else:
                _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:
            if isinstance(self.instance, dict):
                _dict['instance'] = self.instance
            else:
                _dict['instance'] = self.instance.to_dict()
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'type') and self.type is not None:
            _dict['type'] = self.type
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VolumeAttachmentReferenceVolumeContext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VolumeAttachmentReferenceVolumeContext') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VolumeAttachmentReferenceVolumeContext') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class TypeEnum(str, Enum):
        """
        The type of volume attachment.
        """

        BOOT = 'boot'
        DATA = 'data'



class VolumeAttachmentReferenceVolumeContextDeleted:
    """
    If present, this property indicates the referenced resource has been deleted, and
    provides some supplementary information.

    :attr str more_info: Link to documentation about deleted resources.
    """

    def __init__(
        self,
        more_info: str,
    ) -> None:
        """
        Initialize a VolumeAttachmentReferenceVolumeContextDeleted object.

        :param str more_info: Link to documentation about deleted resources.
        """
        self.more_info = more_info

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VolumeAttachmentReferenceVolumeContextDeleted':
        """Initialize a VolumeAttachmentReferenceVolumeContextDeleted object from a json dictionary."""
        args = {}
        if 'more_info' in _dict:
            args['more_info'] = _dict.get('more_info')
        else:
            raise ValueError('Required property \'more_info\' not present in VolumeAttachmentReferenceVolumeContextDeleted JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VolumeAttachmentReferenceVolumeContextDeleted object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'more_info') and self.more_info is not None:
            _dict['more_info'] = self.more_info
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VolumeAttachmentReferenceVolumeContextDeleted object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VolumeAttachmentReferenceVolumeContextDeleted') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VolumeAttachmentReferenceVolumeContextDeleted') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class 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 int total_count: The total number of resources across all pages.
    :attr List[Volume] volumes: Collection of volumes.
    """

    def __init__(
        self,
        first: 'VolumeCollectionFirst',
        limit: int,
        total_count: 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 int total_count: The total number of resources across all pages.
        :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.total_count = total_count
        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 'total_count' in _dict:
            args['total_count'] = _dict.get('total_count')
        else:
            raise ValueError('Required property \'total_count\' not present in VolumeCollection JSON')
        if 'volumes' in _dict:
            args['volumes'] = [Volume.from_dict(v) for v 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:
            if isinstance(self.first, dict):
                _dict['first'] = self.first
            else:
                _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:
            if isinstance(self.next, dict):
                _dict['next'] = self.next
            else:
                _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, 'volumes') and self.volumes is not None:
            volumes_list = []
            for v in self.volumes:
                if isinstance(v, dict):
                    volumes_list.append(v)
                else:
                    volumes_list.append(v.to_dict())
            _dict['volumes'] = volumes_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 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 VolumeHealthReason:
    """
    VolumeHealthReason.

    :attr str code: A snake case string succinctly identifying the reason for this
          health state.
    :attr str message: An explanation of the reason for this health state.
    :attr str more_info: (optional) Link to documentation about the reason for this
          health state.
    """

    def __init__(
        self,
        code: str,
        message: str,
        *,
        more_info: str = None,
    ) -> None:
        """
        Initialize a VolumeHealthReason object.

        :param str code: A snake case string succinctly identifying the reason for
               this health state.
        :param str message: An explanation of the reason for this health state.
        :param str more_info: (optional) Link to documentation about the reason for
               this health state.
        """
        self.code = code
        self.message = message
        self.more_info = more_info

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VolumeHealthReason':
        """Initialize a VolumeHealthReason object from a json dictionary."""
        args = {}
        if 'code' in _dict:
            args['code'] = _dict.get('code')
        else:
            raise ValueError('Required property \'code\' not present in VolumeHealthReason JSON')
        if 'message' in _dict:
            args['message'] = _dict.get('message')
        else:
            raise ValueError('Required property \'message\' not present in VolumeHealthReason JSON')
        if 'more_info' in _dict:
            args['more_info'] = _dict.get('more_info')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VolumeHealthReason object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'code') and self.code is not None:
            _dict['code'] = self.code
        if hasattr(self, 'message') and self.message is not None:
            _dict['message'] = self.message
        if hasattr(self, 'more_info') and self.more_info is not None:
            _dict['more_info'] = self.more_info
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VolumeHealthReason object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VolumeHealthReason') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VolumeHealthReason') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class CodeEnum(str, Enum):
        """
        A snake case string succinctly identifying the reason for this health state.
        """

        INITIALIZING_FROM_SNAPSHOT = 'initializing_from_snapshot'



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 int capacity: (optional) The capacity to use for the volume (in
          gigabytes). The volume must be attached to a running virtual server instance,
          and the specified value must not be less than the current capacity.
          Additionally, if the volume is attached as a boot volume, the maximum value is
          250 gigabytes.
          The minimum and maximum capacity limits for creating or updating volumes may
          expand in the future.
    :attr int iops: (optional) The maximum I/O operations per second (IOPS) to use
          for this volume. Applicable only to volumes using a profile `family` of
          `custom`. The volume must be attached as a data volume to a running virtual
          server instance.
    :attr str name: (optional) The name for this volume. The name must not be used
          by another volume in the region.
    :attr VolumeProfileIdentity profile: (optional) The profile to use for this
          volume. The requested profile must be in the same
          `family` as the current profile. The volume must be attached as a data volume to
          a running virtual server instance, and must have a `capacity` within the range
          supported by the specified profile.
    :attr List[str] user_tags: (optional) The [user
          tags](https://cloud.ibm.com/apidocs/tagging#types-of-tags) associated with this
          volume.
    """

    def __init__(
        self,
        *,
        capacity: int = None,
        iops: int = None,
        name: str = None,
        profile: 'VolumeProfileIdentity' = None,
        user_tags: List[str] = None,
    ) -> None:
        """
        Initialize a VolumePatch object.

        :param int capacity: (optional) The capacity to use for the volume (in
               gigabytes). The volume must be attached to a running virtual server
               instance, and the specified value must not be less than the current
               capacity. Additionally, if the volume is attached as a boot volume, the
               maximum value is 250 gigabytes.
               The minimum and maximum capacity limits for creating or updating volumes
               may expand in the future.
        :param int iops: (optional) The maximum I/O operations per second (IOPS) to
               use for this volume. Applicable only to volumes using a profile `family` of
               `custom`. The volume must be attached as a data volume to a running virtual
               server instance.
        :param str name: (optional) The name for this volume. The name must not be
               used by another volume in the region.
        :param VolumeProfileIdentity profile: (optional) The profile to use for
               this volume. The requested profile must be in the same
               `family` as the current profile. The volume must be attached as a data
               volume to
               a running virtual server instance, and must have a `capacity` within the
               range
               supported by the specified profile.
        :param List[str] user_tags: (optional) The [user
               tags](https://cloud.ibm.com/apidocs/tagging#types-of-tags) associated with
               this volume.
        """
        self.capacity = capacity
        self.iops = iops
        self.name = name
        self.profile = profile
        self.user_tags = user_tags

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VolumePatch':
        """Initialize a VolumePatch object from a json dictionary."""
        args = {}
        if 'capacity' in _dict:
            args['capacity'] = _dict.get('capacity')
        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')
        if 'user_tags' in _dict:
            args['user_tags'] = _dict.get('user_tags')
        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, 'capacity') and self.capacity is not None:
            _dict['capacity'] = self.capacity
        if hasattr(self, 'iops') and self.iops is not None:
            _dict['iops'] = self.iops
        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, 'user_tags') and self.user_tags is not None:
            _dict['user_tags'] = self.user_tags
        return _dict

    def _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: The product family this volume profile belongs to.
          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 profile on which the
          unexpected property value was encountered.
    :attr str href: The URL for this volume profile.
    :attr str name: The globally unique name for this volume profile.
    """

    def __init__(
        self,
        family: str,
        href: str,
        name: str,
    ) -> None:
        """
        Initialize a VolumeProfile object.

        :param str family: The product family this volume profile belongs to.
               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 profile on which the
               unexpected property value was encountered.
        :param str href: The URL for this volume profile.
        :param str name: The globally unique name for this volume profile.
        """
        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')
        else:
            raise ValueError('Required property \'family\' not present in VolumeProfile JSON')
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in VolumeProfile JSON')
        if '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 FamilyEnum(str, Enum):
        """
        The product family this volume profile belongs to.
        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 profile on which the unexpected property
        value was encountered.
        """

        CUSTOM = 'custom'
        TIERED = 'tiered'



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(v) for v 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:
            if isinstance(self.first, dict):
                _dict['first'] = self.first
            else:
                _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:
            if isinstance(self.next, dict):
                _dict['next'] = self.next
            else:
                _dict['next'] = self.next.to_dict()
        if hasattr(self, 'profiles') and self.profiles is not None:
            profiles_list = []
            for v in self.profiles:
                if isinstance(v, dict):
                    profiles_list.append(v)
                else:
                    profiles_list.append(v.to_dict())
            _dict['profiles'] = profiles_list
        if hasattr(self, 'total_count') and self.total_count is not None:
            _dict['total_count'] = self.total_count
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VolumeProfileCollection object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VolumeProfileCollection') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VolumeProfileCollection') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VolumeProfileCollectionFirst:
    """
    A link to the first page of resources.

    :attr str href: The URL for a page of resources.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a VolumeProfileCollectionFirst object.

        :param str href: The URL for a page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VolumeProfileCollectionFirst':
        """Initialize a VolumeProfileCollectionFirst object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in VolumeProfileCollectionFirst JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VolumeProfileCollectionFirst object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VolumeProfileCollectionFirst object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VolumeProfileCollectionFirst') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VolumeProfileCollectionFirst') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VolumeProfileCollectionNext:
    """
    A link to the next page of resources. This property is present for all pages except
    the last page.

    :attr str href: The URL for a page of resources.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a VolumeProfileCollectionNext object.

        :param str href: The URL for a page of resources.
        """
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VolumeProfileCollectionNext':
        """Initialize a VolumeProfileCollectionNext object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in VolumeProfileCollectionNext JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VolumeProfileCollectionNext object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VolumeProfileCollectionNext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VolumeProfileCollectionNext') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VolumeProfileCollectionNext') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VolumeProfileIdentity:
    """
    Identifies a volume profile by a unique property.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a VolumeProfileIdentity object.

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['VolumeProfileIdentityByName', 'VolumeProfileIdentityByHref'])
        )
        raise Exception(msg)


class VolumeProfileReference:
    """
    VolumeProfileReference.

    :attr str href: The URL for this volume profile.
    :attr str name: The globally unique name for this volume profile.
    """

    def __init__(
        self,
        href: str,
        name: str,
    ) -> None:
        """
        Initialize a VolumeProfileReference object.

        :param str href: The URL for this volume profile.
        :param str name: The globally unique name for this volume profile.
        """
        self.href = href
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VolumeProfileReference':
        """Initialize a VolumeProfileReference object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in VolumeProfileReference JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in VolumeProfileReference JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VolumeProfileReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VolumeProfileReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VolumeProfileReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VolumeProfileReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VolumePrototype:
    """
    VolumePrototype.

    :attr int iops: (optional) The maximum I/O operations per second (IOPS) to use
          for this volume. Applicable only to volumes using a profile `family` of
          `custom`.
    :attr str name: (optional) The name for this volume. The name must not be used
          by another volume in the region. If unspecified, the name will be a hyphenated
          list of randomly-selected words.
    :attr VolumeProfileIdentity profile: The
          [profile](https://cloud.ibm.com/docs/vpc?topic=vpc-block-storage-profiles) 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) will be
          used.
    :attr List[str] user_tags: (optional) The [user
          tags](https://cloud.ibm.com/apidocs/tagging#types-of-tags) associated with this
          volume.
    :attr ZoneIdentity zone: The zone this volume will reside in.
    """

    def __init__(
        self,
        profile: 'VolumeProfileIdentity',
        zone: 'ZoneIdentity',
        *,
        iops: int = None,
        name: str = None,
        resource_group: 'ResourceGroupIdentity' = None,
        user_tags: List[str] = None,
    ) -> None:
        """
        Initialize a VolumePrototype object.

        :param VolumeProfileIdentity profile: The
               [profile](https://cloud.ibm.com/docs/vpc?topic=vpc-block-storage-profiles)
               to
               use for this volume.
        :param ZoneIdentity zone: The zone this volume will reside in.
        :param int iops: (optional) The maximum I/O operations per second (IOPS) to
               use for this volume. Applicable only to volumes using a profile `family` of
               `custom`.
        :param str name: (optional) The name for this volume. The name must not be
               used by another volume in the region. 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) will be
               used.
        :param List[str] user_tags: (optional) The [user
               tags](https://cloud.ibm.com/apidocs/tagging#types-of-tags) associated with
               this volume.
        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['VolumePrototypeVolumeByCapacity', 'VolumePrototypeVolumeBySourceSnapshot'])
        )
        raise Exception(msg)


class VolumePrototypeInstanceByImageContext:
    """
    VolumePrototypeInstanceByImageContext.

    :attr int capacity: (optional) The capacity to use for the volume (in
          gigabytes). Must be at least the image's
          `minimum_provisioned_size`. The maximum value may increase in the future.
          If unspecified, the capacity will be the image's `minimum_provisioned_size`.
    :attr EncryptionKeyIdentity encryption_key: (optional) The root key to use to
          wrap the data encryption key for the volume.
          If unspecified, the `encryption` type for the volume will be `provider_managed`.
    :attr int iops: (optional) The maximum I/O operations per second (IOPS) to use
          for this volume. Applicable only to volumes using a profile `family` of
          `custom`.
    :attr str name: (optional) The name for this volume. The name must not be used
          by another volume in the region. If unspecified, the name will be a hyphenated
          list of randomly-selected words.
    :attr VolumeProfileIdentity profile: The
          [profile](https://cloud.ibm.com/docs/vpc?topic=vpc-block-storage-profiles) to
          use for this volume.
    :attr ResourceGroupIdentity resource_group: (optional) The resource group to use
          for this volume. If unspecified, the instance's resource
          group will be used.
    :attr List[str] user_tags: (optional) The [user
          tags](https://cloud.ibm.com/apidocs/tagging#types-of-tags) associated with this
          volume.
    """

    def __init__(
        self,
        profile: 'VolumeProfileIdentity',
        *,
        capacity: int = None,
        encryption_key: 'EncryptionKeyIdentity' = None,
        iops: int = None,
        name: str = None,
        resource_group: 'ResourceGroupIdentity' = None,
        user_tags: List[str] = None,
    ) -> None:
        """
        Initialize a VolumePrototypeInstanceByImageContext object.

        :param VolumeProfileIdentity profile: The
               [profile](https://cloud.ibm.com/docs/vpc?topic=vpc-block-storage-profiles)
               to
               use for this volume.
        :param int capacity: (optional) The capacity to use for the volume (in
               gigabytes). Must be at least the image's
               `minimum_provisioned_size`. The maximum value may increase in the future.
               If unspecified, the capacity will be the image's
               `minimum_provisioned_size`.
        :param EncryptionKeyIdentity encryption_key: (optional) The root key to use
               to wrap the data encryption key for the volume.
               If unspecified, the `encryption` type for the volume will be
               `provider_managed`.
        :param int iops: (optional) The maximum I/O operations per second (IOPS) to
               use for this volume. Applicable only to volumes using a profile `family` of
               `custom`.
        :param str name: (optional) The name for this volume. The name must not be
               used by another volume in the region. If unspecified, the name will be a
               hyphenated list of randomly-selected words.
        :param ResourceGroupIdentity resource_group: (optional) The resource group
               to use for this volume. If unspecified, the instance's resource
               group will be used.
        :param List[str] user_tags: (optional) The [user
               tags](https://cloud.ibm.com/apidocs/tagging#types-of-tags) associated with
               this volume.
        """
        self.capacity = capacity
        self.encryption_key = encryption_key
        self.iops = iops
        self.name = name
        self.profile = profile
        self.resource_group = resource_group
        self.user_tags = user_tags

    @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')
        if 'resource_group' in _dict:
            args['resource_group'] = _dict.get('resource_group')
        if 'user_tags' in _dict:
            args['user_tags'] = _dict.get('user_tags')
        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()
        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_tags') and self.user_tags is not None:
            _dict['user_tags'] = self.user_tags
        return _dict

    def _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 VolumePrototypeInstanceBySourceSnapshotContext:
    """
    VolumePrototypeInstanceBySourceSnapshotContext.

    :attr int capacity: (optional) The capacity to use for the volume (in
          gigabytes). Must be at least the snapshot's
          `minimum_capacity`. The maximum value may increase in the future.
          If unspecified, the capacity will be the source snapshot's `minimum_capacity`.
    :attr EncryptionKeyIdentity encryption_key: (optional) The root key to use to
          wrap the data encryption key for the volume.
          If unspecified, the `encryption` type for the volume will be `provider_managed`.
    :attr int iops: (optional) The maximum I/O operations per second (IOPS) to use
          for this volume. Applicable only to volumes using a profile `family` of
          `custom`.
    :attr str name: (optional) The name for this volume. The name must not be used
          by another volume in the region. If unspecified, the name will be a hyphenated
          list of randomly-selected words.
    :attr VolumeProfileIdentity profile: The
          [profile](https://cloud.ibm.com/docs/vpc?topic=vpc-block-storage-profiles) to
          use for this volume.
    :attr ResourceGroupIdentity resource_group: (optional) The resource group to use
          for this volume. If unspecified, the instance's resource
          group will be used.
    :attr SnapshotIdentity source_snapshot: The snapshot from which to clone the
          volume.
    :attr List[str] user_tags: (optional) The [user
          tags](https://cloud.ibm.com/apidocs/tagging#types-of-tags) associated with this
          volume.
    """

    def __init__(
        self,
        profile: 'VolumeProfileIdentity',
        source_snapshot: 'SnapshotIdentity',
        *,
        capacity: int = None,
        encryption_key: 'EncryptionKeyIdentity' = None,
        iops: int = None,
        name: str = None,
        resource_group: 'ResourceGroupIdentity' = None,
        user_tags: List[str] = None,
    ) -> None:
        """
        Initialize a VolumePrototypeInstanceBySourceSnapshotContext object.

        :param VolumeProfileIdentity profile: The
               [profile](https://cloud.ibm.com/docs/vpc?topic=vpc-block-storage-profiles)
               to
               use for this volume.
        :param SnapshotIdentity source_snapshot: The snapshot from which to clone
               the volume.
        :param int capacity: (optional) The capacity to use for the volume (in
               gigabytes). Must be at least the snapshot's
               `minimum_capacity`. The maximum value may increase in the future.
               If unspecified, the capacity will be the source snapshot's
               `minimum_capacity`.
        :param EncryptionKeyIdentity encryption_key: (optional) The root key to use
               to wrap the data encryption key for the volume.
               If unspecified, the `encryption` type for the volume will be
               `provider_managed`.
        :param int iops: (optional) The maximum I/O operations per second (IOPS) to
               use for this volume. Applicable only to volumes using a profile `family` of
               `custom`.
        :param str name: (optional) The name for this volume. The name must not be
               used by another volume in the region. If unspecified, the name will be a
               hyphenated list of randomly-selected words.
        :param ResourceGroupIdentity resource_group: (optional) The resource group
               to use for this volume. If unspecified, the instance's resource
               group will be used.
        :param List[str] user_tags: (optional) The [user
               tags](https://cloud.ibm.com/apidocs/tagging#types-of-tags) associated with
               this volume.
        """
        self.capacity = capacity
        self.encryption_key = encryption_key
        self.iops = iops
        self.name = name
        self.profile = profile
        self.resource_group = resource_group
        self.source_snapshot = source_snapshot
        self.user_tags = user_tags

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VolumePrototypeInstanceBySourceSnapshotContext':
        """Initialize a VolumePrototypeInstanceBySourceSnapshotContext 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 VolumePrototypeInstanceBySourceSnapshotContext JSON')
        if 'resource_group' in _dict:
            args['resource_group'] = _dict.get('resource_group')
        if 'source_snapshot' in _dict:
            args['source_snapshot'] = _dict.get('source_snapshot')
        else:
            raise ValueError('Required property \'source_snapshot\' not present in VolumePrototypeInstanceBySourceSnapshotContext JSON')
        if 'user_tags' in _dict:
            args['user_tags'] = _dict.get('user_tags')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VolumePrototypeInstanceBySourceSnapshotContext object from 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()
        if hasattr(self, 'resource_group') and self.resource_group is not None:
            if isinstance(self.resource_group, dict):
                _dict['resource_group'] = self.resource_group
            else:
                _dict['resource_group'] = self.resource_group.to_dict()
        if hasattr(self, 'source_snapshot') and self.source_snapshot is not None:
            if isinstance(self.source_snapshot, dict):
                _dict['source_snapshot'] = self.source_snapshot
            else:
                _dict['source_snapshot'] = self.source_snapshot.to_dict()
        if hasattr(self, 'user_tags') and self.user_tags is not None:
            _dict['user_tags'] = self.user_tags
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VolumePrototypeInstanceBySourceSnapshotContext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VolumePrototypeInstanceBySourceSnapshotContext') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VolumePrototypeInstanceBySourceSnapshotContext') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VolumeReference:
    """
    VolumeReference.

    :attr str crn: The CRN for this volume.
    :attr VolumeReferenceDeleted deleted: (optional) If present, this property
          indicates the referenced resource has been deleted, and provides
          some supplementary information.
    :attr str href: The URL for this volume.
    :attr str id: The unique identifier for this volume.
    :attr str name: The name for this volume. The name is unique across all volumes
          in the region.
    :attr VolumeRemote remote: (optional) If present, this property indicates that
          the resource associated with this reference
          is remote and therefore may not be directly retrievable.
    :attr str resource_type: The resource type.
    """

    def __init__(
        self,
        crn: str,
        href: str,
        id: str,
        name: str,
        resource_type: str,
        *,
        deleted: 'VolumeReferenceDeleted' = None,
        remote: 'VolumeRemote' = None,
    ) -> None:
        """
        Initialize a VolumeReference object.

        :param str crn: The CRN for this volume.
        :param str href: The URL for this volume.
        :param str id: The unique identifier for this volume.
        :param str name: The name for this volume. The name is unique across all
               volumes in the region.
        :param str resource_type: The resource type.
        :param VolumeReferenceDeleted deleted: (optional) If present, this property
               indicates the referenced resource has been deleted, and provides
               some supplementary information.
        :param VolumeRemote remote: (optional) If present, this property indicates
               that the resource associated with this reference
               is remote and therefore may not be directly retrievable.
        """
        self.crn = crn
        self.deleted = deleted
        self.href = href
        self.id = id
        self.name = name
        self.remote = remote
        self.resource_type = resource_type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VolumeReference':
        """Initialize a VolumeReference object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError('Required property \'crn\' not present in VolumeReference JSON')
        if 'deleted' in _dict:
            args['deleted'] = VolumeReferenceDeleted.from_dict(_dict.get('deleted'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in VolumeReference JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in VolumeReference JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in VolumeReference JSON')
        if 'remote' in _dict:
            args['remote'] = VolumeRemote.from_dict(_dict.get('remote'))
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError('Required property \'resource_type\' not present in VolumeReference JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VolumeReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'deleted') and self.deleted is not None:
            if isinstance(self.deleted, dict):
                _dict['deleted'] = self.deleted
            else:
                _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, '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, '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 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 ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        VOLUME = 'volume'



class VolumeReferenceDeleted:
    """
    If present, this property indicates the referenced resource has been deleted, and
    provides some supplementary information.

    :attr str more_info: Link to documentation about deleted resources.
    """

    def __init__(
        self,
        more_info: str,
    ) -> None:
        """
        Initialize a VolumeReferenceDeleted object.

        :param str more_info: Link to documentation about deleted resources.
        """
        self.more_info = more_info

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VolumeReferenceDeleted':
        """Initialize a VolumeReferenceDeleted object from a json dictionary."""
        args = {}
        if 'more_info' in _dict:
            args['more_info'] = _dict.get('more_info')
        else:
            raise ValueError('Required property \'more_info\' not present in VolumeReferenceDeleted JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VolumeReferenceDeleted object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'more_info') and self.more_info is not None:
            _dict['more_info'] = self.more_info
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VolumeReferenceDeleted object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VolumeReferenceDeleted') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VolumeReferenceDeleted') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VolumeReferenceVolumeAttachmentContext:
    """
    VolumeReferenceVolumeAttachmentContext.

    :attr str crn: The CRN for this volume.
    :attr VolumeReferenceVolumeAttachmentContextDeleted deleted: (optional) If
          present, this property indicates the referenced resource has been deleted, and
          provides
          some supplementary information.
    :attr str href: The URL for this volume.
    :attr str id: The unique identifier for this volume.
    :attr str name: The name for this volume. The name is unique across all volumes
          in the region.
    :attr str resource_type: The resource type.
    """

    def __init__(
        self,
        crn: str,
        href: str,
        id: str,
        name: str,
        resource_type: str,
        *,
        deleted: 'VolumeReferenceVolumeAttachmentContextDeleted' = None,
    ) -> None:
        """
        Initialize a VolumeReferenceVolumeAttachmentContext 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 name for this volume. The name is unique across all
               volumes in the region.
        :param str resource_type: The resource type.
        :param VolumeReferenceVolumeAttachmentContextDeleted deleted: (optional) If
               present, this property indicates the referenced resource has been deleted,
               and provides
               some supplementary information.
        """
        self.crn = crn
        self.deleted = deleted
        self.href = href
        self.id = id
        self.name = name
        self.resource_type = resource_type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VolumeReferenceVolumeAttachmentContext':
        """Initialize a VolumeReferenceVolumeAttachmentContext object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError('Required property \'crn\' not present in VolumeReferenceVolumeAttachmentContext JSON')
        if 'deleted' in _dict:
            args['deleted'] = VolumeReferenceVolumeAttachmentContextDeleted.from_dict(_dict.get('deleted'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in VolumeReferenceVolumeAttachmentContext JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in VolumeReferenceVolumeAttachmentContext JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in VolumeReferenceVolumeAttachmentContext JSON')
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError('Required property \'resource_type\' not present in VolumeReferenceVolumeAttachmentContext JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VolumeReferenceVolumeAttachmentContext object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'deleted') and self.deleted is not None:
            if isinstance(self.deleted, dict):
                _dict['deleted'] = self.deleted
            else:
                _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'resource_type') and self.resource_type is not None:
            _dict['resource_type'] = self.resource_type
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VolumeReferenceVolumeAttachmentContext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VolumeReferenceVolumeAttachmentContext') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VolumeReferenceVolumeAttachmentContext') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        VOLUME = 'volume'



class VolumeReferenceVolumeAttachmentContextDeleted:
    """
    If present, this property indicates the referenced resource has been deleted, and
    provides some supplementary information.

    :attr str more_info: Link to documentation about deleted resources.
    """

    def __init__(
        self,
        more_info: str,
    ) -> None:
        """
        Initialize a VolumeReferenceVolumeAttachmentContextDeleted object.

        :param str more_info: Link to documentation about deleted resources.
        """
        self.more_info = more_info

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VolumeReferenceVolumeAttachmentContextDeleted':
        """Initialize a VolumeReferenceVolumeAttachmentContextDeleted object from a json dictionary."""
        args = {}
        if 'more_info' in _dict:
            args['more_info'] = _dict.get('more_info')
        else:
            raise ValueError('Required property \'more_info\' not present in VolumeReferenceVolumeAttachmentContextDeleted JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VolumeReferenceVolumeAttachmentContextDeleted object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'more_info') and self.more_info is not None:
            _dict['more_info'] = self.more_info
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VolumeReferenceVolumeAttachmentContextDeleted object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VolumeReferenceVolumeAttachmentContextDeleted') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VolumeReferenceVolumeAttachmentContextDeleted') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VolumeRemote:
    """
    If present, this property indicates that the resource associated with this reference
    is remote and therefore may not be directly retrievable.

    :attr RegionReference region: (optional) If present, this property indicates
          that the referenced resource is remote to this
          region, and identifies the native region.
    """

    def __init__(
        self,
        *,
        region: 'RegionReference' = None,
    ) -> None:
        """
        Initialize a VolumeRemote object.

        :param RegionReference region: (optional) If present, this property
               indicates that the referenced resource is remote to this
               region, and identifies the native region.
        """
        self.region = region

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VolumeRemote':
        """Initialize a VolumeRemote object from a json dictionary."""
        args = {}
        if 'region' in _dict:
            args['region'] = RegionReference.from_dict(_dict.get('region'))
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VolumeRemote object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'region') and self.region is not None:
            if isinstance(self.region, dict):
                _dict['region'] = self.region
            else:
                _dict['region'] = self.region.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 VolumeRemote object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VolumeRemote') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VolumeRemote') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VolumeStatusReason:
    """
    VolumeStatusReason.

    :attr str code: A snake case string succinctly identifying the status reason.
    :attr str message: An explanation of the status reason.
    :attr str more_info: (optional) Link to documentation about this status reason.
    """

    def __init__(
        self,
        code: str,
        message: str,
        *,
        more_info: str = None,
    ) -> None:
        """
        Initialize a VolumeStatusReason object.

        :param str code: A snake case string succinctly identifying the status
               reason.
        :param str message: An explanation of the status reason.
        :param str more_info: (optional) Link to documentation about this status
               reason.
        """
        self.code = code
        self.message = message
        self.more_info = more_info

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VolumeStatusReason':
        """Initialize a VolumeStatusReason object from a json dictionary."""
        args = {}
        if 'code' in _dict:
            args['code'] = _dict.get('code')
        else:
            raise ValueError('Required property \'code\' not present in VolumeStatusReason JSON')
        if 'message' in _dict:
            args['message'] = _dict.get('message')
        else:
            raise ValueError('Required property \'message\' not present in VolumeStatusReason JSON')
        if 'more_info' in _dict:
            args['more_info'] = _dict.get('more_info')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VolumeStatusReason object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'code') and self.code is not None:
            _dict['code'] = self.code
        if hasattr(self, 'message') and self.message is not None:
            _dict['message'] = self.message
        if hasattr(self, 'more_info') and self.more_info is not None:
            _dict['more_info'] = self.more_info
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VolumeStatusReason object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VolumeStatusReason') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VolumeStatusReason') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class CodeEnum(str, Enum):
        """
        A snake case string succinctly identifying the status reason.
        """

        ENCRYPTION_KEY_DELETED = 'encryption_key_deleted'



class Zone:
    """
    Zone.

    :attr str href: The URL for this zone.
    :attr str name: The globally unique name for this zone.
    :attr RegionReference region: The region this zone resides in.
    :attr str status: The availability status of this zone.
    """

    def __init__(
        self,
        href: str,
        name: str,
        region: 'RegionReference',
        status: str,
    ) -> None:
        """
        Initialize a Zone object.

        :param str href: The URL for this zone.
        :param str name: The globally unique name for this zone.
        :param RegionReference region: The region this zone resides in.
        :param str status: The availability status of this zone.
        """
        self.href = href
        self.name = name
        self.region = region
        self.status = status

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'Zone':
        """Initialize a Zone object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in Zone JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in Zone JSON')
        if 'region' in _dict:
            args['region'] = RegionReference.from_dict(_dict.get('region'))
        else:
            raise ValueError('Required property \'region\' not present in Zone JSON')
        if 'status' in _dict:
            args['status'] = _dict.get('status')
        else:
            raise ValueError('Required property \'status\' not present in Zone JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a Zone object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'region') and self.region is not None:
            if isinstance(self.region, dict):
                _dict['region'] = self.region
            else:
                _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(v) for v 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:
            zones_list = []
            for v in self.zones:
                if isinstance(v, dict):
                    zones_list.append(v)
                else:
                    zones_list.append(v.to_dict())
            _dict['zones'] = zones_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 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 BackupPolicyJobSourceVolumeReference(BackupPolicyJobSource):
    """
    BackupPolicyJobSourceVolumeReference.

    :attr str crn: The CRN for this volume.
    :attr VolumeReferenceDeleted deleted: (optional) If present, this property
          indicates the referenced resource has been deleted, and provides
          some supplementary information.
    :attr str href: The URL for this volume.
    :attr str id: The unique identifier for this volume.
    :attr str name: The name for this volume. The name is unique across all volumes
          in the region.
    :attr VolumeRemote remote: (optional) If present, this property indicates that
          the resource associated with this reference
          is remote and therefore may not be directly retrievable.
    :attr str resource_type: The resource type.
    """

    def __init__(
        self,
        crn: str,
        href: str,
        id: str,
        name: str,
        resource_type: str,
        *,
        deleted: 'VolumeReferenceDeleted' = None,
        remote: 'VolumeRemote' = None,
    ) -> None:
        """
        Initialize a BackupPolicyJobSourceVolumeReference 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 name for this volume. The name is unique across all
               volumes in the region.
        :param str resource_type: The resource type.
        :param VolumeReferenceDeleted deleted: (optional) If present, this property
               indicates the referenced resource has been deleted, and provides
               some supplementary information.
        :param VolumeRemote remote: (optional) If present, this property indicates
               that the resource associated with this reference
               is remote and therefore may not be directly retrievable.
        """
        # pylint: disable=super-init-not-called
        self.crn = crn
        self.deleted = deleted
        self.href = href
        self.id = id
        self.name = name
        self.remote = remote
        self.resource_type = resource_type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'BackupPolicyJobSourceVolumeReference':
        """Initialize a BackupPolicyJobSourceVolumeReference object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError('Required property \'crn\' not present in BackupPolicyJobSourceVolumeReference JSON')
        if 'deleted' in _dict:
            args['deleted'] = VolumeReferenceDeleted.from_dict(_dict.get('deleted'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in BackupPolicyJobSourceVolumeReference JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in BackupPolicyJobSourceVolumeReference JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in BackupPolicyJobSourceVolumeReference JSON')
        if 'remote' in _dict:
            args['remote'] = VolumeRemote.from_dict(_dict.get('remote'))
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError('Required property \'resource_type\' not present in BackupPolicyJobSourceVolumeReference JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a BackupPolicyJobSourceVolumeReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'deleted') and self.deleted is not None:
            if isinstance(self.deleted, dict):
                _dict['deleted'] = self.deleted
            else:
                _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, '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, '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 BackupPolicyJobSourceVolumeReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'BackupPolicyJobSourceVolumeReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'BackupPolicyJobSourceVolumeReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        VOLUME = 'volume'



class BackupPolicyScopePrototypeEnterpriseIdentity(BackupPolicyScopePrototype):
    """
    Identifies an enterprise by a unique property.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a BackupPolicyScopePrototypeEnterpriseIdentity object.

        """
        # pylint: disable=super-init-not-called
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['BackupPolicyScopePrototypeEnterpriseIdentityEnterpriseIdentityByCRN'])
        )
        raise Exception(msg)


class BackupPolicyScopeAccountReference(BackupPolicyScope):
    """
    BackupPolicyScopeAccountReference.

    :attr str id: The unique identifier for this account.
    :attr str resource_type: The resource type.
    """

    def __init__(
        self,
        id: str,
        resource_type: str,
    ) -> None:
        """
        Initialize a BackupPolicyScopeAccountReference object.

        :param str id: The unique identifier for this account.
        :param str resource_type: The resource type.
        """
        # pylint: disable=super-init-not-called
        self.id = id
        self.resource_type = resource_type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'BackupPolicyScopeAccountReference':
        """Initialize a BackupPolicyScopeAccountReference object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in BackupPolicyScopeAccountReference JSON')
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError('Required property \'resource_type\' not present in BackupPolicyScopeAccountReference JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a BackupPolicyScopeAccountReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, '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 BackupPolicyScopeAccountReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'BackupPolicyScopeAccountReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'BackupPolicyScopeAccountReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        ACCOUNT = 'account'



class BackupPolicyScopeEnterpriseReference(BackupPolicyScope):
    """
    BackupPolicyScopeEnterpriseReference.

    :attr str crn: The CRN for this enterprise.
    :attr str id: The unique identifier for this enterprise.
    :attr str resource_type: The resource type.
    """

    def __init__(
        self,
        crn: str,
        id: str,
        resource_type: str,
    ) -> None:
        """
        Initialize a BackupPolicyScopeEnterpriseReference object.

        :param str crn: The CRN for this enterprise.
        :param str id: The unique identifier for this enterprise.
        :param str resource_type: The resource type.
        """
        # pylint: disable=super-init-not-called
        self.crn = crn
        self.id = id
        self.resource_type = resource_type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'BackupPolicyScopeEnterpriseReference':
        """Initialize a BackupPolicyScopeEnterpriseReference object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError('Required property \'crn\' not present in BackupPolicyScopeEnterpriseReference JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in BackupPolicyScopeEnterpriseReference JSON')
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError('Required property \'resource_type\' not present in BackupPolicyScopeEnterpriseReference JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a BackupPolicyScopeEnterpriseReference object from 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, 'id') and self.id is not None:
            _dict['id'] = self.id
        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 BackupPolicyScopeEnterpriseReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'BackupPolicyScopeEnterpriseReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'BackupPolicyScopeEnterpriseReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        ENTERPRISE = 'enterprise'



class BareMetalServerBootTargetBareMetalServerDiskReference(BareMetalServerBootTarget):
    """
    BareMetalServerBootTargetBareMetalServerDiskReference.

    :attr BareMetalServerDiskReferenceDeleted deleted: (optional) If present, this
          property indicates the referenced resource has been deleted, and provides
          some supplementary information.
    :attr str href: The URL for this bare metal server disk.
    :attr str id: The unique identifier for this bare metal server disk.
    :attr str name: The name for this bare metal server disk. The name is unique
          across all disks on the bare metal server.
    :attr str resource_type: The resource type.
    """

    def __init__(
        self,
        href: str,
        id: str,
        name: str,
        resource_type: str,
        *,
        deleted: 'BareMetalServerDiskReferenceDeleted' = None,
    ) -> None:
        """
        Initialize a BareMetalServerBootTargetBareMetalServerDiskReference object.

        :param str href: The URL for this bare metal server disk.
        :param str id: The unique identifier for this bare metal server disk.
        :param str name: The name for this bare metal server disk. The name is
               unique across all disks on the bare metal server.
        :param str resource_type: The resource type.
        :param BareMetalServerDiskReferenceDeleted deleted: (optional) If present,
               this property indicates the referenced resource has been deleted, and
               provides
               some supplementary information.
        """
        # pylint: disable=super-init-not-called
        self.deleted = deleted
        self.href = href
        self.id = id
        self.name = name
        self.resource_type = resource_type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'BareMetalServerBootTargetBareMetalServerDiskReference':
        """Initialize a BareMetalServerBootTargetBareMetalServerDiskReference object from a json dictionary."""
        args = {}
        if 'deleted' in _dict:
            args['deleted'] = BareMetalServerDiskReferenceDeleted.from_dict(_dict.get('deleted'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in BareMetalServerBootTargetBareMetalServerDiskReference JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in BareMetalServerBootTargetBareMetalServerDiskReference JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in BareMetalServerBootTargetBareMetalServerDiskReference JSON')
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError('Required property \'resource_type\' not present in BareMetalServerBootTargetBareMetalServerDiskReference JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a BareMetalServerBootTargetBareMetalServerDiskReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'deleted') and self.deleted is not None:
            if isinstance(self.deleted, dict):
                _dict['deleted'] = self.deleted
            else:
                _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'resource_type') and self.resource_type is not None:
            _dict['resource_type'] = self.resource_type
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this BareMetalServerBootTargetBareMetalServerDiskReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'BareMetalServerBootTargetBareMetalServerDiskReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'BareMetalServerBootTargetBareMetalServerDiskReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        BARE_METAL_SERVER_DISK = 'bare_metal_server_disk'



class BareMetalServerInitializationUserAccountBareMetalServerInitializationHostUserAccount(BareMetalServerInitializationUserAccount):
    """
    BareMetalServerInitializationUserAccountBareMetalServerInitializationHostUserAccount.

    :attr bytes encrypted_password: The password at initialization, encrypted using
          `encryption_key`, and returned base64-encoded.
    :attr KeyReference encryption_key: The public SSH key used to encrypt the
          password.
    :attr str resource_type: The resource type.
    :attr str username: The username for the account created at initialization.
    """

    def __init__(
        self,
        encrypted_password: bytes,
        encryption_key: 'KeyReference',
        resource_type: str,
        username: str,
    ) -> None:
        """
        Initialize a BareMetalServerInitializationUserAccountBareMetalServerInitializationHostUserAccount object.

        :param bytes encrypted_password: The password at initialization, encrypted
               using `encryption_key`, and returned base64-encoded.
        :param KeyReference encryption_key: The public SSH key used to encrypt the
               password.
        :param str resource_type: The resource type.
        :param str username: The username for the account created at
               initialization.
        """
        # pylint: disable=super-init-not-called
        self.encrypted_password = encrypted_password
        self.encryption_key = encryption_key
        self.resource_type = resource_type
        self.username = username

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'BareMetalServerInitializationUserAccountBareMetalServerInitializationHostUserAccount':
        """Initialize a BareMetalServerInitializationUserAccountBareMetalServerInitializationHostUserAccount 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 BareMetalServerInitializationUserAccountBareMetalServerInitializationHostUserAccount JSON')
        if 'encryption_key' in _dict:
            args['encryption_key'] = KeyReference.from_dict(_dict.get('encryption_key'))
        else:
            raise ValueError('Required property \'encryption_key\' not present in BareMetalServerInitializationUserAccountBareMetalServerInitializationHostUserAccount JSON')
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError('Required property \'resource_type\' not present in BareMetalServerInitializationUserAccountBareMetalServerInitializationHostUserAccount JSON')
        if 'username' in _dict:
            args['username'] = _dict.get('username')
        else:
            raise ValueError('Required property \'username\' not present in BareMetalServerInitializationUserAccountBareMetalServerInitializationHostUserAccount JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a BareMetalServerInitializationUserAccountBareMetalServerInitializationHostUserAccount object from 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()
        if hasattr(self, 'resource_type') and self.resource_type is not None:
            _dict['resource_type'] = self.resource_type
        if hasattr(self, 'username') and self.username is not None:
            _dict['username'] = self.username
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this BareMetalServerInitializationUserAccountBareMetalServerInitializationHostUserAccount object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'BareMetalServerInitializationUserAccountBareMetalServerInitializationHostUserAccount') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'BareMetalServerInitializationUserAccountBareMetalServerInitializationHostUserAccount') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        HOST_USER_ACCOUNT = 'host_user_account'



class BareMetalServerNetworkInterfaceByHiperSocket(BareMetalServerNetworkInterface):
    """
    BareMetalServerNetworkInterfaceByHiperSocket.

    :attr bool allow_ip_spoofing: Indicates whether source IP spoofing is allowed on
          this bare metal server network interface.
    :attr datetime created_at: The date and time that the bare metal server network
          interface was created.
    :attr bool enable_infrastructure_nat: If `true`:
          - The VPC infrastructure performs any needed NAT operations.
          - `floating_ips` must not have more than one floating IP.
          If `false`:
          - Packets are passed unchanged to/from the bare metal server network interface,
            allowing the workload to perform any needed NAT operations.
          - `allow_ip_spoofing` must be `false`.
          - `interface_type` must not be `hipersocket`.
    :attr List[FloatingIPReference] floating_ips: The floating IPs associated with
          this bare metal server network interface.
    :attr str href: The URL for this bare metal server network interface.
    :attr str id: The unique identifier for this bare metal server network
          interface.
    :attr str mac_address: The MAC address of this bare metal server network
          interface. If the MAC address has not yet been selected, the value will be an
          empty string.
    :attr str name: The name for this bare metal server network interface.
    :attr int port_speed: The bare metal server network interface port speed in
          Mbps.
    :attr ReservedIPReference primary_ip:
    :attr str resource_type: The resource type.
    :attr List[SecurityGroupReference] security_groups: The security groups
          targeting this bare metal server network interface.
    :attr str status: The status of the bare metal server network interface.
    :attr SubnetReference subnet: The associated subnet.
    :attr str type: The bare metal server network interface type.
    :attr str interface_type: - `hipersocket`: a virtual network device that
          provides high-speed TCP/IP connectivity
            within a `s390x` based system.
    """

    def __init__(
        self,
        allow_ip_spoofing: bool,
        created_at: datetime,
        enable_infrastructure_nat: bool,
        floating_ips: List['FloatingIPReference'],
        href: str,
        id: str,
        mac_address: str,
        name: str,
        port_speed: int,
        primary_ip: 'ReservedIPReference',
        resource_type: str,
        security_groups: List['SecurityGroupReference'],
        status: str,
        subnet: 'SubnetReference',
        type: str,
        interface_type: str,
    ) -> None:
        """
        Initialize a BareMetalServerNetworkInterfaceByHiperSocket object.

        :param bool allow_ip_spoofing: Indicates whether source IP spoofing is
               allowed on this bare metal server network interface.
        :param datetime created_at: The date and time that the bare metal server
               network interface was created.
        :param bool enable_infrastructure_nat: If `true`:
               - The VPC infrastructure performs any needed NAT operations.
               - `floating_ips` must not have more than one floating IP.
               If `false`:
               - Packets are passed unchanged to/from the bare metal server network
               interface,
                 allowing the workload to perform any needed NAT operations.
               - `allow_ip_spoofing` must be `false`.
               - `interface_type` must not be `hipersocket`.
        :param List[FloatingIPReference] floating_ips: The floating IPs associated
               with this bare metal server network interface.
        :param str href: The URL for this bare metal server network interface.
        :param str id: The unique identifier for this bare metal server network
               interface.
        :param str mac_address: The MAC address of this bare metal server network
               interface. If the MAC address has not yet been selected, the value will be
               an empty string.
        :param str name: The name for this bare metal server network interface.
        :param int port_speed: The bare metal server network interface port speed
               in Mbps.
        :param ReservedIPReference primary_ip:
        :param str resource_type: The resource type.
        :param List[SecurityGroupReference] security_groups: The security groups
               targeting this bare metal server network interface.
        :param str status: The status of the bare metal server network interface.
        :param SubnetReference subnet: The associated subnet.
        :param str type: The bare metal server network interface type.
        :param str interface_type: - `hipersocket`: a virtual network device that
               provides high-speed TCP/IP connectivity
                 within a `s390x` based system.
        """
        # pylint: disable=super-init-not-called
        self.allow_ip_spoofing = allow_ip_spoofing
        self.created_at = created_at
        self.enable_infrastructure_nat = enable_infrastructure_nat
        self.floating_ips = floating_ips
        self.href = href
        self.id = id
        self.mac_address = mac_address
        self.name = name
        self.port_speed = port_speed
        self.primary_ip = primary_ip
        self.resource_type = resource_type
        self.security_groups = security_groups
        self.status = status
        self.subnet = subnet
        self.type = type
        self.interface_type = interface_type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'BareMetalServerNetworkInterfaceByHiperSocket':
        """Initialize a BareMetalServerNetworkInterfaceByHiperSocket object from a json dictionary."""
        args = {}
        if 'allow_ip_spoofing' in _dict:
            args['allow_ip_spoofing'] = _dict.get('allow_ip_spoofing')
        else:
            raise ValueError('Required property \'allow_ip_spoofing\' not present in BareMetalServerNetworkInterfaceByHiperSocket 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 BareMetalServerNetworkInterfaceByHiperSocket JSON')
        if 'enable_infrastructure_nat' in _dict:
            args['enable_infrastructure_nat'] = _dict.get('enable_infrastructure_nat')
        else:
            raise ValueError('Required property \'enable_infrastructure_nat\' not present in BareMetalServerNetworkInterfaceByHiperSocket JSON')
        if 'floating_ips' in _dict:
            args['floating_ips'] = [FloatingIPReference.from_dict(v) for v in _dict.get('floating_ips')]
        else:
            raise ValueError('Required property \'floating_ips\' not present in BareMetalServerNetworkInterfaceByHiperSocket JSON')
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in BareMetalServerNetworkInterfaceByHiperSocket JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in BareMetalServerNetworkInterfaceByHiperSocket JSON')
        if 'mac_address' in _dict:
            args['mac_address'] = _dict.get('mac_address')
        else:
            raise ValueError('Required property \'mac_address\' not present in BareMetalServerNetworkInterfaceByHiperSocket JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in BareMetalServerNetworkInterfaceByHiperSocket JSON')
        if 'port_speed' in _dict:
            args['port_speed'] = _dict.get('port_speed')
        else:
            raise ValueError('Required property \'port_speed\' not present in BareMetalServerNetworkInterfaceByHiperSocket JSON')
        if 'primary_ip' in _dict:
            args['primary_ip'] = ReservedIPReference.from_dict(_dict.get('primary_ip'))
        else:
            raise ValueError('Required property \'primary_ip\' not present in BareMetalServerNetworkInterfaceByHiperSocket JSON')
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError('Required property \'resource_type\' not present in BareMetalServerNetworkInterfaceByHiperSocket JSON')
        if 'security_groups' in _dict:
            args['security_groups'] = [SecurityGroupReference.from_dict(v) for v in _dict.get('security_groups')]
        else:
            raise ValueError('Required property \'security_groups\' not present in BareMetalServerNetworkInterfaceByHiperSocket JSON')
        if 'status' in _dict:
            args['status'] = _dict.get('status')
        else:
            raise ValueError('Required property \'status\' not present in BareMetalServerNetworkInterfaceByHiperSocket JSON')
        if 'subnet' in _dict:
            args['subnet'] = SubnetReference.from_dict(_dict.get('subnet'))
        else:
            raise ValueError('Required property \'subnet\' not present in BareMetalServerNetworkInterfaceByHiperSocket JSON')
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in BareMetalServerNetworkInterfaceByHiperSocket JSON')
        if 'interface_type' in _dict:
            args['interface_type'] = _dict.get('interface_type')
        else:
            raise ValueError('Required property \'interface_type\' not present in BareMetalServerNetworkInterfaceByHiperSocket JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a BareMetalServerNetworkInterfaceByHiperSocket object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'allow_ip_spoofing') and self.allow_ip_spoofing is not None:
            _dict['allow_ip_spoofing'] = self.allow_ip_spoofing
        if hasattr(self, 'created_at') and self.created_at is not None:
            _dict['created_at'] = datetime_to_string(self.created_at)
        if hasattr(self, 'enable_infrastructure_nat') and self.enable_infrastructure_nat is not None:
            _dict['enable_infrastructure_nat'] = self.enable_infrastructure_nat
        if hasattr(self, 'floating_ips') and self.floating_ips is not None:
            floating_ips_list = []
            for v in self.floating_ips:
                if isinstance(v, dict):
                    floating_ips_list.append(v)
                else:
                    floating_ips_list.append(v.to_dict())
            _dict['floating_ips'] = floating_ips_list
        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, 'mac_address') and self.mac_address is not None:
            _dict['mac_address'] = self.mac_address
        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_ip') and self.primary_ip is not None:
            if isinstance(self.primary_ip, dict):
                _dict['primary_ip'] = self.primary_ip
            else:
                _dict['primary_ip'] = self.primary_ip.to_dict()
        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:
            security_groups_list = []
            for v in self.security_groups:
                if isinstance(v, dict):
                    security_groups_list.append(v)
                else:
                    security_groups_list.append(v.to_dict())
            _dict['security_groups'] = security_groups_list
        if hasattr(self, 'status') and self.status is not None:
            _dict['status'] = self.status
        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, 'type') and self.type is not None:
            _dict['type'] = self.type
        if hasattr(self, 'interface_type') and self.interface_type is not None:
            _dict['interface_type'] = self.interface_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 BareMetalServerNetworkInterfaceByHiperSocket object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'BareMetalServerNetworkInterfaceByHiperSocket') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'BareMetalServerNetworkInterfaceByHiperSocket') -> 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 bare metal server network interface.
        """

        AVAILABLE = 'available'
        DELETING = 'deleting'
        FAILED = 'failed'
        PENDING = 'pending'


    class TypeEnum(str, Enum):
        """
        The bare metal server network interface type.
        """

        PRIMARY = 'primary'
        SECONDARY = 'secondary'


    class InterfaceTypeEnum(str, Enum):
        """
        - `hipersocket`: a virtual network device that provides high-speed TCP/IP
        connectivity
          within a `s390x` based system.
        """

        HIPERSOCKET = 'hipersocket'



class BareMetalServerNetworkInterfaceByPCI(BareMetalServerNetworkInterface):
    """
    BareMetalServerNetworkInterfaceByPCI.

    :attr bool allow_ip_spoofing: Indicates whether source IP spoofing is allowed on
          this bare metal server network interface.
    :attr datetime created_at: The date and time that the bare metal server network
          interface was created.
    :attr bool enable_infrastructure_nat: If `true`:
          - The VPC infrastructure performs any needed NAT operations.
          - `floating_ips` must not have more than one floating IP.
          If `false`:
          - Packets are passed unchanged to/from the bare metal server network interface,
            allowing the workload to perform any needed NAT operations.
          - `allow_ip_spoofing` must be `false`.
          - `interface_type` must not be `hipersocket`.
    :attr List[FloatingIPReference] floating_ips: The floating IPs associated with
          this bare metal server network interface.
    :attr str href: The URL for this bare metal server network interface.
    :attr str id: The unique identifier for this bare metal server network
          interface.
    :attr str mac_address: The MAC address of this bare metal server network
          interface. If the MAC address has not yet been selected, the value will be an
          empty string.
    :attr str name: The name for this bare metal server network interface.
    :attr int port_speed: The bare metal server network interface port speed in
          Mbps.
    :attr ReservedIPReference primary_ip:
    :attr str resource_type: The resource type.
    :attr List[SecurityGroupReference] security_groups: The security groups
          targeting this bare metal server network interface.
    :attr str status: The status of the bare metal server network interface.
    :attr SubnetReference subnet: The associated subnet.
    :attr str type: The bare metal server network interface type.
    :attr List[int] allowed_vlans: The VLAN IDs allowed for `vlan` interfaces using
          this PCI interface.
    :attr str interface_type: - `pci`: a physical PCI device which can only be
          created or deleted when the bare metal
            server is stopped
            - Has an `allowed_vlans` property which controls the VLANs that will be
          permitted
              to use the PCI interface
            - Cannot directly use an IEEE 802.1Q tag.
    """

    def __init__(
        self,
        allow_ip_spoofing: bool,
        created_at: datetime,
        enable_infrastructure_nat: bool,
        floating_ips: List['FloatingIPReference'],
        href: str,
        id: str,
        mac_address: str,
        name: str,
        port_speed: int,
        primary_ip: 'ReservedIPReference',
        resource_type: str,
        security_groups: List['SecurityGroupReference'],
        status: str,
        subnet: 'SubnetReference',
        type: str,
        allowed_vlans: List[int],
        interface_type: str,
    ) -> None:
        """
        Initialize a BareMetalServerNetworkInterfaceByPCI object.

        :param bool allow_ip_spoofing: Indicates whether source IP spoofing is
               allowed on this bare metal server network interface.
        :param datetime created_at: The date and time that the bare metal server
               network interface was created.
        :param bool enable_infrastructure_nat: If `true`:
               - The VPC infrastructure performs any needed NAT operations.
               - `floating_ips` must not have more than one floating IP.
               If `false`:
               - Packets are passed unchanged to/from the bare metal server network
               interface,
                 allowing the workload to perform any needed NAT operations.
               - `allow_ip_spoofing` must be `false`.
               - `interface_type` must not be `hipersocket`.
        :param List[FloatingIPReference] floating_ips: The floating IPs associated
               with this bare metal server network interface.
        :param str href: The URL for this bare metal server network interface.
        :param str id: The unique identifier for this bare metal server network
               interface.
        :param str mac_address: The MAC address of this bare metal server network
               interface. If the MAC address has not yet been selected, the value will be
               an empty string.
        :param str name: The name for this bare metal server network interface.
        :param int port_speed: The bare metal server network interface port speed
               in Mbps.
        :param ReservedIPReference primary_ip:
        :param str resource_type: The resource type.
        :param List[SecurityGroupReference] security_groups: The security groups
               targeting this bare metal server network interface.
        :param str status: The status of the bare metal server network interface.
        :param SubnetReference subnet: The associated subnet.
        :param str type: The bare metal server network interface type.
        :param List[int] allowed_vlans: The VLAN IDs allowed for `vlan` interfaces
               using this PCI interface.
        :param str interface_type: - `pci`: a physical PCI device which can only be
               created or deleted when the bare metal
                 server is stopped
                 - Has an `allowed_vlans` property which controls the VLANs that will be
               permitted
                   to use the PCI interface
                 - Cannot directly use an IEEE 802.1Q tag.
        """
        # pylint: disable=super-init-not-called
        self.allow_ip_spoofing = allow_ip_spoofing
        self.created_at = created_at
        self.enable_infrastructure_nat = enable_infrastructure_nat
        self.floating_ips = floating_ips
        self.href = href
        self.id = id
        self.mac_address = mac_address
        self.name = name
        self.port_speed = port_speed
        self.primary_ip = primary_ip
        self.resource_type = resource_type
        self.security_groups = security_groups
        self.status = status
        self.subnet = subnet
        self.type = type
        self.allowed_vlans = allowed_vlans
        self.interface_type = interface_type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'BareMetalServerNetworkInterfaceByPCI':
        """Initialize a BareMetalServerNetworkInterfaceByPCI object from a json dictionary."""
        args = {}
        if 'allow_ip_spoofing' in _dict:
            args['allow_ip_spoofing'] = _dict.get('allow_ip_spoofing')
        else:
            raise ValueError('Required property \'allow_ip_spoofing\' not present in BareMetalServerNetworkInterfaceByPCI 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 BareMetalServerNetworkInterfaceByPCI JSON')
        if 'enable_infrastructure_nat' in _dict:
            args['enable_infrastructure_nat'] = _dict.get('enable_infrastructure_nat')
        else:
            raise ValueError('Required property \'enable_infrastructure_nat\' not present in BareMetalServerNetworkInterfaceByPCI JSON')
        if 'floating_ips' in _dict:
            args['floating_ips'] = [FloatingIPReference.from_dict(v) for v in _dict.get('floating_ips')]
        else:
            raise ValueError('Required property \'floating_ips\' not present in BareMetalServerNetworkInterfaceByPCI JSON')
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in BareMetalServerNetworkInterfaceByPCI JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in BareMetalServerNetworkInterfaceByPCI JSON')
        if 'mac_address' in _dict:
            args['mac_address'] = _dict.get('mac_address')
        else:
            raise ValueError('Required property \'mac_address\' not present in BareMetalServerNetworkInterfaceByPCI JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in BareMetalServerNetworkInterfaceByPCI JSON')
        if 'port_speed' in _dict:
            args['port_speed'] = _dict.get('port_speed')
        else:
            raise ValueError('Required property \'port_speed\' not present in BareMetalServerNetworkInterfaceByPCI JSON')
        if 'primary_ip' in _dict:
            args['primary_ip'] = ReservedIPReference.from_dict(_dict.get('primary_ip'))
        else:
            raise ValueError('Required property \'primary_ip\' not present in BareMetalServerNetworkInterfaceByPCI JSON')
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError('Required property \'resource_type\' not present in BareMetalServerNetworkInterfaceByPCI JSON')
        if 'security_groups' in _dict:
            args['security_groups'] = [SecurityGroupReference.from_dict(v) for v in _dict.get('security_groups')]
        else:
            raise ValueError('Required property \'security_groups\' not present in BareMetalServerNetworkInterfaceByPCI JSON')
        if 'status' in _dict:
            args['status'] = _dict.get('status')
        else:
            raise ValueError('Required property \'status\' not present in BareMetalServerNetworkInterfaceByPCI JSON')
        if 'subnet' in _dict:
            args['subnet'] = SubnetReference.from_dict(_dict.get('subnet'))
        else:
            raise ValueError('Required property \'subnet\' not present in BareMetalServerNetworkInterfaceByPCI JSON')
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in BareMetalServerNetworkInterfaceByPCI JSON')
        if 'allowed_vlans' in _dict:
            args['allowed_vlans'] = _dict.get('allowed_vlans')
        else:
            raise ValueError('Required property \'allowed_vlans\' not present in BareMetalServerNetworkInterfaceByPCI JSON')
        if 'interface_type' in _dict:
            args['interface_type'] = _dict.get('interface_type')
        else:
            raise ValueError('Required property \'interface_type\' not present in BareMetalServerNetworkInterfaceByPCI JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a BareMetalServerNetworkInterfaceByPCI object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'allow_ip_spoofing') and self.allow_ip_spoofing is not None:
            _dict['allow_ip_spoofing'] = self.allow_ip_spoofing
        if hasattr(self, 'created_at') and self.created_at is not None:
            _dict['created_at'] = datetime_to_string(self.created_at)
        if hasattr(self, 'enable_infrastructure_nat') and self.enable_infrastructure_nat is not None:
            _dict['enable_infrastructure_nat'] = self.enable_infrastructure_nat
        if hasattr(self, 'floating_ips') and self.floating_ips is not None:
            floating_ips_list = []
            for v in self.floating_ips:
                if isinstance(v, dict):
                    floating_ips_list.append(v)
                else:
                    floating_ips_list.append(v.to_dict())
            _dict['floating_ips'] = floating_ips_list
        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, 'mac_address') and self.mac_address is not None:
            _dict['mac_address'] = self.mac_address
        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_ip') and self.primary_ip is not None:
            if isinstance(self.primary_ip, dict):
                _dict['primary_ip'] = self.primary_ip
            else:
                _dict['primary_ip'] = self.primary_ip.to_dict()
        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:
            security_groups_list = []
            for v in self.security_groups:
                if isinstance(v, dict):
                    security_groups_list.append(v)
                else:
                    security_groups_list.append(v.to_dict())
            _dict['security_groups'] = security_groups_list
        if hasattr(self, 'status') and self.status is not None:
            _dict['status'] = self.status
        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, 'type') and self.type is not None:
            _dict['type'] = self.type
        if hasattr(self, 'allowed_vlans') and self.allowed_vlans is not None:
            _dict['allowed_vlans'] = self.allowed_vlans
        if hasattr(self, 'interface_type') and self.interface_type is not None:
            _dict['interface_type'] = self.interface_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 BareMetalServerNetworkInterfaceByPCI object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'BareMetalServerNetworkInterfaceByPCI') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'BareMetalServerNetworkInterfaceByPCI') -> 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 bare metal server network interface.
        """

        AVAILABLE = 'available'
        DELETING = 'deleting'
        FAILED = 'failed'
        PENDING = 'pending'


    class TypeEnum(str, Enum):
        """
        The bare metal server network interface type.
        """

        PRIMARY = 'primary'
        SECONDARY = 'secondary'


    class InterfaceTypeEnum(str, Enum):
        """
        - `pci`: a physical PCI device which can only be created or deleted when the bare
        metal
          server is stopped
          - Has an `allowed_vlans` property which controls the VLANs that will be
        permitted
            to use the PCI interface
          - Cannot directly use an IEEE 802.1Q tag.
        """

        PCI = 'pci'



class BareMetalServerNetworkInterfaceByVLAN(BareMetalServerNetworkInterface):
    """
    BareMetalServerNetworkInterfaceByVLAN.

    :attr bool allow_ip_spoofing: Indicates whether source IP spoofing is allowed on
          this bare metal server network interface.
    :attr datetime created_at: The date and time that the bare metal server network
          interface was created.
    :attr bool enable_infrastructure_nat: If `true`:
          - The VPC infrastructure performs any needed NAT operations.
          - `floating_ips` must not have more than one floating IP.
          If `false`:
          - Packets are passed unchanged to/from the bare metal server network interface,
            allowing the workload to perform any needed NAT operations.
          - `allow_ip_spoofing` must be `false`.
          - `interface_type` must not be `hipersocket`.
    :attr List[FloatingIPReference] floating_ips: The floating IPs associated with
          this bare metal server network interface.
    :attr str href: The URL for this bare metal server network interface.
    :attr str id: The unique identifier for this bare metal server network
          interface.
    :attr str mac_address: The MAC address of this bare metal server network
          interface. If the MAC address has not yet been selected, the value will be an
          empty string.
    :attr str name: The name for this bare metal server network interface.
    :attr int port_speed: The bare metal server network interface port speed in
          Mbps.
    :attr ReservedIPReference primary_ip:
    :attr str resource_type: The resource type.
    :attr List[SecurityGroupReference] security_groups: The security groups
          targeting this bare metal server network interface.
    :attr str status: The status of the bare metal server network interface.
    :attr SubnetReference subnet: The associated subnet.
    :attr str type: The bare metal server network interface type.
    :attr bool allow_interface_to_float: Indicates if the data path for the network
          interface can float to another bare metal server. Can only be `true` for network
          interfaces with an `interface_type` of `vlan`.
          If `true`, and the network detects traffic for this data path on another bare
          metal server in the resource group, the network interface will be automatically
          deleted from this bare metal server and a new network interface with the same
          `id`, `name` and `vlan` will be created on the other bare metal server.
          For the data path to float, the other bare metal server must be in the same
          `resource_group`, and must have a network interface with `interface_type` of
          `pci` with `allowed_vlans` including this network interface's `vlan`.
    :attr str interface_type: - `vlan`: a virtual device, used through a `pci`
          device that has the `vlan` in its array
             of `allowed_vlans`.
            - Must use an IEEE 802.1Q tag.
            - Has its own security groups and does not inherit those of the PCI device
          through
              which traffic flows.
    :attr int vlan: The VLAN ID used in the IEEE 802.1Q tag present in all traffic
          on this interface.
    """

    def __init__(
        self,
        allow_ip_spoofing: bool,
        created_at: datetime,
        enable_infrastructure_nat: bool,
        floating_ips: List['FloatingIPReference'],
        href: str,
        id: str,
        mac_address: str,
        name: str,
        port_speed: int,
        primary_ip: 'ReservedIPReference',
        resource_type: str,
        security_groups: List['SecurityGroupReference'],
        status: str,
        subnet: 'SubnetReference',
        type: str,
        allow_interface_to_float: bool,
        interface_type: str,
        vlan: int,
    ) -> None:
        """
        Initialize a BareMetalServerNetworkInterfaceByVLAN object.

        :param bool allow_ip_spoofing: Indicates whether source IP spoofing is
               allowed on this bare metal server network interface.
        :param datetime created_at: The date and time that the bare metal server
               network interface was created.
        :param bool enable_infrastructure_nat: If `true`:
               - The VPC infrastructure performs any needed NAT operations.
               - `floating_ips` must not have more than one floating IP.
               If `false`:
               - Packets are passed unchanged to/from the bare metal server network
               interface,
                 allowing the workload to perform any needed NAT operations.
               - `allow_ip_spoofing` must be `false`.
               - `interface_type` must not be `hipersocket`.
        :param List[FloatingIPReference] floating_ips: The floating IPs associated
               with this bare metal server network interface.
        :param str href: The URL for this bare metal server network interface.
        :param str id: The unique identifier for this bare metal server network
               interface.
        :param str mac_address: The MAC address of this bare metal server network
               interface. If the MAC address has not yet been selected, the value will be
               an empty string.
        :param str name: The name for this bare metal server network interface.
        :param int port_speed: The bare metal server network interface port speed
               in Mbps.
        :param ReservedIPReference primary_ip:
        :param str resource_type: The resource type.
        :param List[SecurityGroupReference] security_groups: The security groups
               targeting this bare metal server network interface.
        :param str status: The status of the bare metal server network interface.
        :param SubnetReference subnet: The associated subnet.
        :param str type: The bare metal server network interface type.
        :param bool allow_interface_to_float: Indicates if the data path for the
               network interface can float to another bare metal server. Can only be
               `true` for network interfaces with an `interface_type` of `vlan`.
               If `true`, and the network detects traffic for this data path on another
               bare metal server in the resource group, the network interface will be
               automatically deleted from this bare metal server and a new network
               interface with the same `id`, `name` and `vlan` will be created on the
               other bare metal server.
               For the data path to float, the other bare metal server must be in the same
               `resource_group`, and must have a network interface with `interface_type`
               of `pci` with `allowed_vlans` including this network interface's `vlan`.
        :param str interface_type: - `vlan`: a virtual device, used through a `pci`
               device that has the `vlan` in its array
                  of `allowed_vlans`.
                 - Must use an IEEE 802.1Q tag.
                 - Has its own security groups and does not inherit those of the PCI
               device through
                   which traffic flows.
        :param int vlan: The VLAN ID used in the IEEE 802.1Q tag present in all
               traffic on this interface.
        """
        # pylint: disable=super-init-not-called
        self.allow_ip_spoofing = allow_ip_spoofing
        self.created_at = created_at
        self.enable_infrastructure_nat = enable_infrastructure_nat
        self.floating_ips = floating_ips
        self.href = href
        self.id = id
        self.mac_address = mac_address
        self.name = name
        self.port_speed = port_speed
        self.primary_ip = primary_ip
        self.resource_type = resource_type
        self.security_groups = security_groups
        self.status = status
        self.subnet = subnet
        self.type = type
        self.allow_interface_to_float = allow_interface_to_float
        self.interface_type = interface_type
        self.vlan = vlan

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'BareMetalServerNetworkInterfaceByVLAN':
        """Initialize a BareMetalServerNetworkInterfaceByVLAN object from a json dictionary."""
        args = {}
        if 'allow_ip_spoofing' in _dict:
            args['allow_ip_spoofing'] = _dict.get('allow_ip_spoofing')
        else:
            raise ValueError('Required property \'allow_ip_spoofing\' not present in BareMetalServerNetworkInterfaceByVLAN 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 BareMetalServerNetworkInterfaceByVLAN JSON')
        if 'enable_infrastructure_nat' in _dict:
            args['enable_infrastructure_nat'] = _dict.get('enable_infrastructure_nat')
        else:
            raise ValueError('Required property \'enable_infrastructure_nat\' not present in BareMetalServerNetworkInterfaceByVLAN JSON')
        if 'floating_ips' in _dict:
            args['floating_ips'] = [FloatingIPReference.from_dict(v) for v in _dict.get('floating_ips')]
        else:
            raise ValueError('Required property \'floating_ips\' not present in BareMetalServerNetworkInterfaceByVLAN JSON')
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in BareMetalServerNetworkInterfaceByVLAN JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in BareMetalServerNetworkInterfaceByVLAN JSON')
        if 'mac_address' in _dict:
            args['mac_address'] = _dict.get('mac_address')
        else:
            raise ValueError('Required property \'mac_address\' not present in BareMetalServerNetworkInterfaceByVLAN JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in BareMetalServerNetworkInterfaceByVLAN JSON')
        if 'port_speed' in _dict:
            args['port_speed'] = _dict.get('port_speed')
        else:
            raise ValueError('Required property \'port_speed\' not present in BareMetalServerNetworkInterfaceByVLAN JSON')
        if 'primary_ip' in _dict:
            args['primary_ip'] = ReservedIPReference.from_dict(_dict.get('primary_ip'))
        else:
            raise ValueError('Required property \'primary_ip\' not present in BareMetalServerNetworkInterfaceByVLAN JSON')
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError('Required property \'resource_type\' not present in BareMetalServerNetworkInterfaceByVLAN JSON')
        if 'security_groups' in _dict:
            args['security_groups'] = [SecurityGroupReference.from_dict(v) for v in _dict.get('security_groups')]
        else:
            raise ValueError('Required property \'security_groups\' not present in BareMetalServerNetworkInterfaceByVLAN JSON')
        if 'status' in _dict:
            args['status'] = _dict.get('status')
        else:
            raise ValueError('Required property \'status\' not present in BareMetalServerNetworkInterfaceByVLAN JSON')
        if 'subnet' in _dict:
            args['subnet'] = SubnetReference.from_dict(_dict.get('subnet'))
        else:
            raise ValueError('Required property \'subnet\' not present in BareMetalServerNetworkInterfaceByVLAN JSON')
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in BareMetalServerNetworkInterfaceByVLAN JSON')
        if 'allow_interface_to_float' in _dict:
            args['allow_interface_to_float'] = _dict.get('allow_interface_to_float')
        else:
            raise ValueError('Required property \'allow_interface_to_float\' not present in BareMetalServerNetworkInterfaceByVLAN JSON')
        if 'interface_type' in _dict:
            args['interface_type'] = _dict.get('interface_type')
        else:
            raise ValueError('Required property \'interface_type\' not present in BareMetalServerNetworkInterfaceByVLAN JSON')
        if 'vlan' in _dict:
            args['vlan'] = _dict.get('vlan')
        else:
            raise ValueError('Required property \'vlan\' not present in BareMetalServerNetworkInterfaceByVLAN JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a BareMetalServerNetworkInterfaceByVLAN object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'allow_ip_spoofing') and self.allow_ip_spoofing is not None:
            _dict['allow_ip_spoofing'] = self.allow_ip_spoofing
        if hasattr(self, 'created_at') and self.created_at is not None:
            _dict['created_at'] = datetime_to_string(self.created_at)
        if hasattr(self, 'enable_infrastructure_nat') and self.enable_infrastructure_nat is not None:
            _dict['enable_infrastructure_nat'] = self.enable_infrastructure_nat
        if hasattr(self, 'floating_ips') and self.floating_ips is not None:
            floating_ips_list = []
            for v in self.floating_ips:
                if isinstance(v, dict):
                    floating_ips_list.append(v)
                else:
                    floating_ips_list.append(v.to_dict())
            _dict['floating_ips'] = floating_ips_list
        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, 'mac_address') and self.mac_address is not None:
            _dict['mac_address'] = self.mac_address
        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_ip') and self.primary_ip is not None:
            if isinstance(self.primary_ip, dict):
                _dict['primary_ip'] = self.primary_ip
            else:
                _dict['primary_ip'] = self.primary_ip.to_dict()
        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:
            security_groups_list = []
            for v in self.security_groups:
                if isinstance(v, dict):
                    security_groups_list.append(v)
                else:
                    security_groups_list.append(v.to_dict())
            _dict['security_groups'] = security_groups_list
        if hasattr(self, 'status') and self.status is not None:
            _dict['status'] = self.status
        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, 'type') and self.type is not None:
            _dict['type'] = self.type
        if hasattr(self, 'allow_interface_to_float') and self.allow_interface_to_float is not None:
            _dict['allow_interface_to_float'] = self.allow_interface_to_float
        if hasattr(self, 'interface_type') and self.interface_type is not None:
            _dict['interface_type'] = self.interface_type
        if hasattr(self, 'vlan') and self.vlan is not None:
            _dict['vlan'] = self.vlan
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this BareMetalServerNetworkInterfaceByVLAN object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'BareMetalServerNetworkInterfaceByVLAN') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'BareMetalServerNetworkInterfaceByVLAN') -> 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 bare metal server network interface.
        """

        AVAILABLE = 'available'
        DELETING = 'deleting'
        FAILED = 'failed'
        PENDING = 'pending'


    class TypeEnum(str, Enum):
        """
        The bare metal server network interface type.
        """

        PRIMARY = 'primary'
        SECONDARY = 'secondary'


    class InterfaceTypeEnum(str, Enum):
        """
        - `vlan`: a virtual device, used through a `pci` device that has the `vlan` in its
        array
           of `allowed_vlans`.
          - Must use an IEEE 802.1Q tag.
          - Has its own security groups and does not inherit those of the PCI device
        through
            which traffic flows.
        """

        VLAN = 'vlan'



class BareMetalServerNetworkInterfacePrototypeBareMetalServerNetworkInterfaceByHiperSocketPrototype(BareMetalServerNetworkInterfacePrototype):
    """
    BareMetalServerNetworkInterfacePrototypeBareMetalServerNetworkInterfaceByHiperSocketPrototype.

    :attr bool allow_ip_spoofing: (optional) Indicates whether source IP spoofing is
          allowed on this bare metal server network interface.
    :attr bool enable_infrastructure_nat: (optional) If `true`:
          - The VPC infrastructure performs any needed NAT operations.
          - `floating_ips` must not have more than one floating IP.
          If `false`:
          - Packets are passed unchanged to/from the bare metal server network interface,
            allowing the workload to perform any needed NAT operations.
          - `allow_ip_spoofing` must be `false`.
          - `interface_type` must not be `hipersocket`.
    :attr str name: (optional) The name for this bare metal server network
          interface. The name must not be used by another network interface on the bare
          metal server. If unspecified, the name will be a hyphenated list of
          randomly-selected words.
    :attr NetworkInterfaceIPPrototype primary_ip: (optional) The primary IP address
          to bind to the bare metal server network interface. This can be specified using
          an existing reserved IP, or a prototype object for a new reserved IP.
          If an existing reserved IP or a prototype object with an address is specified,
          it must be available on the bare metal server network interface's subnet.
          Otherwise, an available address on the subnet will be automatically selected and
          reserved.
    :attr List[SecurityGroupIdentity] security_groups: (optional) The security
          groups to use for this bare metal server network interface. If unspecified, the
          VPC's default security group is used.
    :attr SubnetIdentity subnet: The associated subnet.
    :attr str interface_type: - `hipersocket`: a virtual network device that
          provides high-speed TCP/IP connectivity
            within a `s390x` based system.
            - Not supported on bare metal servers with a `cpu.architecture` of `amd64`.
    """

    def __init__(
        self,
        subnet: 'SubnetIdentity',
        interface_type: str,
        *,
        allow_ip_spoofing: bool = None,
        enable_infrastructure_nat: bool = None,
        name: str = None,
        primary_ip: 'NetworkInterfaceIPPrototype' = None,
        security_groups: List['SecurityGroupIdentity'] = None,
    ) -> None:
        """
        Initialize a BareMetalServerNetworkInterfacePrototypeBareMetalServerNetworkInterfaceByHiperSocketPrototype object.

        :param SubnetIdentity subnet: The associated subnet.
        :param str interface_type: - `hipersocket`: a virtual network device that
               provides high-speed TCP/IP connectivity
                 within a `s390x` based system.
                 - Not supported on bare metal servers with a `cpu.architecture` of
               `amd64`.
        :param bool allow_ip_spoofing: (optional) Indicates whether source IP
               spoofing is allowed on this bare metal server network interface.
        :param bool enable_infrastructure_nat: (optional) If `true`:
               - The VPC infrastructure performs any needed NAT operations.
               - `floating_ips` must not have more than one floating IP.
               If `false`:
               - Packets are passed unchanged to/from the bare metal server network
               interface,
                 allowing the workload to perform any needed NAT operations.
               - `allow_ip_spoofing` must be `false`.
               - `interface_type` must not be `hipersocket`.
        :param str name: (optional) The name for this bare metal server network
               interface. The name must not be used by another network interface on the
               bare metal server. If unspecified, the name will be a hyphenated list of
               randomly-selected words.
        :param NetworkInterfaceIPPrototype primary_ip: (optional) The primary IP
               address to bind to the bare metal server network interface. This can be
               specified using an existing reserved IP, or a prototype object for a new
               reserved IP.
               If an existing reserved IP or a prototype object with an address is
               specified, it must be available on the bare metal server network
               interface's subnet. Otherwise, an available address on the subnet will be
               automatically selected and reserved.
        :param List[SecurityGroupIdentity] security_groups: (optional) The security
               groups to use for this bare metal server network interface. If unspecified,
               the VPC's default security group is used.
        """
        # pylint: disable=super-init-not-called
        self.allow_ip_spoofing = allow_ip_spoofing
        self.enable_infrastructure_nat = enable_infrastructure_nat
        self.name = name
        self.primary_ip = primary_ip
        self.security_groups = security_groups
        self.subnet = subnet
        self.interface_type = interface_type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'BareMetalServerNetworkInterfacePrototypeBareMetalServerNetworkInterfaceByHiperSocketPrototype':
        """Initialize a BareMetalServerNetworkInterfacePrototypeBareMetalServerNetworkInterfaceByHiperSocketPrototype object from a json dictionary."""
        args = {}
        if 'allow_ip_spoofing' in _dict:
            args['allow_ip_spoofing'] = _dict.get('allow_ip_spoofing')
        if 'enable_infrastructure_nat' in _dict:
            args['enable_infrastructure_nat'] = _dict.get('enable_infrastructure_nat')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        if 'primary_ip' in _dict:
            args['primary_ip'] = _dict.get('primary_ip')
        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 BareMetalServerNetworkInterfacePrototypeBareMetalServerNetworkInterfaceByHiperSocketPrototype JSON')
        if 'interface_type' in _dict:
            args['interface_type'] = _dict.get('interface_type')
        else:
            raise ValueError('Required property \'interface_type\' not present in BareMetalServerNetworkInterfacePrototypeBareMetalServerNetworkInterfaceByHiperSocketPrototype JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a BareMetalServerNetworkInterfacePrototypeBareMetalServerNetworkInterfaceByHiperSocketPrototype object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'allow_ip_spoofing') and self.allow_ip_spoofing is not None:
            _dict['allow_ip_spoofing'] = self.allow_ip_spoofing
        if hasattr(self, 'enable_infrastructure_nat') and self.enable_infrastructure_nat is not None:
            _dict['enable_infrastructure_nat'] = self.enable_infrastructure_nat
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'primary_ip') and self.primary_ip is not None:
            if isinstance(self.primary_ip, dict):
                _dict['primary_ip'] = self.primary_ip
            else:
                _dict['primary_ip'] = self.primary_ip.to_dict()
        if hasattr(self, 'security_groups') and self.security_groups is not None:
            security_groups_list = []
            for v in self.security_groups:
                if isinstance(v, dict):
                    security_groups_list.append(v)
                else:
                    security_groups_list.append(v.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()
        if hasattr(self, 'interface_type') and self.interface_type is not None:
            _dict['interface_type'] = self.interface_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 BareMetalServerNetworkInterfacePrototypeBareMetalServerNetworkInterfaceByHiperSocketPrototype object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'BareMetalServerNetworkInterfacePrototypeBareMetalServerNetworkInterfaceByHiperSocketPrototype') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'BareMetalServerNetworkInterfacePrototypeBareMetalServerNetworkInterfaceByHiperSocketPrototype') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class InterfaceTypeEnum(str, Enum):
        """
        - `hipersocket`: a virtual network device that provides high-speed TCP/IP
        connectivity
          within a `s390x` based system.
          - Not supported on bare metal servers with a `cpu.architecture` of `amd64`.
        """

        HIPERSOCKET = 'hipersocket'



class BareMetalServerNetworkInterfacePrototypeBareMetalServerNetworkInterfaceByPCIPrototype(BareMetalServerNetworkInterfacePrototype):
    """
    BareMetalServerNetworkInterfacePrototypeBareMetalServerNetworkInterfaceByPCIPrototype.

    :attr bool allow_ip_spoofing: (optional) Indicates whether source IP spoofing is
          allowed on this bare metal server network interface.
    :attr bool enable_infrastructure_nat: (optional) If `true`:
          - The VPC infrastructure performs any needed NAT operations.
          - `floating_ips` must not have more than one floating IP.
          If `false`:
          - Packets are passed unchanged to/from the bare metal server network interface,
            allowing the workload to perform any needed NAT operations.
          - `allow_ip_spoofing` must be `false`.
          - `interface_type` must not be `hipersocket`.
    :attr str name: (optional) The name for this bare metal server network
          interface. The name must not be used by another network interface on the bare
          metal server. If unspecified, the name will be a hyphenated list of
          randomly-selected words.
    :attr NetworkInterfaceIPPrototype primary_ip: (optional) The primary IP address
          to bind to the bare metal server network interface. This can be specified using
          an existing reserved IP, or a prototype object for a new reserved IP.
          If an existing reserved IP or a prototype object with an address is specified,
          it must be available on the bare metal server network interface's subnet.
          Otherwise, an available address on the subnet will be automatically selected and
          reserved.
    :attr List[SecurityGroupIdentity] security_groups: (optional) The security
          groups to use for this bare metal server network interface. If unspecified, the
          VPC's default security group is used.
    :attr SubnetIdentity subnet: The associated subnet.
    :attr List[int] allowed_vlans: (optional) The VLAN IDs to allow for `vlan`
          interfaces using this PCI interface.
    :attr str interface_type: - `pci`: a physical PCI device which can only be
          created or deleted when the bare metal
            server is stopped
            - Has an `allowed_vlans` property which controls the VLANs that will be
          permitted
              to use the PCI interface
            - Cannot directly use an IEEE 802.1Q tag.
            - Not supported on bare metal servers with a `cpu.architecture` of `s390x`.
    """

    def __init__(
        self,
        subnet: 'SubnetIdentity',
        interface_type: str,
        *,
        allow_ip_spoofing: bool = None,
        enable_infrastructure_nat: bool = None,
        name: str = None,
        primary_ip: 'NetworkInterfaceIPPrototype' = None,
        security_groups: List['SecurityGroupIdentity'] = None,
        allowed_vlans: List[int] = None,
    ) -> None:
        """
        Initialize a BareMetalServerNetworkInterfacePrototypeBareMetalServerNetworkInterfaceByPCIPrototype object.

        :param SubnetIdentity subnet: The associated subnet.
        :param str interface_type: - `pci`: a physical PCI device which can only be
               created or deleted when the bare metal
                 server is stopped
                 - Has an `allowed_vlans` property which controls the VLANs that will be
               permitted
                   to use the PCI interface
                 - Cannot directly use an IEEE 802.1Q tag.
                 - Not supported on bare metal servers with a `cpu.architecture` of
               `s390x`.
        :param bool allow_ip_spoofing: (optional) Indicates whether source IP
               spoofing is allowed on this bare metal server network interface.
        :param bool enable_infrastructure_nat: (optional) If `true`:
               - The VPC infrastructure performs any needed NAT operations.
               - `floating_ips` must not have more than one floating IP.
               If `false`:
               - Packets are passed unchanged to/from the bare metal server network
               interface,
                 allowing the workload to perform any needed NAT operations.
               - `allow_ip_spoofing` must be `false`.
               - `interface_type` must not be `hipersocket`.
        :param str name: (optional) The name for this bare metal server network
               interface. The name must not be used by another network interface on the
               bare metal server. If unspecified, the name will be a hyphenated list of
               randomly-selected words.
        :param NetworkInterfaceIPPrototype primary_ip: (optional) The primary IP
               address to bind to the bare metal server network interface. This can be
               specified using an existing reserved IP, or a prototype object for a new
               reserved IP.
               If an existing reserved IP or a prototype object with an address is
               specified, it must be available on the bare metal server network
               interface's subnet. Otherwise, an available address on the subnet will be
               automatically selected and reserved.
        :param List[SecurityGroupIdentity] security_groups: (optional) The security
               groups to use for this bare metal server network interface. If unspecified,
               the VPC's default security group is used.
        :param List[int] allowed_vlans: (optional) The VLAN IDs to allow for `vlan`
               interfaces using this PCI interface.
        """
        # pylint: disable=super-init-not-called
        self.allow_ip_spoofing = allow_ip_spoofing
        self.enable_infrastructure_nat = enable_infrastructure_nat
        self.name = name
        self.primary_ip = primary_ip
        self.security_groups = security_groups
        self.subnet = subnet
        self.allowed_vlans = allowed_vlans
        self.interface_type = interface_type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'BareMetalServerNetworkInterfacePrototypeBareMetalServerNetworkInterfaceByPCIPrototype':
        """Initialize a BareMetalServerNetworkInterfacePrototypeBareMetalServerNetworkInterfaceByPCIPrototype object from a json dictionary."""
        args = {}
        if 'allow_ip_spoofing' in _dict:
            args['allow_ip_spoofing'] = _dict.get('allow_ip_spoofing')
        if 'enable_infrastructure_nat' in _dict:
            args['enable_infrastructure_nat'] = _dict.get('enable_infrastructure_nat')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        if 'primary_ip' in _dict:
            args['primary_ip'] = _dict.get('primary_ip')
        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 BareMetalServerNetworkInterfacePrototypeBareMetalServerNetworkInterfaceByPCIPrototype JSON')
        if 'allowed_vlans' in _dict:
            args['allowed_vlans'] = _dict.get('allowed_vlans')
        if 'interface_type' in _dict:
            args['interface_type'] = _dict.get('interface_type')
        else:
            raise ValueError('Required property \'interface_type\' not present in BareMetalServerNetworkInterfacePrototypeBareMetalServerNetworkInterfaceByPCIPrototype JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a BareMetalServerNetworkInterfacePrototypeBareMetalServerNetworkInterfaceByPCIPrototype object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'allow_ip_spoofing') and self.allow_ip_spoofing is not None:
            _dict['allow_ip_spoofing'] = self.allow_ip_spoofing
        if hasattr(self, 'enable_infrastructure_nat') and self.enable_infrastructure_nat is not None:
            _dict['enable_infrastructure_nat'] = self.enable_infrastructure_nat
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'primary_ip') and self.primary_ip is not None:
            if isinstance(self.primary_ip, dict):
                _dict['primary_ip'] = self.primary_ip
            else:
                _dict['primary_ip'] = self.primary_ip.to_dict()
        if hasattr(self, 'security_groups') and self.security_groups is not None:
            security_groups_list = []
            for v in self.security_groups:
                if isinstance(v, dict):
                    security_groups_list.append(v)
                else:
                    security_groups_list.append(v.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()
        if hasattr(self, 'allowed_vlans') and self.allowed_vlans is not None:
            _dict['allowed_vlans'] = self.allowed_vlans
        if hasattr(self, 'interface_type') and self.interface_type is not None:
            _dict['interface_type'] = self.interface_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 BareMetalServerNetworkInterfacePrototypeBareMetalServerNetworkInterfaceByPCIPrototype object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'BareMetalServerNetworkInterfacePrototypeBareMetalServerNetworkInterfaceByPCIPrototype') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'BareMetalServerNetworkInterfacePrototypeBareMetalServerNetworkInterfaceByPCIPrototype') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class InterfaceTypeEnum(str, Enum):
        """
        - `pci`: a physical PCI device which can only be created or deleted when the bare
        metal
          server is stopped
          - Has an `allowed_vlans` property which controls the VLANs that will be
        permitted
            to use the PCI interface
          - Cannot directly use an IEEE 802.1Q tag.
          - Not supported on bare metal servers with a `cpu.architecture` of `s390x`.
        """

        PCI = 'pci'



class BareMetalServerNetworkInterfacePrototypeBareMetalServerNetworkInterfaceByVLANPrototype(BareMetalServerNetworkInterfacePrototype):
    """
    BareMetalServerNetworkInterfacePrototypeBareMetalServerNetworkInterfaceByVLANPrototype.

    :attr bool allow_ip_spoofing: (optional) Indicates whether source IP spoofing is
          allowed on this bare metal server network interface.
    :attr bool enable_infrastructure_nat: (optional) If `true`:
          - The VPC infrastructure performs any needed NAT operations.
          - `floating_ips` must not have more than one floating IP.
          If `false`:
          - Packets are passed unchanged to/from the bare metal server network interface,
            allowing the workload to perform any needed NAT operations.
          - `allow_ip_spoofing` must be `false`.
          - `interface_type` must not be `hipersocket`.
    :attr str name: (optional) The name for this bare metal server network
          interface. The name must not be used by another network interface on the bare
          metal server. If unspecified, the name will be a hyphenated list of
          randomly-selected words.
    :attr NetworkInterfaceIPPrototype primary_ip: (optional) The primary IP address
          to bind to the bare metal server network interface. This can be specified using
          an existing reserved IP, or a prototype object for a new reserved IP.
          If an existing reserved IP or a prototype object with an address is specified,
          it must be available on the bare metal server network interface's subnet.
          Otherwise, an available address on the subnet will be automatically selected and
          reserved.
    :attr List[SecurityGroupIdentity] security_groups: (optional) The security
          groups to use for this bare metal server network interface. If unspecified, the
          VPC's default security group is used.
    :attr SubnetIdentity subnet: The associated subnet.
    :attr bool allow_interface_to_float: (optional) Indicates if the data path for
          the network interface can float to another bare metal server. Can only be `true`
          for network interfaces with an `interface_type` of `vlan`.
          If `true`, and the network detects traffic for this data path on another bare
          metal server in the resource group, the network interface will be automatically
          deleted from this bare metal server and a new network interface with the same
          `id`, `name` and `vlan` will be created on the other bare metal server.
          For the data path to float, the other bare metal server must be in the same
          `resource_group`, and must have a network interface with `interface_type` of
          `pci` with `allowed_vlans` including this network interface's `vlan`.
    :attr str interface_type: - `vlan`: a virtual device, used through a `pci`
          device that has the `vlan` in its array
             of `allowed_vlans`.
            - Must use an IEEE 802.1Q tag.
            - Has its own security groups and does not inherit those of the PCI device
          through
              which traffic flows.
            - Not supported on bare metal servers with a `cpu.architecture` of `s390x`.
    :attr int vlan: The VLAN ID used in the IEEE 802.1Q tag present in all traffic
          on this interface.
    """

    def __init__(
        self,
        subnet: 'SubnetIdentity',
        interface_type: str,
        vlan: int,
        *,
        allow_ip_spoofing: bool = None,
        enable_infrastructure_nat: bool = None,
        name: str = None,
        primary_ip: 'NetworkInterfaceIPPrototype' = None,
        security_groups: List['SecurityGroupIdentity'] = None,
        allow_interface_to_float: bool = None,
    ) -> None:
        """
        Initialize a BareMetalServerNetworkInterfacePrototypeBareMetalServerNetworkInterfaceByVLANPrototype object.

        :param SubnetIdentity subnet: The associated subnet.
        :param str interface_type: - `vlan`: a virtual device, used through a `pci`
               device that has the `vlan` in its array
                  of `allowed_vlans`.
                 - Must use an IEEE 802.1Q tag.
                 - Has its own security groups and does not inherit those of the PCI
               device through
                   which traffic flows.
                 - Not supported on bare metal servers with a `cpu.architecture` of
               `s390x`.
        :param int vlan: The VLAN ID used in the IEEE 802.1Q tag present in all
               traffic on this interface.
        :param bool allow_ip_spoofing: (optional) Indicates whether source IP
               spoofing is allowed on this bare metal server network interface.
        :param bool enable_infrastructure_nat: (optional) If `true`:
               - The VPC infrastructure performs any needed NAT operations.
               - `floating_ips` must not have more than one floating IP.
               If `false`:
               - Packets are passed unchanged to/from the bare metal server network
               interface,
                 allowing the workload to perform any needed NAT operations.
               - `allow_ip_spoofing` must be `false`.
               - `interface_type` must not be `hipersocket`.
        :param str name: (optional) The name for this bare metal server network
               interface. The name must not be used by another network interface on the
               bare metal server. If unspecified, the name will be a hyphenated list of
               randomly-selected words.
        :param NetworkInterfaceIPPrototype primary_ip: (optional) The primary IP
               address to bind to the bare metal server network interface. This can be
               specified using an existing reserved IP, or a prototype object for a new
               reserved IP.
               If an existing reserved IP or a prototype object with an address is
               specified, it must be available on the bare metal server network
               interface's subnet. Otherwise, an available address on the subnet will be
               automatically selected and reserved.
        :param List[SecurityGroupIdentity] security_groups: (optional) The security
               groups to use for this bare metal server network interface. If unspecified,
               the VPC's default security group is used.
        :param bool allow_interface_to_float: (optional) Indicates if the data path
               for the network interface can float to another bare metal server. Can only
               be `true` for network interfaces with an `interface_type` of `vlan`.
               If `true`, and the network detects traffic for this data path on another
               bare metal server in the resource group, the network interface will be
               automatically deleted from this bare metal server and a new network
               interface with the same `id`, `name` and `vlan` will be created on the
               other bare metal server.
               For the data path to float, the other bare metal server must be in the same
               `resource_group`, and must have a network interface with `interface_type`
               of `pci` with `allowed_vlans` including this network interface's `vlan`.
        """
        # pylint: disable=super-init-not-called
        self.allow_ip_spoofing = allow_ip_spoofing
        self.enable_infrastructure_nat = enable_infrastructure_nat
        self.name = name
        self.primary_ip = primary_ip
        self.security_groups = security_groups
        self.subnet = subnet
        self.allow_interface_to_float = allow_interface_to_float
        self.interface_type = interface_type
        self.vlan = vlan

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'BareMetalServerNetworkInterfacePrototypeBareMetalServerNetworkInterfaceByVLANPrototype':
        """Initialize a BareMetalServerNetworkInterfacePrototypeBareMetalServerNetworkInterfaceByVLANPrototype object from a json dictionary."""
        args = {}
        if 'allow_ip_spoofing' in _dict:
            args['allow_ip_spoofing'] = _dict.get('allow_ip_spoofing')
        if 'enable_infrastructure_nat' in _dict:
            args['enable_infrastructure_nat'] = _dict.get('enable_infrastructure_nat')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        if 'primary_ip' in _dict:
            args['primary_ip'] = _dict.get('primary_ip')
        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 BareMetalServerNetworkInterfacePrototypeBareMetalServerNetworkInterfaceByVLANPrototype JSON')
        if 'allow_interface_to_float' in _dict:
            args['allow_interface_to_float'] = _dict.get('allow_interface_to_float')
        if 'interface_type' in _dict:
            args['interface_type'] = _dict.get('interface_type')
        else:
            raise ValueError('Required property \'interface_type\' not present in BareMetalServerNetworkInterfacePrototypeBareMetalServerNetworkInterfaceByVLANPrototype JSON')
        if 'vlan' in _dict:
            args['vlan'] = _dict.get('vlan')
        else:
            raise ValueError('Required property \'vlan\' not present in BareMetalServerNetworkInterfacePrototypeBareMetalServerNetworkInterfaceByVLANPrototype JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a BareMetalServerNetworkInterfacePrototypeBareMetalServerNetworkInterfaceByVLANPrototype object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'allow_ip_spoofing') and self.allow_ip_spoofing is not None:
            _dict['allow_ip_spoofing'] = self.allow_ip_spoofing
        if hasattr(self, 'enable_infrastructure_nat') and self.enable_infrastructure_nat is not None:
            _dict['enable_infrastructure_nat'] = self.enable_infrastructure_nat
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'primary_ip') and self.primary_ip is not None:
            if isinstance(self.primary_ip, dict):
                _dict['primary_ip'] = self.primary_ip
            else:
                _dict['primary_ip'] = self.primary_ip.to_dict()
        if hasattr(self, 'security_groups') and self.security_groups is not None:
            security_groups_list = []
            for v in self.security_groups:
                if isinstance(v, dict):
                    security_groups_list.append(v)
                else:
                    security_groups_list.append(v.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()
        if hasattr(self, 'allow_interface_to_float') and self.allow_interface_to_float is not None:
            _dict['allow_interface_to_float'] = self.allow_interface_to_float
        if hasattr(self, 'interface_type') and self.interface_type is not None:
            _dict['interface_type'] = self.interface_type
        if hasattr(self, 'vlan') and self.vlan is not None:
            _dict['vlan'] = self.vlan
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this BareMetalServerNetworkInterfacePrototypeBareMetalServerNetworkInterfaceByVLANPrototype object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'BareMetalServerNetworkInterfacePrototypeBareMetalServerNetworkInterfaceByVLANPrototype') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'BareMetalServerNetworkInterfacePrototypeBareMetalServerNetworkInterfaceByVLANPrototype') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class InterfaceTypeEnum(str, Enum):
        """
        - `vlan`: a virtual device, used through a `pci` device that has the `vlan` in its
        array
           of `allowed_vlans`.
          - Must use an IEEE 802.1Q tag.
          - Has its own security groups and does not inherit those of the PCI device
        through
            which traffic flows.
          - Not supported on bare metal servers with a `cpu.architecture` of `s390x`.
        """

        VLAN = 'vlan'



class BareMetalServerProfileBandwidthDependent(BareMetalServerProfileBandwidth):
    """
    The total bandwidth shared across the bare metal server network interfaces of a bare
    metal server with this profile depends on its configuration.

    :attr str type: The type for this profile field.
    """

    def __init__(
        self,
        type: str,
    ) -> None:
        """
        Initialize a BareMetalServerProfileBandwidthDependent 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) -> 'BareMetalServerProfileBandwidthDependent':
        """Initialize a BareMetalServerProfileBandwidthDependent object from a json dictionary."""
        args = {}
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in BareMetalServerProfileBandwidthDependent JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a BareMetalServerProfileBandwidthDependent object from 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 BareMetalServerProfileBandwidthDependent object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'BareMetalServerProfileBandwidthDependent') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'BareMetalServerProfileBandwidthDependent') -> 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 BareMetalServerProfileBandwidthEnum(BareMetalServerProfileBandwidth):
    """
    The permitted total bandwidth values (in megabits per second) shared across the bare
    metal server network interfaces of a bare metal server 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 BareMetalServerProfileBandwidthEnum 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) -> 'BareMetalServerProfileBandwidthEnum':
        """Initialize a BareMetalServerProfileBandwidthEnum object from a json dictionary."""
        args = {}
        if 'default' in _dict:
            args['default'] = _dict.get('default')
        else:
            raise ValueError('Required property \'default\' not present in BareMetalServerProfileBandwidthEnum JSON')
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in BareMetalServerProfileBandwidthEnum JSON')
        if 'values' in _dict:
            args['values'] = _dict.get('values')
        else:
            raise ValueError('Required property \'values\' not present in BareMetalServerProfileBandwidthEnum JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a BareMetalServerProfileBandwidthEnum object from 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 BareMetalServerProfileBandwidthEnum object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'BareMetalServerProfileBandwidthEnum') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'BareMetalServerProfileBandwidthEnum') -> 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 BareMetalServerProfileBandwidthFixed(BareMetalServerProfileBandwidth):
    """
    The total bandwidth (in megabits per second) shared across the bare metal server
    network interfaces of a bare metal server 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 BareMetalServerProfileBandwidthFixed 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) -> 'BareMetalServerProfileBandwidthFixed':
        """Initialize a BareMetalServerProfileBandwidthFixed object from a json dictionary."""
        args = {}
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in BareMetalServerProfileBandwidthFixed JSON')
        if 'value' in _dict:
            args['value'] = _dict.get('value')
        else:
            raise ValueError('Required property \'value\' not present in BareMetalServerProfileBandwidthFixed JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a BareMetalServerProfileBandwidthFixed object from 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 BareMetalServerProfileBandwidthFixed object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'BareMetalServerProfileBandwidthFixed') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'BareMetalServerProfileBandwidthFixed') -> 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 BareMetalServerProfileBandwidthRange(BareMetalServerProfileBandwidth):
    """
    The permitted total bandwidth range (in megabits per second) shared across the bare
    metal server network interfaces of a bare metal server 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 BareMetalServerProfileBandwidthRange 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) -> 'BareMetalServerProfileBandwidthRange':
        """Initialize a BareMetalServerProfileBandwidthRange object from a json dictionary."""
        args = {}
        if 'default' in _dict:
            args['default'] = _dict.get('default')
        else:
            raise ValueError('Required property \'default\' not present in BareMetalServerProfileBandwidthRange JSON')
        if 'max' in _dict:
            args['max'] = _dict.get('max')
        else:
            raise ValueError('Required property \'max\' not present in BareMetalServerProfileBandwidthRange JSON')
        if 'min' in _dict:
            args['min'] = _dict.get('min')
        else:
            raise ValueError('Required property \'min\' not present in BareMetalServerProfileBandwidthRange JSON')
        if 'step' in _dict:
            args['step'] = _dict.get('step')
        else:
            raise ValueError('Required property \'step\' not present in BareMetalServerProfileBandwidthRange JSON')
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in BareMetalServerProfileBandwidthRange JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a BareMetalServerProfileBandwidthRange object from 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 BareMetalServerProfileBandwidthRange object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'BareMetalServerProfileBandwidthRange') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'BareMetalServerProfileBandwidthRange') -> 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 BareMetalServerProfileCPUCoreCountDependent(BareMetalServerProfileCPUCoreCount):
    """
    The CPU core count for a bare metal server with this profile depends on its
    configuration.

    :attr str type: The type for this profile field.
    """

    def __init__(
        self,
        type: str,
    ) -> None:
        """
        Initialize a BareMetalServerProfileCPUCoreCountDependent 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) -> 'BareMetalServerProfileCPUCoreCountDependent':
        """Initialize a BareMetalServerProfileCPUCoreCountDependent object from a json dictionary."""
        args = {}
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in BareMetalServerProfileCPUCoreCountDependent JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a BareMetalServerProfileCPUCoreCountDependent object from 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 BareMetalServerProfileCPUCoreCountDependent object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'BareMetalServerProfileCPUCoreCountDependent') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'BareMetalServerProfileCPUCoreCountDependent') -> 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 BareMetalServerProfileCPUCoreCountEnum(BareMetalServerProfileCPUCoreCount):
    """
    The permitted values for CPU cores for a bare metal server 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 BareMetalServerProfileCPUCoreCountEnum 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) -> 'BareMetalServerProfileCPUCoreCountEnum':
        """Initialize a BareMetalServerProfileCPUCoreCountEnum object from a json dictionary."""
        args = {}
        if 'default' in _dict:
            args['default'] = _dict.get('default')
        else:
            raise ValueError('Required property \'default\' not present in BareMetalServerProfileCPUCoreCountEnum JSON')
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in BareMetalServerProfileCPUCoreCountEnum JSON')
        if 'values' in _dict:
            args['values'] = _dict.get('values')
        else:
            raise ValueError('Required property \'values\' not present in BareMetalServerProfileCPUCoreCountEnum JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a BareMetalServerProfileCPUCoreCountEnum object from 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 BareMetalServerProfileCPUCoreCountEnum object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'BareMetalServerProfileCPUCoreCountEnum') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'BareMetalServerProfileCPUCoreCountEnum') -> 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 BareMetalServerProfileCPUCoreCountFixed(BareMetalServerProfileCPUCoreCount):
    """
    The CPU core count for a bare metal server 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 BareMetalServerProfileCPUCoreCountFixed 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) -> 'BareMetalServerProfileCPUCoreCountFixed':
        """Initialize a BareMetalServerProfileCPUCoreCountFixed object from a json dictionary."""
        args = {}
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in BareMetalServerProfileCPUCoreCountFixed JSON')
        if 'value' in _dict:
            args['value'] = _dict.get('value')
        else:
            raise ValueError('Required property \'value\' not present in BareMetalServerProfileCPUCoreCountFixed JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a BareMetalServerProfileCPUCoreCountFixed object from 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 BareMetalServerProfileCPUCoreCountFixed object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'BareMetalServerProfileCPUCoreCountFixed') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'BareMetalServerProfileCPUCoreCountFixed') -> 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 BareMetalServerProfileCPUCoreCountRange(BareMetalServerProfileCPUCoreCount):
    """
    The permitted range for the number of CPU cores for a bare metal server 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 BareMetalServerProfileCPUCoreCountRange 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) -> 'BareMetalServerProfileCPUCoreCountRange':
        """Initialize a BareMetalServerProfileCPUCoreCountRange object from a json dictionary."""
        args = {}
        if 'default' in _dict:
            args['default'] = _dict.get('default')
        else:
            raise ValueError('Required property \'default\' not present in BareMetalServerProfileCPUCoreCountRange JSON')
        if 'max' in _dict:
            args['max'] = _dict.get('max')
        else:
            raise ValueError('Required property \'max\' not present in BareMetalServerProfileCPUCoreCountRange JSON')
        if 'min' in _dict:
            args['min'] = _dict.get('min')
        else:
            raise ValueError('Required property \'min\' not present in BareMetalServerProfileCPUCoreCountRange JSON')
        if 'step' in _dict:
            args['step'] = _dict.get('step')
        else:
            raise ValueError('Required property \'step\' not present in BareMetalServerProfileCPUCoreCountRange JSON')
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in BareMetalServerProfileCPUCoreCountRange JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a BareMetalServerProfileCPUCoreCountRange object from 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 BareMetalServerProfileCPUCoreCountRange object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'BareMetalServerProfileCPUCoreCountRange') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'BareMetalServerProfileCPUCoreCountRange') -> 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 BareMetalServerProfileCPUSocketCountDependent(BareMetalServerProfileCPUSocketCount):
    """
    The CPU socket count for a bare metal server with this profile depends on its
    configuration.

    :attr str type: The type for this profile field.
    """

    def __init__(
        self,
        type: str,
    ) -> None:
        """
        Initialize a BareMetalServerProfileCPUSocketCountDependent 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) -> 'BareMetalServerProfileCPUSocketCountDependent':
        """Initialize a BareMetalServerProfileCPUSocketCountDependent object from a json dictionary."""
        args = {}
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in BareMetalServerProfileCPUSocketCountDependent JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a BareMetalServerProfileCPUSocketCountDependent object from 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 BareMetalServerProfileCPUSocketCountDependent object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'BareMetalServerProfileCPUSocketCountDependent') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'BareMetalServerProfileCPUSocketCountDependent') -> 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 BareMetalServerProfileCPUSocketCountEnum(BareMetalServerProfileCPUSocketCount):
    """
    The permitted values for CPU sockets for a bare metal server 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 BareMetalServerProfileCPUSocketCountEnum 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) -> 'BareMetalServerProfileCPUSocketCountEnum':
        """Initialize a BareMetalServerProfileCPUSocketCountEnum object from a json dictionary."""
        args = {}
        if 'default' in _dict:
            args['default'] = _dict.get('default')
        else:
            raise ValueError('Required property \'default\' not present in BareMetalServerProfileCPUSocketCountEnum JSON')
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in BareMetalServerProfileCPUSocketCountEnum JSON')
        if 'values' in _dict:
            args['values'] = _dict.get('values')
        else:
            raise ValueError('Required property \'values\' not present in BareMetalServerProfileCPUSocketCountEnum JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a BareMetalServerProfileCPUSocketCountEnum object from 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 BareMetalServerProfileCPUSocketCountEnum object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'BareMetalServerProfileCPUSocketCountEnum') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'BareMetalServerProfileCPUSocketCountEnum') -> 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 BareMetalServerProfileCPUSocketCountFixed(BareMetalServerProfileCPUSocketCount):
    """
    The number of CPU sockets for a bare metal server 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 BareMetalServerProfileCPUSocketCountFixed 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) -> 'BareMetalServerProfileCPUSocketCountFixed':
        """Initialize a BareMetalServerProfileCPUSocketCountFixed object from a json dictionary."""
        args = {}
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in BareMetalServerProfileCPUSocketCountFixed JSON')
        if 'value' in _dict:
            args['value'] = _dict.get('value')
        else:
            raise ValueError('Required property \'value\' not present in BareMetalServerProfileCPUSocketCountFixed JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a BareMetalServerProfileCPUSocketCountFixed object from 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 BareMetalServerProfileCPUSocketCountFixed object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'BareMetalServerProfileCPUSocketCountFixed') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'BareMetalServerProfileCPUSocketCountFixed') -> 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 BareMetalServerProfileCPUSocketCountRange(BareMetalServerProfileCPUSocketCount):
    """
    The permitted range for the number of CPU sockets for a bare metal server 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 BareMetalServerProfileCPUSocketCountRange 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) -> 'BareMetalServerProfileCPUSocketCountRange':
        """Initialize a BareMetalServerProfileCPUSocketCountRange object from a json dictionary."""
        args = {}
        if 'default' in _dict:
            args['default'] = _dict.get('default')
        else:
            raise ValueError('Required property \'default\' not present in BareMetalServerProfileCPUSocketCountRange JSON')
        if 'max' in _dict:
            args['max'] = _dict.get('max')
        else:
            raise ValueError('Required property \'max\' not present in BareMetalServerProfileCPUSocketCountRange JSON')
        if 'min' in _dict:
            args['min'] = _dict.get('min')
        else:
            raise ValueError('Required property \'min\' not present in BareMetalServerProfileCPUSocketCountRange JSON')
        if 'step' in _dict:
            args['step'] = _dict.get('step')
        else:
            raise ValueError('Required property \'step\' not present in BareMetalServerProfileCPUSocketCountRange JSON')
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in BareMetalServerProfileCPUSocketCountRange JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a BareMetalServerProfileCPUSocketCountRange object from 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 BareMetalServerProfileCPUSocketCountRange object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'BareMetalServerProfileCPUSocketCountRange') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'BareMetalServerProfileCPUSocketCountRange') -> 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 BareMetalServerProfileDiskQuantityDependent(BareMetalServerProfileDiskQuantity):
    """
    The number of disks of this configuration for a bare metal server with this profile
    depends on its bare metal server configuration.

    :attr str type: The type for this profile field.
    """

    def __init__(
        self,
        type: str,
    ) -> None:
        """
        Initialize a BareMetalServerProfileDiskQuantityDependent 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) -> 'BareMetalServerProfileDiskQuantityDependent':
        """Initialize a BareMetalServerProfileDiskQuantityDependent object from a json dictionary."""
        args = {}
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in BareMetalServerProfileDiskQuantityDependent JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a BareMetalServerProfileDiskQuantityDependent object from 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 BareMetalServerProfileDiskQuantityDependent object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'BareMetalServerProfileDiskQuantityDependent') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'BareMetalServerProfileDiskQuantityDependent') -> 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 BareMetalServerProfileDiskQuantityEnum(BareMetalServerProfileDiskQuantity):
    """
    The permitted the number of disks of this configuration for a bare metal server 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 BareMetalServerProfileDiskQuantityEnum 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) -> 'BareMetalServerProfileDiskQuantityEnum':
        """Initialize a BareMetalServerProfileDiskQuantityEnum object from a json dictionary."""
        args = {}
        if 'default' in _dict:
            args['default'] = _dict.get('default')
        else:
            raise ValueError('Required property \'default\' not present in BareMetalServerProfileDiskQuantityEnum JSON')
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in BareMetalServerProfileDiskQuantityEnum JSON')
        if 'values' in _dict:
            args['values'] = _dict.get('values')
        else:
            raise ValueError('Required property \'values\' not present in BareMetalServerProfileDiskQuantityEnum JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a BareMetalServerProfileDiskQuantityEnum object from 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 BareMetalServerProfileDiskQuantityEnum object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'BareMetalServerProfileDiskQuantityEnum') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'BareMetalServerProfileDiskQuantityEnum') -> 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 BareMetalServerProfileDiskQuantityFixed(BareMetalServerProfileDiskQuantity):
    """
    The number of disks of this configuration for a bare metal server 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 BareMetalServerProfileDiskQuantityFixed 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) -> 'BareMetalServerProfileDiskQuantityFixed':
        """Initialize a BareMetalServerProfileDiskQuantityFixed object from a json dictionary."""
        args = {}
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in BareMetalServerProfileDiskQuantityFixed JSON')
        if 'value' in _dict:
            args['value'] = _dict.get('value')
        else:
            raise ValueError('Required property \'value\' not present in BareMetalServerProfileDiskQuantityFixed JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a BareMetalServerProfileDiskQuantityFixed object from 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 BareMetalServerProfileDiskQuantityFixed object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'BareMetalServerProfileDiskQuantityFixed') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'BareMetalServerProfileDiskQuantityFixed') -> 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 BareMetalServerProfileDiskQuantityRange(BareMetalServerProfileDiskQuantity):
    """
    The permitted range for the number of disks of this configuration for a bare metal
    server 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 BareMetalServerProfileDiskQuantityRange 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) -> 'BareMetalServerProfileDiskQuantityRange':
        """Initialize a BareMetalServerProfileDiskQuantityRange object from a json dictionary."""
        args = {}
        if 'default' in _dict:
            args['default'] = _dict.get('default')
        else:
            raise ValueError('Required property \'default\' not present in BareMetalServerProfileDiskQuantityRange JSON')
        if 'max' in _dict:
            args['max'] = _dict.get('max')
        else:
            raise ValueError('Required property \'max\' not present in BareMetalServerProfileDiskQuantityRange JSON')
        if 'min' in _dict:
            args['min'] = _dict.get('min')
        else:
            raise ValueError('Required property \'min\' not present in BareMetalServerProfileDiskQuantityRange JSON')
        if 'step' in _dict:
            args['step'] = _dict.get('step')
        else:
            raise ValueError('Required property \'step\' not present in BareMetalServerProfileDiskQuantityRange JSON')
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in BareMetalServerProfileDiskQuantityRange JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a BareMetalServerProfileDiskQuantityRange object from 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 BareMetalServerProfileDiskQuantityRange object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'BareMetalServerProfileDiskQuantityRange') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'BareMetalServerProfileDiskQuantityRange') -> 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 BareMetalServerProfileDiskSizeDependent(BareMetalServerProfileDiskSize):
    """
    The disk size in GB (gigabytes) of this configuration for a bare metal server with
    this profile depends on its bare metal server configuration.

    :attr str type: The type for this profile field.
    """

    def __init__(
        self,
        type: str,
    ) -> None:
        """
        Initialize a BareMetalServerProfileDiskSizeDependent 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) -> 'BareMetalServerProfileDiskSizeDependent':
        """Initialize a BareMetalServerProfileDiskSizeDependent object from a json dictionary."""
        args = {}
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in BareMetalServerProfileDiskSizeDependent JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a BareMetalServerProfileDiskSizeDependent object from 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 BareMetalServerProfileDiskSizeDependent object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'BareMetalServerProfileDiskSizeDependent') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'BareMetalServerProfileDiskSizeDependent') -> 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 BareMetalServerProfileDiskSizeEnum(BareMetalServerProfileDiskSize):
    """
    The permitted disk size in GB (gigabytes) of this configuration for a bare metal
    server 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 BareMetalServerProfileDiskSizeEnum 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) -> 'BareMetalServerProfileDiskSizeEnum':
        """Initialize a BareMetalServerProfileDiskSizeEnum object from a json dictionary."""
        args = {}
        if 'default' in _dict:
            args['default'] = _dict.get('default')
        else:
            raise ValueError('Required property \'default\' not present in BareMetalServerProfileDiskSizeEnum JSON')
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in BareMetalServerProfileDiskSizeEnum JSON')
        if 'values' in _dict:
            args['values'] = _dict.get('values')
        else:
            raise ValueError('Required property \'values\' not present in BareMetalServerProfileDiskSizeEnum JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a BareMetalServerProfileDiskSizeEnum object from 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 BareMetalServerProfileDiskSizeEnum object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'BareMetalServerProfileDiskSizeEnum') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'BareMetalServerProfileDiskSizeEnum') -> 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 BareMetalServerProfileDiskSizeFixed(BareMetalServerProfileDiskSize):
    """
    The size of the disk in GB (gigabytes).

    :attr str type: The type for this profile field.
    :attr int value: The value for this profile field.
    """

    def __init__(
        self,
        type: str,
        value: int,
    ) -> None:
        """
        Initialize a BareMetalServerProfileDiskSizeFixed 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) -> 'BareMetalServerProfileDiskSizeFixed':
        """Initialize a BareMetalServerProfileDiskSizeFixed object from a json dictionary."""
        args = {}
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in BareMetalServerProfileDiskSizeFixed JSON')
        if 'value' in _dict:
            args['value'] = _dict.get('value')
        else:
            raise ValueError('Required property \'value\' not present in BareMetalServerProfileDiskSizeFixed JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a BareMetalServerProfileDiskSizeFixed object from 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 BareMetalServerProfileDiskSizeFixed object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'BareMetalServerProfileDiskSizeFixed') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'BareMetalServerProfileDiskSizeFixed') -> 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 BareMetalServerProfileDiskSizeRange(BareMetalServerProfileDiskSize):
    """
    The permitted range for the disk size of this configuration in GB (gigabytes) for a
    bare metal server 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 BareMetalServerProfileDiskSizeRange 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) -> 'BareMetalServerProfileDiskSizeRange':
        """Initialize a BareMetalServerProfileDiskSizeRange object from a json dictionary."""
        args = {}
        if 'default' in _dict:
            args['default'] = _dict.get('default')
        else:
            raise ValueError('Required property \'default\' not present in BareMetalServerProfileDiskSizeRange JSON')
        if 'max' in _dict:
            args['max'] = _dict.get('max')
        else:
            raise ValueError('Required property \'max\' not present in BareMetalServerProfileDiskSizeRange JSON')
        if 'min' in _dict:
            args['min'] = _dict.get('min')
        else:
            raise ValueError('Required property \'min\' not present in BareMetalServerProfileDiskSizeRange JSON')
        if 'step' in _dict:
            args['step'] = _dict.get('step')
        else:
            raise ValueError('Required property \'step\' not present in BareMetalServerProfileDiskSizeRange JSON')
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in BareMetalServerProfileDiskSizeRange JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a BareMetalServerProfileDiskSizeRange object from 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 BareMetalServerProfileDiskSizeRange object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'BareMetalServerProfileDiskSizeRange') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'BareMetalServerProfileDiskSizeRange') -> 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 BareMetalServerProfileIdentityByHref(BareMetalServerProfileIdentity):
    """
    BareMetalServerProfileIdentityByHref.

    :attr str href: The URL for this bare metal server profile.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a BareMetalServerProfileIdentityByHref object.

        :param str href: The URL for this bare metal server profile.
        """
        # pylint: disable=super-init-not-called
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'BareMetalServerProfileIdentityByHref':
        """Initialize a BareMetalServerProfileIdentityByHref object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in BareMetalServerProfileIdentityByHref JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a BareMetalServerProfileIdentityByHref object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(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 BareMetalServerProfileIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'BareMetalServerProfileIdentityByHref') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'BareMetalServerProfileIdentityByHref') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class BareMetalServerProfileIdentityByName(BareMetalServerProfileIdentity):
    """
    BareMetalServerProfileIdentityByName.

    :attr str name: The name for this bare metal server profile.
    """

    def __init__(
        self,
        name: str,
    ) -> None:
        """
        Initialize a BareMetalServerProfileIdentityByName object.

        :param str name: The name for this bare metal server profile.
        """
        # pylint: disable=super-init-not-called
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'BareMetalServerProfileIdentityByName':
        """Initialize a BareMetalServerProfileIdentityByName object from a json dictionary."""
        args = {}
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in BareMetalServerProfileIdentityByName JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a BareMetalServerProfileIdentityByName object from 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 BareMetalServerProfileIdentityByName object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'BareMetalServerProfileIdentityByName') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'BareMetalServerProfileIdentityByName') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class BareMetalServerProfileMemoryDependent(BareMetalServerProfileMemory):
    """
    The memory value for a bare metal server with this profile depends on its
    configuration.

    :attr str type: The type for this profile field.
    """

    def __init__(
        self,
        type: str,
    ) -> None:
        """
        Initialize a BareMetalServerProfileMemoryDependent 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) -> 'BareMetalServerProfileMemoryDependent':
        """Initialize a BareMetalServerProfileMemoryDependent object from a json dictionary."""
        args = {}
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in BareMetalServerProfileMemoryDependent JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a BareMetalServerProfileMemoryDependent object from 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 BareMetalServerProfileMemoryDependent object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'BareMetalServerProfileMemoryDependent') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'BareMetalServerProfileMemoryDependent') -> 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 BareMetalServerProfileMemoryEnum(BareMetalServerProfileMemory):
    """
    The permitted memory values (in gibibytes) for a bare metal server 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 BareMetalServerProfileMemoryEnum 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) -> 'BareMetalServerProfileMemoryEnum':
        """Initialize a BareMetalServerProfileMemoryEnum object from a json dictionary."""
        args = {}
        if 'default' in _dict:
            args['default'] = _dict.get('default')
        else:
            raise ValueError('Required property \'default\' not present in BareMetalServerProfileMemoryEnum JSON')
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in BareMetalServerProfileMemoryEnum JSON')
        if 'values' in _dict:
            args['values'] = _dict.get('values')
        else:
            raise ValueError('Required property \'values\' not present in BareMetalServerProfileMemoryEnum JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a BareMetalServerProfileMemoryEnum object from 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 BareMetalServerProfileMemoryEnum object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'BareMetalServerProfileMemoryEnum') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'BareMetalServerProfileMemoryEnum') -> 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 BareMetalServerProfileMemoryFixed(BareMetalServerProfileMemory):
    """
    The memory (in gibibytes) for a bare metal server 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 BareMetalServerProfileMemoryFixed 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) -> 'BareMetalServerProfileMemoryFixed':
        """Initialize a BareMetalServerProfileMemoryFixed object from a json dictionary."""
        args = {}
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in BareMetalServerProfileMemoryFixed JSON')
        if 'value' in _dict:
            args['value'] = _dict.get('value')
        else:
            raise ValueError('Required property \'value\' not present in BareMetalServerProfileMemoryFixed JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a BareMetalServerProfileMemoryFixed object from 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 BareMetalServerProfileMemoryFixed object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'BareMetalServerProfileMemoryFixed') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'BareMetalServerProfileMemoryFixed') -> 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 BareMetalServerProfileMemoryRange(BareMetalServerProfileMemory):
    """
    The permitted memory range (in gibibytes) for a bare metal server 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 BareMetalServerProfileMemoryRange 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) -> 'BareMetalServerProfileMemoryRange':
        """Initialize a BareMetalServerProfileMemoryRange object from a json dictionary."""
        args = {}
        if 'default' in _dict:
            args['default'] = _dict.get('default')
        else:
            raise ValueError('Required property \'default\' not present in BareMetalServerProfileMemoryRange JSON')
        if 'max' in _dict:
            args['max'] = _dict.get('max')
        else:
            raise ValueError('Required property \'max\' not present in BareMetalServerProfileMemoryRange JSON')
        if 'min' in _dict:
            args['min'] = _dict.get('min')
        else:
            raise ValueError('Required property \'min\' not present in BareMetalServerProfileMemoryRange JSON')
        if 'step' in _dict:
            args['step'] = _dict.get('step')
        else:
            raise ValueError('Required property \'step\' not present in BareMetalServerProfileMemoryRange JSON')
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in BareMetalServerProfileMemoryRange JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a BareMetalServerProfileMemoryRange object from 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 BareMetalServerProfileMemoryRange object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'BareMetalServerProfileMemoryRange') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'BareMetalServerProfileMemoryRange') -> 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 BareMetalServerProfileNetworkInterfaceCountDependent(BareMetalServerProfileNetworkInterfaceCount):
    """
    The number of bare metal server network interfaces supported on a bare metal server
    with this profile is dependent on its configuration.

    :attr str type: The type for this profile field.
    """

    def __init__(
        self,
        type: str,
    ) -> None:
        """
        Initialize a BareMetalServerProfileNetworkInterfaceCountDependent 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) -> 'BareMetalServerProfileNetworkInterfaceCountDependent':
        """Initialize a BareMetalServerProfileNetworkInterfaceCountDependent object from a json dictionary."""
        args = {}
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in BareMetalServerProfileNetworkInterfaceCountDependent JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a BareMetalServerProfileNetworkInterfaceCountDependent object from 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 BareMetalServerProfileNetworkInterfaceCountDependent object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'BareMetalServerProfileNetworkInterfaceCountDependent') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'BareMetalServerProfileNetworkInterfaceCountDependent') -> 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 BareMetalServerProfileNetworkInterfaceCountRange(BareMetalServerProfileNetworkInterfaceCount):
    """
    The number of bare metal server network interfaces supported on a bare metal server
    with this profile.

    :attr int max: (optional) The maximum value for this profile field.
    :attr int min: (optional) The minimum value for this profile field.
    :attr str type: The type for this profile field.
    """

    def __init__(
        self,
        type: str,
        *,
        max: int = None,
        min: int = None,
    ) -> None:
        """
        Initialize a BareMetalServerProfileNetworkInterfaceCountRange object.

        :param str type: The type for this profile field.
        :param int max: (optional) The maximum value for this profile field.
        :param int min: (optional) The minimum value for this profile field.
        """
        # pylint: disable=super-init-not-called
        self.max = max
        self.min = min
        self.type = type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'BareMetalServerProfileNetworkInterfaceCountRange':
        """Initialize a BareMetalServerProfileNetworkInterfaceCountRange object from a json dictionary."""
        args = {}
        if 'max' in _dict:
            args['max'] = _dict.get('max')
        if 'min' in _dict:
            args['min'] = _dict.get('min')
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in BareMetalServerProfileNetworkInterfaceCountRange JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a BareMetalServerProfileNetworkInterfaceCountRange object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'max') 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, '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 BareMetalServerProfileNetworkInterfaceCountRange object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'BareMetalServerProfileNetworkInterfaceCountRange') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'BareMetalServerProfileNetworkInterfaceCountRange') -> 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 CatalogOfferingIdentityCatalogOfferingByCRN(CatalogOfferingIdentity):
    """
    CatalogOfferingIdentityCatalogOfferingByCRN.

    :attr str crn: The CRN for this
          [catalog](https://cloud.ibm.com/docs/account?topic=account-restrict-by-user)
          offering.
    """

    def __init__(
        self,
        crn: str,
    ) -> None:
        """
        Initialize a CatalogOfferingIdentityCatalogOfferingByCRN object.

        :param str crn: The CRN for this
               [catalog](https://cloud.ibm.com/docs/account?topic=account-restrict-by-user)
               offering.
        """
        # pylint: disable=super-init-not-called
        self.crn = crn

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'CatalogOfferingIdentityCatalogOfferingByCRN':
        """Initialize a CatalogOfferingIdentityCatalogOfferingByCRN object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError('Required property \'crn\' not present in CatalogOfferingIdentityCatalogOfferingByCRN JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a CatalogOfferingIdentityCatalogOfferingByCRN object from 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 CatalogOfferingIdentityCatalogOfferingByCRN object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'CatalogOfferingIdentityCatalogOfferingByCRN') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'CatalogOfferingIdentityCatalogOfferingByCRN') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class CatalogOfferingVersionIdentityCatalogOfferingVersionByCRN(CatalogOfferingVersionIdentity):
    """
    CatalogOfferingVersionIdentityCatalogOfferingVersionByCRN.

    :attr str crn: The CRN for this version of a
          [catalog](https://cloud.ibm.com/docs/account?topic=account-restrict-by-user)
          offering.
    """

    def __init__(
        self,
        crn: str,
    ) -> None:
        """
        Initialize a CatalogOfferingVersionIdentityCatalogOfferingVersionByCRN object.

        :param str crn: The CRN for this version of a
               [catalog](https://cloud.ibm.com/docs/account?topic=account-restrict-by-user)
               offering.
        """
        # pylint: disable=super-init-not-called
        self.crn = crn

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'CatalogOfferingVersionIdentityCatalogOfferingVersionByCRN':
        """Initialize a CatalogOfferingVersionIdentityCatalogOfferingVersionByCRN object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError('Required property \'crn\' not present in CatalogOfferingVersionIdentityCatalogOfferingVersionByCRN JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a CatalogOfferingVersionIdentityCatalogOfferingVersionByCRN object from 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 CatalogOfferingVersionIdentityCatalogOfferingVersionByCRN object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'CatalogOfferingVersionIdentityCatalogOfferingVersionByCRN') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'CatalogOfferingVersionIdentityCatalogOfferingVersionByCRN') -> 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 CloudObjectStorageBucketIdentityByCRN(CloudObjectStorageBucketIdentity):
    """
    CloudObjectStorageBucketIdentityByCRN.

    :attr str crn: The CRN of this Cloud Object Storage bucket.
    """

    def __init__(
        self,
        crn: str,
    ) -> None:
        """
        Initialize a CloudObjectStorageBucketIdentityByCRN object.

        :param str crn: The CRN of this Cloud Object Storage bucket.
        """
        # pylint: disable=super-init-not-called
        self.crn = crn

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'CloudObjectStorageBucketIdentityByCRN':
        """Initialize a CloudObjectStorageBucketIdentityByCRN object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError('Required property \'crn\' not present in CloudObjectStorageBucketIdentityByCRN JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a CloudObjectStorageBucketIdentityByCRN object from 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 CloudObjectStorageBucketIdentityByCRN object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'CloudObjectStorageBucketIdentityByCRN') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'CloudObjectStorageBucketIdentityByCRN') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class CloudObjectStorageBucketIdentityCloudObjectStorageBucketIdentityByName(CloudObjectStorageBucketIdentity):
    """
    CloudObjectStorageBucketIdentityCloudObjectStorageBucketIdentityByName.

    :attr str name: The globally unique name of this Cloud Object Storage bucket.
    """

    def __init__(
        self,
        name: str,
    ) -> None:
        """
        Initialize a CloudObjectStorageBucketIdentityCloudObjectStorageBucketIdentityByName object.

        :param str name: The globally unique name of this Cloud Object Storage
               bucket.
        """
        # pylint: disable=super-init-not-called
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'CloudObjectStorageBucketIdentityCloudObjectStorageBucketIdentityByName':
        """Initialize a CloudObjectStorageBucketIdentityCloudObjectStorageBucketIdentityByName object from a json dictionary."""
        args = {}
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in CloudObjectStorageBucketIdentityCloudObjectStorageBucketIdentityByName JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a CloudObjectStorageBucketIdentityCloudObjectStorageBucketIdentityByName object from 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 CloudObjectStorageBucketIdentityCloudObjectStorageBucketIdentityByName object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'CloudObjectStorageBucketIdentityCloudObjectStorageBucketIdentityByName') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'CloudObjectStorageBucketIdentityCloudObjectStorageBucketIdentityByName') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class DNSInstanceIdentityByCRN(DNSInstanceIdentity):
    """
    DNSInstanceIdentityByCRN.

    :attr str crn: The CRN for this DNS instance.
    """

    def __init__(
        self,
        crn: str,
    ) -> None:
        """
        Initialize a DNSInstanceIdentityByCRN object.

        :param str crn: The CRN for this DNS instance.
        """
        # pylint: disable=super-init-not-called
        self.crn = crn

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'DNSInstanceIdentityByCRN':
        """Initialize a DNSInstanceIdentityByCRN object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError('Required property \'crn\' not present in DNSInstanceIdentityByCRN JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a DNSInstanceIdentityByCRN object from 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 DNSInstanceIdentityByCRN object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'DNSInstanceIdentityByCRN') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'DNSInstanceIdentityByCRN') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class DNSZoneIdentityById(DNSZoneIdentity):
    """
    DNSZoneIdentityById.

    :attr str id:
    """

    def __init__(
        self,
        id: str,
    ) -> None:
        """
        Initialize a DNSZoneIdentityById object.

        :param str id:
        """
        # pylint: disable=super-init-not-called
        self.id = id

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'DNSZoneIdentityById':
        """Initialize a DNSZoneIdentityById object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in DNSZoneIdentityById JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a DNSZoneIdentityById object from 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 DNSZoneIdentityById object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'DNSZoneIdentityById') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'DNSZoneIdentityById') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class DedicatedHostGroupIdentityByCRN(DedicatedHostGroupIdentity):
    """
    DedicatedHostGroupIdentityByCRN.

    :attr str crn: The CRN for this dedicated host group.
    """

    def __init__(
        self,
        crn: str,
    ) -> None:
        """
        Initialize a DedicatedHostGroupIdentityByCRN object.

        :param str crn: The CRN for this dedicated host group.
        """
        # pylint: disable=super-init-not-called
        self.crn = crn

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'DedicatedHostGroupIdentityByCRN':
        """Initialize a DedicatedHostGroupIdentityByCRN object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError('Required property \'crn\' not present in DedicatedHostGroupIdentityByCRN JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a DedicatedHostGroupIdentityByCRN object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this DedicatedHostGroupIdentityByCRN object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'DedicatedHostGroupIdentityByCRN') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'DedicatedHostGroupIdentityByCRN') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class DedicatedHostGroupIdentityByHref(DedicatedHostGroupIdentity):
    """
    DedicatedHostGroupIdentityByHref.

    :attr str href: The URL for this dedicated host group.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a DedicatedHostGroupIdentityByHref object.

        :param str href: The URL for this dedicated host group.
        """
        # pylint: disable=super-init-not-called
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'DedicatedHostGroupIdentityByHref':
        """Initialize a DedicatedHostGroupIdentityByHref object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in DedicatedHostGroupIdentityByHref JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a DedicatedHostGroupIdentityByHref object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this DedicatedHostGroupIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'DedicatedHostGroupIdentityByHref') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'DedicatedHostGroupIdentityByHref') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class DedicatedHostGroupIdentityById(DedicatedHostGroupIdentity):
    """
    DedicatedHostGroupIdentityById.

    :attr str id: The unique identifier for this dedicated host group.
    """

    def __init__(
        self,
        id: str,
    ) -> None:
        """
        Initialize a DedicatedHostGroupIdentityById object.

        :param str id: The unique identifier for this dedicated host group.
        """
        # pylint: disable=super-init-not-called
        self.id = id

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'DedicatedHostGroupIdentityById':
        """Initialize a DedicatedHostGroupIdentityById object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in DedicatedHostGroupIdentityById JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a DedicatedHostGroupIdentityById object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this DedicatedHostGroupIdentityById object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'DedicatedHostGroupIdentityById') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'DedicatedHostGroupIdentityById') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class DedicatedHostProfileIdentityByHref(DedicatedHostProfileIdentity):
    """
    DedicatedHostProfileIdentityByHref.

    :attr str href: The URL for this dedicated host profile.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a DedicatedHostProfileIdentityByHref object.

        :param str href: The URL for this dedicated host profile.
        """
        # pylint: disable=super-init-not-called
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'DedicatedHostProfileIdentityByHref':
        """Initialize a DedicatedHostProfileIdentityByHref object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in DedicatedHostProfileIdentityByHref JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a DedicatedHostProfileIdentityByHref object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this DedicatedHostProfileIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'DedicatedHostProfileIdentityByHref') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'DedicatedHostProfileIdentityByHref') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class DedicatedHostProfileIdentityByName(DedicatedHostProfileIdentity):
    """
    DedicatedHostProfileIdentityByName.

    :attr str name: The globally unique name for this dedicated host profile.
    """

    def __init__(
        self,
        name: str,
    ) -> None:
        """
        Initialize a DedicatedHostProfileIdentityByName object.

        :param str name: The globally unique name for this dedicated host profile.
        """
        # pylint: disable=super-init-not-called
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'DedicatedHostProfileIdentityByName':
        """Initialize a DedicatedHostProfileIdentityByName object from a json dictionary."""
        args = {}
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in DedicatedHostProfileIdentityByName JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a DedicatedHostProfileIdentityByName object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this DedicatedHostProfileIdentityByName object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'DedicatedHostProfileIdentityByName') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'DedicatedHostProfileIdentityByName') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class DedicatedHostProfileMemoryDependent(DedicatedHostProfileMemory):
    """
    The memory value for a dedicated host with this profile depends on its configuration.

    :attr str type: The type for this profile field.
    """

    def __init__(
        self,
        type: str,
    ) -> None:
        """
        Initialize a DedicatedHostProfileMemoryDependent object.

        :param str type: The type for this profile field.
        """
        # pylint: disable=super-init-not-called
        self.type = type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'DedicatedHostProfileMemoryDependent':
        """Initialize a DedicatedHostProfileMemoryDependent object from a json dictionary."""
        args = {}
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in DedicatedHostProfileMemoryDependent JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a DedicatedHostProfileMemoryDependent object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'type') and self.type is not None:
            _dict['type'] = self.type
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this DedicatedHostProfileMemoryDependent object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'DedicatedHostProfileMemoryDependent') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'DedicatedHostProfileMemoryDependent') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class TypeEnum(str, Enum):
        """
        The type for this profile field.
        """

        DEPENDENT = 'dependent'



class DedicatedHostProfileMemoryEnum(DedicatedHostProfileMemory):
    """
    The permitted memory values (in gibibytes) for a dedicated host with this profile.

    :attr int default: The default value for this profile field.
    :attr str type: The type for this profile field.
    :attr List[int] values: The permitted values for this profile field.
    """

    def __init__(
        self,
        default: int,
        type: str,
        values: List[int],
    ) -> None:
        """
        Initialize a DedicatedHostProfileMemoryEnum object.

        :param int default: The default value for this profile field.
        :param str type: The type for this profile field.
        :param List[int] values: The permitted values for this profile field.
        """
        # pylint: disable=super-init-not-called
        self.default = default
        self.type = type
        self.values = values

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'DedicatedHostProfileMemoryEnum':
        """Initialize a DedicatedHostProfileMemoryEnum object from a json dictionary."""
        args = {}
        if 'default' in _dict:
            args['default'] = _dict.get('default')
        else:
            raise ValueError('Required property \'default\' not present in DedicatedHostProfileMemoryEnum JSON')
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in DedicatedHostProfileMemoryEnum JSON')
        if 'values' in _dict:
            args['values'] = _dict.get('values')
        else:
            raise ValueError('Required property \'values\' not present in DedicatedHostProfileMemoryEnum JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a DedicatedHostProfileMemoryEnum object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'default') and self.default is not None:
            _dict['default'] = self.default
        if hasattr(self, 'type') and self.type is not None:
            _dict['type'] = self.type
        if hasattr(self, 'values') and self.values is not None:
            _dict['values'] = self.values
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this DedicatedHostProfileMemoryEnum object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'DedicatedHostProfileMemoryEnum') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'DedicatedHostProfileMemoryEnum') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class TypeEnum(str, Enum):
        """
        The type for this profile field.
        """

        ENUM = 'enum'



class DedicatedHostProfileMemoryFixed(DedicatedHostProfileMemory):
    """
    The memory (in gibibytes) for a dedicated host with this profile.

    :attr str type: The type for this profile field.
    :attr int value: The value for this profile field.
    """

    def __init__(
        self,
        type: str,
        value: int,
    ) -> None:
        """
        Initialize a DedicatedHostProfileMemoryFixed object.

        :param str type: The type for this profile field.
        :param int value: The value for this profile field.
        """
        # pylint: disable=super-init-not-called
        self.type = type
        self.value = value

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'DedicatedHostProfileMemoryFixed':
        """Initialize a DedicatedHostProfileMemoryFixed object from a json dictionary."""
        args = {}
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in DedicatedHostProfileMemoryFixed JSON')
        if 'value' in _dict:
            args['value'] = _dict.get('value')
        else:
            raise ValueError('Required property \'value\' not present in DedicatedHostProfileMemoryFixed JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a DedicatedHostProfileMemoryFixed object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'type') and self.type is not None:
            _dict['type'] = self.type
        if hasattr(self, 'value') and self.value is not None:
            _dict['value'] = self.value
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this DedicatedHostProfileMemoryFixed object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'DedicatedHostProfileMemoryFixed') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'DedicatedHostProfileMemoryFixed') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class TypeEnum(str, Enum):
        """
        The type for this profile field.
        """

        FIXED = 'fixed'



class DedicatedHostProfileMemoryRange(DedicatedHostProfileMemory):
    """
    The permitted memory range (in gibibytes) for a dedicated host with this profile.

    :attr int default: The default value for this profile field.
    :attr int max: The maximum value for this profile field.
    :attr int min: The minimum value for this profile field.
    :attr int step: The increment step value for this profile field.
    :attr str type: The type for this profile field.
    """

    def __init__(
        self,
        default: int,
        max: int,
        min: int,
        step: int,
        type: str,
    ) -> None:
        """
        Initialize a DedicatedHostProfileMemoryRange object.

        :param int default: The default value for this profile field.
        :param int max: The maximum value for this profile field.
        :param int min: The minimum value for this profile field.
        :param int step: The increment step value for this profile field.
        :param str type: The type for this profile field.
        """
        # pylint: disable=super-init-not-called
        self.default = default
        self.max = max
        self.min = min
        self.step = step
        self.type = type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'DedicatedHostProfileMemoryRange':
        """Initialize a DedicatedHostProfileMemoryRange object from a json dictionary."""
        args = {}
        if 'default' in _dict:
            args['default'] = _dict.get('default')
        else:
            raise ValueError('Required property \'default\' not present in DedicatedHostProfileMemoryRange JSON')
        if 'max' in _dict:
            args['max'] = _dict.get('max')
        else:
            raise ValueError('Required property \'max\' not present in DedicatedHostProfileMemoryRange JSON')
        if 'min' in _dict:
            args['min'] = _dict.get('min')
        else:
            raise ValueError('Required property \'min\' not present in DedicatedHostProfileMemoryRange JSON')
        if 'step' in _dict:
            args['step'] = _dict.get('step')
        else:
            raise ValueError('Required property \'step\' not present in DedicatedHostProfileMemoryRange JSON')
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in DedicatedHostProfileMemoryRange JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a DedicatedHostProfileMemoryRange object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'default') and self.default is not None:
            _dict['default'] = self.default
        if hasattr(self, 'max') and self.max is not None:
            _dict['max'] = self.max
        if hasattr(self, 'min') and self.min is not None:
            _dict['min'] = self.min
        if hasattr(self, 'step') and self.step is not None:
            _dict['step'] = self.step
        if hasattr(self, 'type') and self.type is not None:
            _dict['type'] = self.type
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this DedicatedHostProfileMemoryRange object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'DedicatedHostProfileMemoryRange') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'DedicatedHostProfileMemoryRange') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class TypeEnum(str, Enum):
        """
        The type for this profile field.
        """

        RANGE = 'range'



class DedicatedHostProfileSocketDependent(DedicatedHostProfileSocket):
    """
    The CPU socket count for a dedicated host with this profile depends on its
    configuration.

    :attr str type: The type for this profile field.
    """

    def __init__(
        self,
        type: str,
    ) -> None:
        """
        Initialize a DedicatedHostProfileSocketDependent object.

        :param str type: The type for this profile field.
        """
        # pylint: disable=super-init-not-called
        self.type = type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'DedicatedHostProfileSocketDependent':
        """Initialize a DedicatedHostProfileSocketDependent object from a json dictionary."""
        args = {}
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in DedicatedHostProfileSocketDependent JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a DedicatedHostProfileSocketDependent object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'type') and self.type is not None:
            _dict['type'] = self.type
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this DedicatedHostProfileSocketDependent object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'DedicatedHostProfileSocketDependent') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'DedicatedHostProfileSocketDependent') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class TypeEnum(str, Enum):
        """
        The type for this profile field.
        """

        DEPENDENT = 'dependent'



class DedicatedHostProfileSocketEnum(DedicatedHostProfileSocket):
    """
    The permitted values for CPU socket count for a dedicated host with this profile.

    :attr int default: The default value for this profile field.
    :attr str type: The type for this profile field.
    :attr List[int] values: The permitted values for this profile field.
    """

    def __init__(
        self,
        default: int,
        type: str,
        values: List[int],
    ) -> None:
        """
        Initialize a DedicatedHostProfileSocketEnum object.

        :param int default: The default value for this profile field.
        :param str type: The type for this profile field.
        :param List[int] values: The permitted values for this profile field.
        """
        # pylint: disable=super-init-not-called
        self.default = default
        self.type = type
        self.values = values

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'DedicatedHostProfileSocketEnum':
        """Initialize a DedicatedHostProfileSocketEnum object from a json dictionary."""
        args = {}
        if 'default' in _dict:
            args['default'] = _dict.get('default')
        else:
            raise ValueError('Required property \'default\' not present in DedicatedHostProfileSocketEnum JSON')
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in DedicatedHostProfileSocketEnum JSON')
        if 'values' in _dict:
            args['values'] = _dict.get('values')
        else:
            raise ValueError('Required property \'values\' not present in DedicatedHostProfileSocketEnum JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a DedicatedHostProfileSocketEnum object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'default') and self.default is not None:
            _dict['default'] = self.default
        if hasattr(self, 'type') and self.type is not None:
            _dict['type'] = self.type
        if hasattr(self, 'values') and self.values is not None:
            _dict['values'] = self.values
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this DedicatedHostProfileSocketEnum object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'DedicatedHostProfileSocketEnum') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'DedicatedHostProfileSocketEnum') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class TypeEnum(str, Enum):
        """
        The type for this profile field.
        """

        ENUM = 'enum'



class DedicatedHostProfileSocketFixed(DedicatedHostProfileSocket):
    """
    The CPU socket count for a dedicated host with this profile.

    :attr str type: The type for this profile field.
    :attr int value: The value for this profile field.
    """

    def __init__(
        self,
        type: str,
        value: int,
    ) -> None:
        """
        Initialize a DedicatedHostProfileSocketFixed object.

        :param str type: The type for this profile field.
        :param int value: The value for this profile field.
        """
        # pylint: disable=super-init-not-called
        self.type = type
        self.value = value

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'DedicatedHostProfileSocketFixed':
        """Initialize a DedicatedHostProfileSocketFixed object from a json dictionary."""
        args = {}
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in DedicatedHostProfileSocketFixed JSON')
        if 'value' in _dict:
            args['value'] = _dict.get('value')
        else:
            raise ValueError('Required property \'value\' not present in DedicatedHostProfileSocketFixed JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a DedicatedHostProfileSocketFixed object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'type') and self.type is not None:
            _dict['type'] = self.type
        if hasattr(self, 'value') and self.value is not None:
            _dict['value'] = self.value
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this DedicatedHostProfileSocketFixed object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'DedicatedHostProfileSocketFixed') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'DedicatedHostProfileSocketFixed') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class TypeEnum(str, Enum):
        """
        The type for this profile field.
        """

        FIXED = 'fixed'



class DedicatedHostProfileSocketRange(DedicatedHostProfileSocket):
    """
    The permitted range for CPU socket count for a dedicated host with this profile.

    :attr int default: The default value for this profile field.
    :attr int max: The maximum value for this profile field.
    :attr int min: The minimum value for this profile field.
    :attr int step: The increment step value for this profile field.
    :attr str type: The type for this profile field.
    """

    def __init__(
        self,
        default: int,
        max: int,
        min: int,
        step: int,
        type: str,
    ) -> None:
        """
        Initialize a DedicatedHostProfileSocketRange object.

        :param int default: The default value for this profile field.
        :param int max: The maximum value for this profile field.
        :param int min: The minimum value for this profile field.
        :param int step: The increment step value for this profile field.
        :param str type: The type for this profile field.
        """
        # pylint: disable=super-init-not-called
        self.default = default
        self.max = max
        self.min = min
        self.step = step
        self.type = type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'DedicatedHostProfileSocketRange':
        """Initialize a DedicatedHostProfileSocketRange object from a json dictionary."""
        args = {}
        if 'default' in _dict:
            args['default'] = _dict.get('default')
        else:
            raise ValueError('Required property \'default\' not present in DedicatedHostProfileSocketRange JSON')
        if 'max' in _dict:
            args['max'] = _dict.get('max')
        else:
            raise ValueError('Required property \'max\' not present in DedicatedHostProfileSocketRange JSON')
        if 'min' in _dict:
            args['min'] = _dict.get('min')
        else:
            raise ValueError('Required property \'min\' not present in DedicatedHostProfileSocketRange JSON')
        if 'step' in _dict:
            args['step'] = _dict.get('step')
        else:
            raise ValueError('Required property \'step\' not present in DedicatedHostProfileSocketRange JSON')
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in DedicatedHostProfileSocketRange JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a DedicatedHostProfileSocketRange object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'default') and self.default is not None:
            _dict['default'] = self.default
        if hasattr(self, 'max') and self.max is not None:
            _dict['max'] = self.max
        if hasattr(self, 'min') and self.min is not None:
            _dict['min'] = self.min
        if hasattr(self, 'step') and self.step is not None:
            _dict['step'] = self.step
        if hasattr(self, 'type') and self.type is not None:
            _dict['type'] = self.type
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this DedicatedHostProfileSocketRange object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'DedicatedHostProfileSocketRange') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'DedicatedHostProfileSocketRange') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class TypeEnum(str, Enum):
        """
        The type for this profile field.
        """

        RANGE = 'range'



class DedicatedHostProfileVCPUDependent(DedicatedHostProfileVCPU):
    """
    The VCPU count for a dedicated host with this profile depends on its configuration.

    :attr str type: The type for this profile field.
    """

    def __init__(
        self,
        type: str,
    ) -> None:
        """
        Initialize a DedicatedHostProfileVCPUDependent object.

        :param str type: The type for this profile field.
        """
        # pylint: disable=super-init-not-called
        self.type = type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'DedicatedHostProfileVCPUDependent':
        """Initialize a DedicatedHostProfileVCPUDependent object from a json dictionary."""
        args = {}
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in DedicatedHostProfileVCPUDependent JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a DedicatedHostProfileVCPUDependent object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'type') and self.type is not None:
            _dict['type'] = self.type
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this DedicatedHostProfileVCPUDependent object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'DedicatedHostProfileVCPUDependent') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'DedicatedHostProfileVCPUDependent') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class TypeEnum(str, Enum):
        """
        The type for this profile field.
        """

        DEPENDENT = 'dependent'



class DedicatedHostProfileVCPUEnum(DedicatedHostProfileVCPU):
    """
    The permitted values for VCPU count for a dedicated host with this profile.

    :attr int default: The default value for this profile field.
    :attr str type: The type for this profile field.
    :attr List[int] values: The permitted values for this profile field.
    """

    def __init__(
        self,
        default: int,
        type: str,
        values: List[int],
    ) -> None:
        """
        Initialize a DedicatedHostProfileVCPUEnum object.

        :param int default: The default value for this profile field.
        :param str type: The type for this profile field.
        :param List[int] values: The permitted values for this profile field.
        """
        # pylint: disable=super-init-not-called
        self.default = default
        self.type = type
        self.values = values

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'DedicatedHostProfileVCPUEnum':
        """Initialize a DedicatedHostProfileVCPUEnum object from a json dictionary."""
        args = {}
        if 'default' in _dict:
            args['default'] = _dict.get('default')
        else:
            raise ValueError('Required property \'default\' not present in DedicatedHostProfileVCPUEnum JSON')
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in DedicatedHostProfileVCPUEnum JSON')
        if 'values' in _dict:
            args['values'] = _dict.get('values')
        else:
            raise ValueError('Required property \'values\' not present in DedicatedHostProfileVCPUEnum JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a DedicatedHostProfileVCPUEnum object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'default') and self.default is not None:
            _dict['default'] = self.default
        if hasattr(self, 'type') and self.type is not None:
            _dict['type'] = self.type
        if hasattr(self, 'values') and self.values is not None:
            _dict['values'] = self.values
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this DedicatedHostProfileVCPUEnum object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'DedicatedHostProfileVCPUEnum') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'DedicatedHostProfileVCPUEnum') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class TypeEnum(str, Enum):
        """
        The type for this profile field.
        """

        ENUM = 'enum'



class DedicatedHostProfileVCPUFixed(DedicatedHostProfileVCPU):
    """
    The VCPU count for a dedicated host with this profile.

    :attr str type: The type for this profile field.
    :attr int value: The value for this profile field.
    """

    def __init__(
        self,
        type: str,
        value: int,
    ) -> None:
        """
        Initialize a DedicatedHostProfileVCPUFixed object.

        :param str type: The type for this profile field.
        :param int value: The value for this profile field.
        """
        # pylint: disable=super-init-not-called
        self.type = type
        self.value = value

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'DedicatedHostProfileVCPUFixed':
        """Initialize a DedicatedHostProfileVCPUFixed object from a json dictionary."""
        args = {}
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in DedicatedHostProfileVCPUFixed JSON')
        if 'value' in _dict:
            args['value'] = _dict.get('value')
        else:
            raise ValueError('Required property \'value\' not present in DedicatedHostProfileVCPUFixed JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a DedicatedHostProfileVCPUFixed object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'type') and self.type is not None:
            _dict['type'] = self.type
        if hasattr(self, 'value') and self.value is not None:
            _dict['value'] = self.value
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this DedicatedHostProfileVCPUFixed object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'DedicatedHostProfileVCPUFixed') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'DedicatedHostProfileVCPUFixed') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class TypeEnum(str, Enum):
        """
        The type for this profile field.
        """

        FIXED = 'fixed'



class DedicatedHostProfileVCPURange(DedicatedHostProfileVCPU):
    """
    The permitted range for VCPU count for a dedicated host with this profile.

    :attr int default: The default value for this profile field.
    :attr int max: The maximum value for this profile field.
    :attr int min: The minimum value for this profile field.
    :attr int step: The increment step value for this profile field.
    :attr str type: The type for this profile field.
    """

    def __init__(
        self,
        default: int,
        max: int,
        min: int,
        step: int,
        type: str,
    ) -> None:
        """
        Initialize a DedicatedHostProfileVCPURange object.

        :param int default: The default value for this profile field.
        :param int max: The maximum value for this profile field.
        :param int min: The minimum value for this profile field.
        :param int step: The increment step value for this profile field.
        :param str type: The type for this profile field.
        """
        # pylint: disable=super-init-not-called
        self.default = default
        self.max = max
        self.min = min
        self.step = step
        self.type = type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'DedicatedHostProfileVCPURange':
        """Initialize a DedicatedHostProfileVCPURange object from a json dictionary."""
        args = {}
        if 'default' in _dict:
            args['default'] = _dict.get('default')
        else:
            raise ValueError('Required property \'default\' not present in DedicatedHostProfileVCPURange JSON')
        if 'max' in _dict:
            args['max'] = _dict.get('max')
        else:
            raise ValueError('Required property \'max\' not present in DedicatedHostProfileVCPURange JSON')
        if 'min' in _dict:
            args['min'] = _dict.get('min')
        else:
            raise ValueError('Required property \'min\' not present in DedicatedHostProfileVCPURange JSON')
        if 'step' in _dict:
            args['step'] = _dict.get('step')
        else:
            raise ValueError('Required property \'step\' not present in DedicatedHostProfileVCPURange JSON')
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in DedicatedHostProfileVCPURange JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a DedicatedHostProfileVCPURange object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'default') and self.default is not None:
            _dict['default'] = self.default
        if hasattr(self, 'max') and self.max is not None:
            _dict['max'] = self.max
        if hasattr(self, 'min') and self.min is not None:
            _dict['min'] = self.min
        if hasattr(self, 'step') and self.step is not None:
            _dict['step'] = self.step
        if hasattr(self, 'type') and self.type is not None:
            _dict['type'] = self.type
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this DedicatedHostProfileVCPURange object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'DedicatedHostProfileVCPURange') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'DedicatedHostProfileVCPURange') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class TypeEnum(str, Enum):
        """
        The type for this profile field.
        """

        RANGE = 'range'



class DedicatedHostPrototypeDedicatedHostByGroup(DedicatedHostPrototype):
    """
    DedicatedHostPrototypeDedicatedHostByGroup.

    :attr bool instance_placement_enabled: (optional) If set to true, instances can
          be placed on this dedicated host.
    :attr str name: (optional) The name for this dedicated host. The name must not
          be used by another dedicated host in the region. If unspecified, the name will
          be a hyphenated list of randomly-selected words.
    :attr DedicatedHostProfileIdentity profile: The
          [profile](https://cloud.ibm.com/docs/vpc?topic=vpc-dh-profiles) to use for this
          dedicated host.
    :attr ResourceGroupIdentity resource_group: (optional)
    :attr DedicatedHostGroupIdentity group: The dedicated host group for this
          dedicated host.
    """

    def __init__(
        self,
        profile: 'DedicatedHostProfileIdentity',
        group: 'DedicatedHostGroupIdentity',
        *,
        instance_placement_enabled: bool = None,
        name: str = None,
        resource_group: 'ResourceGroupIdentity' = None,
    ) -> None:
        """
        Initialize a DedicatedHostPrototypeDedicatedHostByGroup object.

        :param DedicatedHostProfileIdentity profile: The
               [profile](https://cloud.ibm.com/docs/vpc?topic=vpc-dh-profiles) to use for
               this dedicated host.
        :param DedicatedHostGroupIdentity group: The dedicated host group for this
               dedicated host.
        :param bool instance_placement_enabled: (optional) If set to true,
               instances can be placed on this dedicated host.
        :param str name: (optional) The name for this dedicated host. The name must
               not be used by another dedicated host in the region. If unspecified, the
               name will be a hyphenated list of randomly-selected words.
        :param ResourceGroupIdentity resource_group: (optional)
        """
        # pylint: disable=super-init-not-called
        self.instance_placement_enabled = instance_placement_enabled
        self.name = name
        self.profile = profile
        self.resource_group = resource_group
        self.group = group

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'DedicatedHostPrototypeDedicatedHostByGroup':
        """Initialize a DedicatedHostPrototypeDedicatedHostByGroup object from a json dictionary."""
        args = {}
        if 'instance_placement_enabled' in _dict:
            args['instance_placement_enabled'] = _dict.get('instance_placement_enabled')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        if 'profile' in _dict:
            args['profile'] = _dict.get('profile')
        else:
            raise ValueError('Required property \'profile\' not present in DedicatedHostPrototypeDedicatedHostByGroup JSON')
        if 'resource_group' in _dict:
            args['resource_group'] = _dict.get('resource_group')
        if 'group' in _dict:
            args['group'] = _dict.get('group')
        else:
            raise ValueError('Required property \'group\' not present in DedicatedHostPrototypeDedicatedHostByGroup JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a DedicatedHostPrototypeDedicatedHostByGroup object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'instance_placement_enabled') and self.instance_placement_enabled is not None:
            _dict['instance_placement_enabled'] = self.instance_placement_enabled
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'profile') and self.profile is not None:
            if isinstance(self.profile, dict):
                _dict['profile'] = self.profile
            else:
                _dict['profile'] = self.profile.to_dict()
        if hasattr(self, 'resource_group') and self.resource_group is not None:
            if isinstance(self.resource_group, dict):
                _dict['resource_group'] = self.resource_group
            else:
                _dict['resource_group'] = self.resource_group.to_dict()
        if hasattr(self, 'group') and self.group is not None:
            if isinstance(self.group, dict):
                _dict['group'] = self.group
            else:
                _dict['group'] = self.group.to_dict()
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this DedicatedHostPrototypeDedicatedHostByGroup object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'DedicatedHostPrototypeDedicatedHostByGroup') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'DedicatedHostPrototypeDedicatedHostByGroup') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class DedicatedHostPrototypeDedicatedHostByZone(DedicatedHostPrototype):
    """
    DedicatedHostPrototypeDedicatedHostByZone.

    :attr bool instance_placement_enabled: (optional) If set to true, instances can
          be placed on this dedicated host.
    :attr str name: (optional) The name for this dedicated host. The name must not
          be used by another dedicated host in the region. If unspecified, the name will
          be a hyphenated list of randomly-selected words.
    :attr DedicatedHostProfileIdentity profile: The
          [profile](https://cloud.ibm.com/docs/vpc?topic=vpc-dh-profiles) to use for this
          dedicated host.
    :attr ResourceGroupIdentity resource_group: (optional)
    :attr DedicatedHostGroupPrototypeDedicatedHostByZoneContext group: (optional)
    :attr ZoneIdentity zone: The zone this dedicated host will reside in.
    """

    def __init__(
        self,
        profile: 'DedicatedHostProfileIdentity',
        zone: 'ZoneIdentity',
        *,
        instance_placement_enabled: bool = None,
        name: str = None,
        resource_group: 'ResourceGroupIdentity' = None,
        group: 'DedicatedHostGroupPrototypeDedicatedHostByZoneContext' = None,
    ) -> None:
        """
        Initialize a DedicatedHostPrototypeDedicatedHostByZone object.

        :param DedicatedHostProfileIdentity profile: The
               [profile](https://cloud.ibm.com/docs/vpc?topic=vpc-dh-profiles) to use for
               this dedicated host.
        :param ZoneIdentity zone: The zone this dedicated host will reside in.
        :param bool instance_placement_enabled: (optional) If set to true,
               instances can be placed on this dedicated host.
        :param str name: (optional) The name for this dedicated host. The name must
               not be used by another dedicated host in the region. If unspecified, the
               name will be a hyphenated list of randomly-selected words.
        :param ResourceGroupIdentity resource_group: (optional)
        :param DedicatedHostGroupPrototypeDedicatedHostByZoneContext group:
               (optional)
        """
        # pylint: disable=super-init-not-called
        self.instance_placement_enabled = instance_placement_enabled
        self.name = name
        self.profile = profile
        self.resource_group = resource_group
        self.group = group
        self.zone = zone

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'DedicatedHostPrototypeDedicatedHostByZone':
        """Initialize a DedicatedHostPrototypeDedicatedHostByZone object from a json dictionary."""
        args = {}
        if 'instance_placement_enabled' in _dict:
            args['instance_placement_enabled'] = _dict.get('instance_placement_enabled')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        if 'profile' in _dict:
            args['profile'] = _dict.get('profile')
        else:
            raise ValueError('Required property \'profile\' not present in DedicatedHostPrototypeDedicatedHostByZone JSON')
        if 'resource_group' in _dict:
            args['resource_group'] = _dict.get('resource_group')
        if 'group' in _dict:
            args['group'] = DedicatedHostGroupPrototypeDedicatedHostByZoneContext.from_dict(_dict.get('group'))
        if 'zone' in _dict:
            args['zone'] = _dict.get('zone')
        else:
            raise ValueError('Required property \'zone\' not present in DedicatedHostPrototypeDedicatedHostByZone JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a DedicatedHostPrototypeDedicatedHostByZone object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'instance_placement_enabled') and self.instance_placement_enabled is not None:
            _dict['instance_placement_enabled'] = self.instance_placement_enabled
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'profile') and self.profile is not None:
            if isinstance(self.profile, dict):
                _dict['profile'] = self.profile
            else:
                _dict['profile'] = self.profile.to_dict()
        if hasattr(self, 'resource_group') and self.resource_group is not None:
            if isinstance(self.resource_group, dict):
                _dict['resource_group'] = self.resource_group
            else:
                _dict['resource_group'] = self.resource_group.to_dict()
        if hasattr(self, 'group') and self.group is not None:
            if isinstance(self.group, dict):
                _dict['group'] = self.group
            else:
                _dict['group'] = self.group.to_dict()
        if hasattr(self, 'zone') and self.zone is not None:
            if isinstance(self.zone, dict):
                _dict['zone'] = self.zone
            else:
                _dict['zone'] = self.zone.to_dict()
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this DedicatedHostPrototypeDedicatedHostByZone object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'DedicatedHostPrototypeDedicatedHostByZone') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'DedicatedHostPrototypeDedicatedHostByZone') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class EncryptionKeyIdentityByCRN(EncryptionKeyIdentity):
    """
    EncryptionKeyIdentityByCRN.

    :attr str crn: The CRN of the [Key Protect Root
          Key](https://cloud.ibm.com/docs/key-protect?topic=key-protect-getting-started-tutorial)
          or [Hyper Protect Crypto Services 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 Services Root
               Key](https://cloud.ibm.com/docs/hs-crypto?topic=hs-crypto-get-started) for
               this resource.
        """
        # pylint: disable=super-init-not-called
        self.crn = crn

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'EncryptionKeyIdentityByCRN':
        """Initialize a EncryptionKeyIdentityByCRN object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError('Required property \'crn\' not present in EncryptionKeyIdentityByCRN JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a EncryptionKeyIdentityByCRN object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this EncryptionKeyIdentityByCRN object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'EncryptionKeyIdentityByCRN') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'EncryptionKeyIdentityByCRN') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class EndpointGatewayReservedIPReservedIPIdentity(EndpointGatewayReservedIP):
    """
    Identifies a reserved IP by a unique property.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a EndpointGatewayReservedIPReservedIPIdentity object.

        """
        # pylint: disable=super-init-not-called
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['EndpointGatewayReservedIPReservedIPIdentityById', 'EndpointGatewayReservedIPReservedIPIdentityByHref'])
        )
        raise Exception(msg)


class EndpointGatewayReservedIPReservedIPPrototypeTargetContext(EndpointGatewayReservedIP):
    """
    EndpointGatewayReservedIPReservedIPPrototypeTargetContext.

    :attr str address: (optional) The IP address to reserve, which must not already
          be reserved on the subnet.
          If unspecified, an available address on the subnet will automatically be
          selected.
    :attr bool auto_delete: (optional) Indicates whether this reserved IP member
          will be automatically deleted when either
          `target` is deleted, or the reserved IP is unbound.
    :attr str name: (optional) The name for this reserved IP. The name must not be
          used by another reserved IP in the subnet. Names starting with `ibm-` are
          reserved for provider-owned resources, and are not allowed. If unspecified, the
          name will be a hyphenated list of randomly-selected words.
    :attr SubnetIdentity subnet: The subnet in which to create this reserved IP.
    """

    def __init__(
        self,
        subnet: 'SubnetIdentity',
        *,
        address: str = None,
        auto_delete: bool = None,
        name: str = None,
    ) -> None:
        """
        Initialize a EndpointGatewayReservedIPReservedIPPrototypeTargetContext object.

        :param SubnetIdentity subnet: The subnet in which to create this reserved
               IP.
        :param str address: (optional) The IP address to reserve, which must not
               already be reserved on the subnet.
               If unspecified, an available address on the subnet will automatically be
               selected.
        :param bool auto_delete: (optional) Indicates whether this reserved IP
               member will be automatically deleted when either
               `target` is deleted, or the reserved IP is unbound.
        :param str name: (optional) The name for this reserved IP. The name must
               not be used by another reserved IP in the subnet. Names starting with
               `ibm-` are reserved for provider-owned resources, and are not allowed. If
               unspecified, the name will be a hyphenated list of randomly-selected words.
        """
        # pylint: disable=super-init-not-called
        self.address = address
        self.auto_delete = auto_delete
        self.name = name
        self.subnet = subnet

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'EndpointGatewayReservedIPReservedIPPrototypeTargetContext':
        """Initialize a EndpointGatewayReservedIPReservedIPPrototypeTargetContext object from a json dictionary."""
        args = {}
        if 'address' in _dict:
            args['address'] = _dict.get('address')
        if 'auto_delete' in _dict:
            args['auto_delete'] = _dict.get('auto_delete')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        if 'subnet' in _dict:
            args['subnet'] = _dict.get('subnet')
        else:
            raise ValueError('Required property \'subnet\' not present in EndpointGatewayReservedIPReservedIPPrototypeTargetContext JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a EndpointGatewayReservedIPReservedIPPrototypeTargetContext object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'address') and self.address is not None:
            _dict['address'] = self.address
        if hasattr(self, 'auto_delete') and self.auto_delete is not None:
            _dict['auto_delete'] = self.auto_delete
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'subnet') and self.subnet is not None:
            if isinstance(self.subnet, dict):
                _dict['subnet'] = self.subnet
            else:
                _dict['subnet'] = self.subnet.to_dict()
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this EndpointGatewayReservedIPReservedIPPrototypeTargetContext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'EndpointGatewayReservedIPReservedIPPrototypeTargetContext') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'EndpointGatewayReservedIPReservedIPPrototypeTargetContext') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class EndpointGatewayTargetPrototypeProviderCloudServiceIdentity(EndpointGatewayTargetPrototype):
    """
    EndpointGatewayTargetPrototypeProviderCloudServiceIdentity.

    :attr str resource_type: The type of target for this endpoint gateway.
    """

    def __init__(
        self,
        resource_type: str,
    ) -> None:
        """
        Initialize a EndpointGatewayTargetPrototypeProviderCloudServiceIdentity object.

        :param str resource_type: The type of target for this endpoint gateway.
        """
        # pylint: disable=super-init-not-called
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['EndpointGatewayTargetPrototypeProviderCloudServiceIdentityProviderCloudServiceIdentityByCRN'])
        )
        raise Exception(msg)

    class ResourceTypeEnum(str, Enum):
        """
        The type of target for this endpoint gateway.
        """

        PROVIDER_CLOUD_SERVICE = 'provider_cloud_service'
        PROVIDER_INFRASTRUCTURE_SERVICE = 'provider_infrastructure_service'



class EndpointGatewayTargetPrototypeProviderInfrastructureServiceIdentity(EndpointGatewayTargetPrototype):
    """
    EndpointGatewayTargetPrototypeProviderInfrastructureServiceIdentity.

    :attr str resource_type: The type of target for this endpoint gateway.
    """

    def __init__(
        self,
        resource_type: str,
    ) -> None:
        """
        Initialize a EndpointGatewayTargetPrototypeProviderInfrastructureServiceIdentity object.

        :param str resource_type: The type of target for this endpoint gateway.
        """
        # pylint: disable=super-init-not-called
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['EndpointGatewayTargetPrototypeProviderInfrastructureServiceIdentityProviderInfrastructureServiceIdentityByName'])
        )
        raise Exception(msg)

    class ResourceTypeEnum(str, Enum):
        """
        The type of target for this endpoint gateway.
        """

        PROVIDER_CLOUD_SERVICE = 'provider_cloud_service'
        PROVIDER_INFRASTRUCTURE_SERVICE = 'provider_infrastructure_service'



class EndpointGatewayTargetProviderCloudServiceReference(EndpointGatewayTarget):
    """
    EndpointGatewayTargetProviderCloudServiceReference.

    :attr str crn: The CRN for this provider cloud service, or the CRN for the
          user's instance of a provider cloud service.
    :attr str resource_type: The type of target.
    """

    def __init__(
        self,
        crn: str,
        resource_type: str,
    ) -> None:
        """
        Initialize a EndpointGatewayTargetProviderCloudServiceReference object.

        :param str crn: The CRN for this provider cloud service, or the CRN for the
               user's instance of a provider cloud service.
        :param str resource_type: The type of target.
        """
        # pylint: disable=super-init-not-called
        self.crn = crn
        self.resource_type = resource_type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'EndpointGatewayTargetProviderCloudServiceReference':
        """Initialize a EndpointGatewayTargetProviderCloudServiceReference object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError('Required property \'crn\' not present in EndpointGatewayTargetProviderCloudServiceReference JSON')
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError('Required property \'resource_type\' not present in EndpointGatewayTargetProviderCloudServiceReference JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a EndpointGatewayTargetProviderCloudServiceReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'resource_type') and self.resource_type is not None:
            _dict['resource_type'] = self.resource_type
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this EndpointGatewayTargetProviderCloudServiceReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'EndpointGatewayTargetProviderCloudServiceReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'EndpointGatewayTargetProviderCloudServiceReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ResourceTypeEnum(str, Enum):
        """
        The type of target.
        """

        PROVIDER_CLOUD_SERVICE = 'provider_cloud_service'



class EndpointGatewayTargetProviderInfrastructureServiceReference(EndpointGatewayTarget):
    """
    The name of this provider infrastructure service.

    :attr str name: The name of a provider infrastructure service. Must be:
          - `ibm-ntp-server`: An NTP (Network Time Protocol) server provided by IBM.
    :attr str resource_type: The type of target.
    """

    def __init__(
        self,
        name: str,
        resource_type: str,
    ) -> None:
        """
        Initialize a EndpointGatewayTargetProviderInfrastructureServiceReference object.

        :param str name: The name of a provider infrastructure service. Must be:
               - `ibm-ntp-server`: An NTP (Network Time Protocol) server provided by IBM.
        :param str resource_type: The type of target.
        """
        # pylint: disable=super-init-not-called
        self.name = name
        self.resource_type = resource_type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'EndpointGatewayTargetProviderInfrastructureServiceReference':
        """Initialize a EndpointGatewayTargetProviderInfrastructureServiceReference object from a json dictionary."""
        args = {}
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in EndpointGatewayTargetProviderInfrastructureServiceReference JSON')
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError('Required property \'resource_type\' not present in EndpointGatewayTargetProviderInfrastructureServiceReference JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a EndpointGatewayTargetProviderInfrastructureServiceReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'resource_type') and self.resource_type is not None:
            _dict['resource_type'] = self.resource_type
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this EndpointGatewayTargetProviderInfrastructureServiceReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'EndpointGatewayTargetProviderInfrastructureServiceReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'EndpointGatewayTargetProviderInfrastructureServiceReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ResourceTypeEnum(str, Enum):
        """
        The type of target.
        """

        PROVIDER_INFRASTRUCTURE_SERVICE = 'provider_infrastructure_service'



class FloatingIPPrototypeFloatingIPByTarget(FloatingIPPrototype):
    """
    FloatingIPPrototypeFloatingIPByTarget.

    :attr str name: (optional) The name for this floating IP. The name must not be
          used by another floating IP in the region. If unspecified, the name will be a
          hyphenated list of randomly-selected words.
    :attr ResourceGroupIdentity resource_group: (optional)
    :attr FloatingIPTargetPrototype target: The target resource to bind this
          floating IP to.
          The target resource must not already have a floating IP bound to it if the
          target
          resource is:
          - an instance network interface
          - a bare metal server network interface with `enable_infrastructure_nat` set to
          `true`.
    """

    def __init__(
        self,
        target: 'FloatingIPTargetPrototype',
        *,
        name: str = None,
        resource_group: 'ResourceGroupIdentity' = None,
    ) -> None:
        """
        Initialize a FloatingIPPrototypeFloatingIPByTarget object.

        :param FloatingIPTargetPrototype target: The target resource to bind this
               floating IP to.
               The target resource must not already have a floating IP bound to it if the
               target
               resource is:
               - an instance network interface
               - a bare metal server network interface with `enable_infrastructure_nat`
               set to `true`.
        :param str name: (optional) The name for this floating IP. The name must
               not be used by another floating IP in the region. If unspecified, the name
               will be a hyphenated list of randomly-selected words.
        :param ResourceGroupIdentity resource_group: (optional)
        """
        # pylint: disable=super-init-not-called
        self.name = name
        self.resource_group = resource_group
        self.target = target

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'FloatingIPPrototypeFloatingIPByTarget':
        """Initialize a FloatingIPPrototypeFloatingIPByTarget object from a json dictionary."""
        args = {}
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        if 'resource_group' in _dict:
            args['resource_group'] = _dict.get('resource_group')
        if 'target' in _dict:
            args['target'] = _dict.get('target')
        else:
            raise ValueError('Required property \'target\' not present in FloatingIPPrototypeFloatingIPByTarget JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a FloatingIPPrototypeFloatingIPByTarget object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'resource_group') and self.resource_group is not None:
            if isinstance(self.resource_group, dict):
                _dict['resource_group'] = self.resource_group
            else:
                _dict['resource_group'] = self.resource_group.to_dict()
        if hasattr(self, 'target') and self.target is not None:
            if isinstance(self.target, dict):
                _dict['target'] = self.target
            else:
                _dict['target'] = self.target.to_dict()
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this FloatingIPPrototypeFloatingIPByTarget object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'FloatingIPPrototypeFloatingIPByTarget') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'FloatingIPPrototypeFloatingIPByTarget') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class FloatingIPPrototypeFloatingIPByZone(FloatingIPPrototype):
    """
    FloatingIPPrototypeFloatingIPByZone.

    :attr str name: (optional) The name for this floating IP. The name must not be
          used by another floating IP in the region. If unspecified, the name will be a
          hyphenated list of randomly-selected words.
    :attr ResourceGroupIdentity resource_group: (optional)
    :attr ZoneIdentity zone: The zone this floating IP will reside in.
    """

    def __init__(
        self,
        zone: 'ZoneIdentity',
        *,
        name: str = None,
        resource_group: 'ResourceGroupIdentity' = None,
    ) -> None:
        """
        Initialize a FloatingIPPrototypeFloatingIPByZone object.

        :param ZoneIdentity zone: The zone this floating IP will reside in.
        :param str name: (optional) The name for this floating IP. The name must
               not be used by another floating IP in the region. If unspecified, the name
               will be a hyphenated list of randomly-selected words.
        :param ResourceGroupIdentity resource_group: (optional)
        """
        # pylint: disable=super-init-not-called
        self.name = name
        self.resource_group = resource_group
        self.zone = zone

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'FloatingIPPrototypeFloatingIPByZone':
        """Initialize a FloatingIPPrototypeFloatingIPByZone object from a json dictionary."""
        args = {}
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        if 'resource_group' in _dict:
            args['resource_group'] = _dict.get('resource_group')
        if 'zone' in _dict:
            args['zone'] = _dict.get('zone')
        else:
            raise ValueError('Required property \'zone\' not present in FloatingIPPrototypeFloatingIPByZone JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a FloatingIPPrototypeFloatingIPByZone object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'resource_group') and self.resource_group is not None:
            if isinstance(self.resource_group, dict):
                _dict['resource_group'] = self.resource_group
            else:
                _dict['resource_group'] = self.resource_group.to_dict()
        if hasattr(self, 'zone') and self.zone is not None:
            if isinstance(self.zone, dict):
                _dict['zone'] = self.zone
            else:
                _dict['zone'] = self.zone.to_dict()
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this FloatingIPPrototypeFloatingIPByZone object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'FloatingIPPrototypeFloatingIPByZone') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'FloatingIPPrototypeFloatingIPByZone') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class FloatingIPTargetPatchBareMetalServerNetworkInterfaceIdentity(FloatingIPTargetPatch):
    """
    Identifies a bare metal server network interface by a unique property.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a FloatingIPTargetPatchBareMetalServerNetworkInterfaceIdentity object.

        """
        # pylint: disable=super-init-not-called
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['FloatingIPTargetPatchBareMetalServerNetworkInterfaceIdentityBareMetalServerNetworkInterfaceIdentityById', 'FloatingIPTargetPatchBareMetalServerNetworkInterfaceIdentityBareMetalServerNetworkInterfaceIdentityByHref'])
        )
        raise Exception(msg)


class FloatingIPTargetPatchNetworkInterfaceIdentity(FloatingIPTargetPatch):
    """
    Identifies an instance network interface by a unique property.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a FloatingIPTargetPatchNetworkInterfaceIdentity object.

        """
        # pylint: disable=super-init-not-called
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['FloatingIPTargetPatchNetworkInterfaceIdentityNetworkInterfaceIdentityById', 'FloatingIPTargetPatchNetworkInterfaceIdentityNetworkInterfaceIdentityByHref'])
        )
        raise Exception(msg)


class FloatingIPTargetPrototypeBareMetalServerNetworkInterfaceIdentity(FloatingIPTargetPrototype):
    """
    Identifies a bare metal server network interface by a unique property.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a FloatingIPTargetPrototypeBareMetalServerNetworkInterfaceIdentity object.

        """
        # pylint: disable=super-init-not-called
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['FloatingIPTargetPrototypeBareMetalServerNetworkInterfaceIdentityBareMetalServerNetworkInterfaceIdentityById', 'FloatingIPTargetPrototypeBareMetalServerNetworkInterfaceIdentityBareMetalServerNetworkInterfaceIdentityByHref'])
        )
        raise Exception(msg)


class FloatingIPTargetPrototypeNetworkInterfaceIdentity(FloatingIPTargetPrototype):
    """
    Identifies an instance network interface by a unique property.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a FloatingIPTargetPrototypeNetworkInterfaceIdentity object.

        """
        # pylint: disable=super-init-not-called
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['FloatingIPTargetPrototypeNetworkInterfaceIdentityNetworkInterfaceIdentityById', 'FloatingIPTargetPrototypeNetworkInterfaceIdentityNetworkInterfaceIdentityByHref'])
        )
        raise Exception(msg)


class FloatingIPTargetBareMetalServerNetworkInterfaceReference(FloatingIPTarget):
    """
    FloatingIPTargetBareMetalServerNetworkInterfaceReference.

    :attr BareMetalServerNetworkInterfaceReferenceDeleted deleted: (optional) If
          present, this property indicates the referenced resource has been deleted, and
          provides
          some supplementary information.
    :attr str href: The URL for this bare metal server network interface.
    :attr str id: The unique identifier for this bare metal server network
          interface.
    :attr str name: The name for this bare metal server network interface.
    :attr ReservedIPReference primary_ip:
    :attr str resource_type: The resource type.
    """

    def __init__(
        self,
        href: str,
        id: str,
        name: str,
        primary_ip: 'ReservedIPReference',
        resource_type: str,
        *,
        deleted: 'BareMetalServerNetworkInterfaceReferenceDeleted' = None,
    ) -> None:
        """
        Initialize a FloatingIPTargetBareMetalServerNetworkInterfaceReference object.

        :param str href: The URL for this bare metal server network interface.
        :param str id: The unique identifier for this bare metal server network
               interface.
        :param str name: The name for this bare metal server network interface.
        :param ReservedIPReference primary_ip:
        :param str resource_type: The resource type.
        :param BareMetalServerNetworkInterfaceReferenceDeleted deleted: (optional)
               If present, this property indicates the referenced resource has been
               deleted, and provides
               some supplementary information.
        """
        # pylint: disable=super-init-not-called
        self.deleted = deleted
        self.href = href
        self.id = id
        self.name = name
        self.primary_ip = primary_ip
        self.resource_type = resource_type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'FloatingIPTargetBareMetalServerNetworkInterfaceReference':
        """Initialize a FloatingIPTargetBareMetalServerNetworkInterfaceReference object from a json dictionary."""
        args = {}
        if 'deleted' in _dict:
            args['deleted'] = BareMetalServerNetworkInterfaceReferenceDeleted.from_dict(_dict.get('deleted'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in FloatingIPTargetBareMetalServerNetworkInterfaceReference JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in FloatingIPTargetBareMetalServerNetworkInterfaceReference JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in FloatingIPTargetBareMetalServerNetworkInterfaceReference JSON')
        if 'primary_ip' in _dict:
            args['primary_ip'] = ReservedIPReference.from_dict(_dict.get('primary_ip'))
        else:
            raise ValueError('Required property \'primary_ip\' not present in FloatingIPTargetBareMetalServerNetworkInterfaceReference JSON')
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError('Required property \'resource_type\' not present in FloatingIPTargetBareMetalServerNetworkInterfaceReference JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a FloatingIPTargetBareMetalServerNetworkInterfaceReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'deleted') and self.deleted is not None:
            if isinstance(self.deleted, dict):
                _dict['deleted'] = self.deleted
            else:
                _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'primary_ip') and self.primary_ip is not None:
            if isinstance(self.primary_ip, dict):
                _dict['primary_ip'] = self.primary_ip
            else:
                _dict['primary_ip'] = self.primary_ip.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 FloatingIPTargetBareMetalServerNetworkInterfaceReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'FloatingIPTargetBareMetalServerNetworkInterfaceReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'FloatingIPTargetBareMetalServerNetworkInterfaceReference') -> 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 FloatingIPTargetNetworkInterfaceReference(FloatingIPTarget):
    """
    FloatingIPTargetNetworkInterfaceReference.

    :attr NetworkInterfaceReferenceDeleted deleted: (optional) If present, this
          property indicates the referenced resource has been deleted, and provides
          some supplementary information.
    :attr str href: The URL for this instance network interface.
    :attr str id: The unique identifier for this instance network interface.
    :attr str name: The name for this instance network interface.
    :attr ReservedIPReference primary_ip:
    :attr str resource_type: The resource type.
    """

    def __init__(
        self,
        href: str,
        id: str,
        name: str,
        primary_ip: 'ReservedIPReference',
        resource_type: str,
        *,
        deleted: 'NetworkInterfaceReferenceDeleted' = None,
    ) -> None:
        """
        Initialize a FloatingIPTargetNetworkInterfaceReference object.

        :param str href: The URL for this instance network interface.
        :param str id: The unique identifier for this instance network interface.
        :param str name: The name for this instance network interface.
        :param ReservedIPReference primary_ip:
        :param str resource_type: The resource type.
        :param NetworkInterfaceReferenceDeleted deleted: (optional) If present,
               this property indicates the referenced resource has been deleted, and
               provides
               some supplementary information.
        """
        # pylint: disable=super-init-not-called
        self.deleted = deleted
        self.href = href
        self.id = id
        self.name = name
        self.primary_ip = primary_ip
        self.resource_type = resource_type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'FloatingIPTargetNetworkInterfaceReference':
        """Initialize a FloatingIPTargetNetworkInterfaceReference object from a json dictionary."""
        args = {}
        if 'deleted' in _dict:
            args['deleted'] = NetworkInterfaceReferenceDeleted.from_dict(_dict.get('deleted'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in FloatingIPTargetNetworkInterfaceReference JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in FloatingIPTargetNetworkInterfaceReference JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in FloatingIPTargetNetworkInterfaceReference JSON')
        if 'primary_ip' in _dict:
            args['primary_ip'] = ReservedIPReference.from_dict(_dict.get('primary_ip'))
        else:
            raise ValueError('Required property \'primary_ip\' not present in FloatingIPTargetNetworkInterfaceReference JSON')
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError('Required property \'resource_type\' not present in FloatingIPTargetNetworkInterfaceReference JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a FloatingIPTargetNetworkInterfaceReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'deleted') and self.deleted is not None:
            if isinstance(self.deleted, dict):
                _dict['deleted'] = self.deleted
            else:
                _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'primary_ip') and self.primary_ip is not None:
            if isinstance(self.primary_ip, dict):
                _dict['primary_ip'] = self.primary_ip
            else:
                _dict['primary_ip'] = self.primary_ip.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 FloatingIPTargetNetworkInterfaceReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'FloatingIPTargetNetworkInterfaceReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'FloatingIPTargetNetworkInterfaceReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        NETWORK_INTERFACE = 'network_interface'



class FloatingIPTargetPublicGatewayReference(FloatingIPTarget):
    """
    FloatingIPTargetPublicGatewayReference.

    :attr str crn: The CRN for this public gateway.
    :attr PublicGatewayReferenceDeleted deleted: (optional) If present, this
          property indicates the referenced resource has been deleted, and provides
          some supplementary information.
    :attr str href: The URL for this public gateway.
    :attr str id: The unique identifier for this public gateway.
    :attr str name: The name for this public gateway. The name is unique across all
          public gateways in the VPC.
    :attr str resource_type: The resource type.
    """

    def __init__(
        self,
        crn: str,
        href: str,
        id: str,
        name: str,
        resource_type: str,
        *,
        deleted: 'PublicGatewayReferenceDeleted' = None,
    ) -> None:
        """
        Initialize a FloatingIPTargetPublicGatewayReference object.

        :param str crn: The CRN for this public gateway.
        :param str href: The URL for this public gateway.
        :param str id: The unique identifier for this public gateway.
        :param str name: The name for this public gateway. The name is unique
               across all public gateways in the VPC.
        :param str resource_type: The resource type.
        :param PublicGatewayReferenceDeleted deleted: (optional) If present, this
               property indicates the referenced resource has been deleted, and provides
               some supplementary information.
        """
        # pylint: disable=super-init-not-called
        self.crn = crn
        self.deleted = deleted
        self.href = href
        self.id = id
        self.name = name
        self.resource_type = resource_type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'FloatingIPTargetPublicGatewayReference':
        """Initialize a FloatingIPTargetPublicGatewayReference object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError('Required property \'crn\' not present in FloatingIPTargetPublicGatewayReference JSON')
        if 'deleted' in _dict:
            args['deleted'] = PublicGatewayReferenceDeleted.from_dict(_dict.get('deleted'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in FloatingIPTargetPublicGatewayReference JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in FloatingIPTargetPublicGatewayReference JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in FloatingIPTargetPublicGatewayReference JSON')
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError('Required property \'resource_type\' not present in FloatingIPTargetPublicGatewayReference JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a FloatingIPTargetPublicGatewayReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'deleted') and self.deleted is not None:
            if isinstance(self.deleted, dict):
                _dict['deleted'] = self.deleted
            else:
                _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'resource_type') and self.resource_type is not None:
            _dict['resource_type'] = self.resource_type
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this FloatingIPTargetPublicGatewayReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'FloatingIPTargetPublicGatewayReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'FloatingIPTargetPublicGatewayReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        PUBLIC_GATEWAY = 'public_gateway'



class FlowLogCollectorTargetPrototypeInstanceIdentity(FlowLogCollectorTargetPrototype):
    """
    Identifies a virtual server instance by a unique property.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a FlowLogCollectorTargetPrototypeInstanceIdentity object.

        """
        # pylint: disable=super-init-not-called
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['FlowLogCollectorTargetPrototypeInstanceIdentityInstanceIdentityById', 'FlowLogCollectorTargetPrototypeInstanceIdentityInstanceIdentityByCRN', 'FlowLogCollectorTargetPrototypeInstanceIdentityInstanceIdentityByHref'])
        )
        raise Exception(msg)


class FlowLogCollectorTargetPrototypeNetworkInterfaceIdentity(FlowLogCollectorTargetPrototype):
    """
    Identifies an instance network interface by a unique property.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a FlowLogCollectorTargetPrototypeNetworkInterfaceIdentity object.

        """
        # pylint: disable=super-init-not-called
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['FlowLogCollectorTargetPrototypeNetworkInterfaceIdentityNetworkInterfaceIdentityById', 'FlowLogCollectorTargetPrototypeNetworkInterfaceIdentityNetworkInterfaceIdentityByHref'])
        )
        raise Exception(msg)


class FlowLogCollectorTargetPrototypeSubnetIdentity(FlowLogCollectorTargetPrototype):
    """
    Identifies a subnet by a unique property.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a FlowLogCollectorTargetPrototypeSubnetIdentity object.

        """
        # pylint: disable=super-init-not-called
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['FlowLogCollectorTargetPrototypeSubnetIdentitySubnetIdentityById', 'FlowLogCollectorTargetPrototypeSubnetIdentitySubnetIdentityByCRN', 'FlowLogCollectorTargetPrototypeSubnetIdentitySubnetIdentityByHref'])
        )
        raise Exception(msg)


class FlowLogCollectorTargetPrototypeVPCIdentity(FlowLogCollectorTargetPrototype):
    """
    Identifies a VPC by a unique property.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a FlowLogCollectorTargetPrototypeVPCIdentity object.

        """
        # pylint: disable=super-init-not-called
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['FlowLogCollectorTargetPrototypeVPCIdentityVPCIdentityById', 'FlowLogCollectorTargetPrototypeVPCIdentityVPCIdentityByCRN', 'FlowLogCollectorTargetPrototypeVPCIdentityVPCIdentityByHref'])
        )
        raise Exception(msg)


class FlowLogCollectorTargetInstanceReference(FlowLogCollectorTarget):
    """
    FlowLogCollectorTargetInstanceReference.

    :attr str crn: The CRN for this virtual server instance.
    :attr InstanceReferenceDeleted deleted: (optional) If present, this property
          indicates the referenced resource has been deleted, and provides
          some supplementary information.
    :attr str href: The URL for this virtual server instance.
    :attr str id: The unique identifier for this virtual server instance.
    :attr str name: The name for this virtual server instance. The name is unique
          across all virtual server instances in the region.
    """

    def __init__(
        self,
        crn: str,
        href: str,
        id: str,
        name: str,
        *,
        deleted: 'InstanceReferenceDeleted' = None,
    ) -> None:
        """
        Initialize a FlowLogCollectorTargetInstanceReference object.

        :param str crn: The CRN for this virtual server instance.
        :param str href: The URL for this virtual server instance.
        :param str id: The unique identifier for this virtual server instance.
        :param str name: The name for this virtual server instance. The name is
               unique across all virtual server instances in the region.
        :param InstanceReferenceDeleted deleted: (optional) If present, this
               property indicates the referenced resource has been deleted, and provides
               some supplementary information.
        """
        # pylint: disable=super-init-not-called
        self.crn = crn
        self.deleted = deleted
        self.href = href
        self.id = id
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'FlowLogCollectorTargetInstanceReference':
        """Initialize a FlowLogCollectorTargetInstanceReference object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError('Required property \'crn\' not present in FlowLogCollectorTargetInstanceReference JSON')
        if 'deleted' in _dict:
            args['deleted'] = InstanceReferenceDeleted.from_dict(_dict.get('deleted'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in FlowLogCollectorTargetInstanceReference JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in FlowLogCollectorTargetInstanceReference JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in FlowLogCollectorTargetInstanceReference JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a FlowLogCollectorTargetInstanceReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'deleted') and self.deleted is not None:
            if isinstance(self.deleted, dict):
                _dict['deleted'] = self.deleted
            else:
                _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this FlowLogCollectorTargetInstanceReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'FlowLogCollectorTargetInstanceReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'FlowLogCollectorTargetInstanceReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class FlowLogCollectorTargetNetworkInterfaceReferenceTargetContext(FlowLogCollectorTarget):
    """
    FlowLogCollectorTargetNetworkInterfaceReferenceTargetContext.

    :attr NetworkInterfaceReferenceTargetContextDeleted deleted: (optional) If
          present, this property indicates the referenced resource has been deleted, and
          provides
          some supplementary information.
    :attr str href: The URL for this instance network interface.
    :attr str id: The unique identifier for this instance network interface.
    :attr str name: The name for this instance network interface.
    :attr str resource_type: The resource type.
    """

    def __init__(
        self,
        href: str,
        id: str,
        name: str,
        resource_type: str,
        *,
        deleted: 'NetworkInterfaceReferenceTargetContextDeleted' = None,
    ) -> None:
        """
        Initialize a FlowLogCollectorTargetNetworkInterfaceReferenceTargetContext object.

        :param str href: The URL for this instance network interface.
        :param str id: The unique identifier for this instance network interface.
        :param str name: The name for this instance network interface.
        :param str resource_type: The resource type.
        :param NetworkInterfaceReferenceTargetContextDeleted deleted: (optional) If
               present, this property indicates the referenced resource has been deleted,
               and provides
               some supplementary information.
        """
        # pylint: disable=super-init-not-called
        self.deleted = deleted
        self.href = href
        self.id = id
        self.name = name
        self.resource_type = resource_type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'FlowLogCollectorTargetNetworkInterfaceReferenceTargetContext':
        """Initialize a FlowLogCollectorTargetNetworkInterfaceReferenceTargetContext object from a json dictionary."""
        args = {}
        if 'deleted' in _dict:
            args['deleted'] = NetworkInterfaceReferenceTargetContextDeleted.from_dict(_dict.get('deleted'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in FlowLogCollectorTargetNetworkInterfaceReferenceTargetContext JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in FlowLogCollectorTargetNetworkInterfaceReferenceTargetContext JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in FlowLogCollectorTargetNetworkInterfaceReferenceTargetContext JSON')
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError('Required property \'resource_type\' not present in FlowLogCollectorTargetNetworkInterfaceReferenceTargetContext JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a FlowLogCollectorTargetNetworkInterfaceReferenceTargetContext object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'deleted') and self.deleted is not None:
            if isinstance(self.deleted, dict):
                _dict['deleted'] = self.deleted
            else:
                _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'resource_type') and self.resource_type is not None:
            _dict['resource_type'] = self.resource_type
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this FlowLogCollectorTargetNetworkInterfaceReferenceTargetContext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'FlowLogCollectorTargetNetworkInterfaceReferenceTargetContext') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'FlowLogCollectorTargetNetworkInterfaceReferenceTargetContext') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        NETWORK_INTERFACE = 'network_interface'



class FlowLogCollectorTargetSubnetReference(FlowLogCollectorTarget):
    """
    FlowLogCollectorTargetSubnetReference.

    :attr str crn: The CRN for this subnet.
    :attr SubnetReferenceDeleted deleted: (optional) If present, this property
          indicates the referenced resource has been deleted, and provides
          some supplementary information.
    :attr str href: The URL for this subnet.
    :attr str id: The unique identifier for this subnet.
    :attr str name: The name for this subnet. The name is unique across all subnets
          in the VPC.
    :attr str resource_type: The resource type.
    """

    def __init__(
        self,
        crn: str,
        href: str,
        id: str,
        name: str,
        resource_type: str,
        *,
        deleted: 'SubnetReferenceDeleted' = None,
    ) -> None:
        """
        Initialize a FlowLogCollectorTargetSubnetReference object.

        :param str crn: The CRN for this subnet.
        :param str href: The URL for this subnet.
        :param str id: The unique identifier for this subnet.
        :param str name: The name for this subnet. The name is unique across all
               subnets in the VPC.
        :param str resource_type: The resource type.
        :param SubnetReferenceDeleted deleted: (optional) If present, this property
               indicates the referenced resource has been deleted, and provides
               some supplementary information.
        """
        # pylint: disable=super-init-not-called
        self.crn = crn
        self.deleted = deleted
        self.href = href
        self.id = id
        self.name = name
        self.resource_type = resource_type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'FlowLogCollectorTargetSubnetReference':
        """Initialize a FlowLogCollectorTargetSubnetReference object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError('Required property \'crn\' not present in FlowLogCollectorTargetSubnetReference JSON')
        if 'deleted' in _dict:
            args['deleted'] = SubnetReferenceDeleted.from_dict(_dict.get('deleted'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in FlowLogCollectorTargetSubnetReference JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in FlowLogCollectorTargetSubnetReference JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in FlowLogCollectorTargetSubnetReference JSON')
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError('Required property \'resource_type\' not present in FlowLogCollectorTargetSubnetReference JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a FlowLogCollectorTargetSubnetReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'deleted') and self.deleted is not None:
            if isinstance(self.deleted, dict):
                _dict['deleted'] = self.deleted
            else:
                _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'resource_type') and self.resource_type is not None:
            _dict['resource_type'] = self.resource_type
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this FlowLogCollectorTargetSubnetReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'FlowLogCollectorTargetSubnetReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'FlowLogCollectorTargetSubnetReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        SUBNET = 'subnet'



class FlowLogCollectorTargetVPCReference(FlowLogCollectorTarget):
    """
    FlowLogCollectorTargetVPCReference.

    :attr str crn: The CRN for this VPC.
    :attr VPCReferenceDeleted deleted: (optional) If present, this property
          indicates the referenced resource has been deleted, and provides
          some supplementary information.
    :attr str href: The URL for this VPC.
    :attr str id: The unique identifier for this VPC.
    :attr str name: The name for this VPC. The name is unique across all VPCs in the
          region.
    :attr str resource_type: The resource type.
    """

    def __init__(
        self,
        crn: str,
        href: str,
        id: str,
        name: str,
        resource_type: str,
        *,
        deleted: 'VPCReferenceDeleted' = None,
    ) -> None:
        """
        Initialize a FlowLogCollectorTargetVPCReference object.

        :param str crn: The CRN for this VPC.
        :param str href: The URL for this VPC.
        :param str id: The unique identifier for this VPC.
        :param str name: The name for this VPC. The name is unique across all VPCs
               in the region.
        :param str resource_type: The resource type.
        :param VPCReferenceDeleted deleted: (optional) If present, this property
               indicates the referenced resource has been deleted, and provides
               some supplementary information.
        """
        # pylint: disable=super-init-not-called
        self.crn = crn
        self.deleted = deleted
        self.href = href
        self.id = id
        self.name = name
        self.resource_type = resource_type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'FlowLogCollectorTargetVPCReference':
        """Initialize a FlowLogCollectorTargetVPCReference object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError('Required property \'crn\' not present in FlowLogCollectorTargetVPCReference JSON')
        if 'deleted' in _dict:
            args['deleted'] = VPCReferenceDeleted.from_dict(_dict.get('deleted'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in FlowLogCollectorTargetVPCReference JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in FlowLogCollectorTargetVPCReference JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in FlowLogCollectorTargetVPCReference JSON')
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError('Required property \'resource_type\' not present in FlowLogCollectorTargetVPCReference JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a FlowLogCollectorTargetVPCReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'deleted') and self.deleted is not None:
            if isinstance(self.deleted, dict):
                _dict['deleted'] = self.deleted
            else:
                _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'resource_type') and self.resource_type is not None:
            _dict['resource_type'] = self.resource_type
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this FlowLogCollectorTargetVPCReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'FlowLogCollectorTargetVPCReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'FlowLogCollectorTargetVPCReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        VPC = 'vpc'



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 datetime deprecation_at: (optional) The deprecation date and time to set
          for this image.
          The date and time must not be in the past, and must be earlier than
          `obsolescence_at`
          (if `obsolescence_at` is set).
          If unspecified, no deprecation date and time will be set.
          If the deprecation date and time is reached while the image has a status of
          `pending`, the image's status will transition to `deprecated` upon its
          successful creation (or
          `obsolete` if the obsolescence date and time was also reached).
    :attr str name: (optional) The name for this image. The name must not be used by
          another image in the region. Names starting with `ibm-` are reserved for
          system-provided images, and are not allowed. If unspecified, the name will be a
          hyphenated list of randomly-selected words.
    :attr datetime obsolescence_at: (optional) The obsolescence date and time to set
          for this image.
          The date and time must not be in the past, and must be later than
          `deprecation_at` (if
          `deprecation_at` is set).
          If unspecified, no obsolescence date and time will be set.
          If the obsolescence date and time is reached while the image has a status of
          `pending`, the image's status will transition to `obsolete` upon its successful
          creation.
    :attr ResourceGroupIdentity resource_group: (optional)
    :attr str encrypted_data_key: (optional) A base64-encoded, encrypted
          representation of the key that was used to encrypt the data for this image.
          That representation is created by wrapping the key's value with the
          `encryption_key` root key (which must also be specified), using either [Key
          Protect](https://cloud.ibm.com/docs/key-protect?topic=key-protect-wrap-keys) or
          the
          [Hyper Protect Crypto
          Services](https://cloud.ibm.com/docs/services/hs-crypto?topic=hs-crypto-wrap-keys).
          If unspecified, the imported image is treated as unencrypted.
    :attr EncryptionKeyIdentity encryption_key: (optional) The root key that was
          used to wrap the data key (which is ultimately represented as
          `encrypted_data_key`). Additionally, the root key will be used to encrypt
          volumes
          created from this image (unless an alternate `encryption_key` is specified at
          volume
          creation).
          If unspecified, the imported image is treated as unencrypted.
    :attr ImageFilePrototype file: The file from which to create the image.
    :attr OperatingSystemIdentity operating_system: 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',
        *,
        deprecation_at: datetime = None,
        name: str = None,
        obsolescence_at: datetime = None,
        resource_group: 'ResourceGroupIdentity' = None,
        encrypted_data_key: str = None,
        encryption_key: 'EncryptionKeyIdentity' = None,
    ) -> None:
        """
        Initialize a ImagePrototypeImageByFile object.

        :param ImageFilePrototype file: The file from which to create the image.
        :param OperatingSystemIdentity operating_system: The [supported operating
               system](https://cloud.ibm.com/apidocs/vpc#list-operating-systems) included
               in this
               image.
        :param datetime deprecation_at: (optional) The deprecation date and time to
               set for this image.
               The date and time must not be in the past, and must be earlier than
               `obsolescence_at`
               (if `obsolescence_at` is set).
               If unspecified, no deprecation date and time will be set.
               If the deprecation date and time is reached while the image has a status of
               `pending`, the image's status will transition to `deprecated` upon its
               successful creation (or
               `obsolete` if the obsolescence date and time was also reached).
        :param str name: (optional) The name for this image. The name must not be
               used by another image in the region. Names starting with `ibm-` are
               reserved for system-provided images, and are not allowed. If unspecified,
               the name will be a hyphenated list of randomly-selected words.
        :param datetime obsolescence_at: (optional) The obsolescence date and time
               to set for this image.
               The date and time must not be in the past, and must be later than
               `deprecation_at` (if
               `deprecation_at` is set).
               If unspecified, no obsolescence date and time will be set.
               If the obsolescence date and time is reached while the image has a status
               of
               `pending`, the image's status will transition to `obsolete` upon its
               successful creation.
        :param ResourceGroupIdentity resource_group: (optional)
        :param str encrypted_data_key: (optional) A base64-encoded, encrypted
               representation of the key that was used to encrypt the data for this image.
               That representation is created by wrapping the key's value with the
               `encryption_key` root key (which must also be specified), using either [Key
               Protect](https://cloud.ibm.com/docs/key-protect?topic=key-protect-wrap-keys)
               or the
               [Hyper Protect Crypto
               Services](https://cloud.ibm.com/docs/services/hs-crypto?topic=hs-crypto-wrap-keys).
               If unspecified, the imported image is treated as unencrypted.
        :param EncryptionKeyIdentity encryption_key: (optional) The root key that
               was used to wrap the data key (which is ultimately represented as
               `encrypted_data_key`). Additionally, the root key will be used to encrypt
               volumes
               created from this image (unless an alternate `encryption_key` is specified
               at volume
               creation).
               If unspecified, the imported image is treated as unencrypted.
        """
        # pylint: disable=super-init-not-called
        self.deprecation_at = deprecation_at
        self.name = name
        self.obsolescence_at = obsolescence_at
        self.resource_group = resource_group
        self.encrypted_data_key = encrypted_data_key
        self.encryption_key = encryption_key
        self.file = file
        self.operating_system = operating_system

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ImagePrototypeImageByFile':
        """Initialize a ImagePrototypeImageByFile object from a json dictionary."""
        args = {}
        if 'deprecation_at' in _dict:
            args['deprecation_at'] = string_to_datetime(_dict.get('deprecation_at'))
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        if 'obsolescence_at' in _dict:
            args['obsolescence_at'] = string_to_datetime(_dict.get('obsolescence_at'))
        if 'resource_group' in _dict:
            args['resource_group'] = _dict.get('resource_group')
        if 'encrypted_data_key' in _dict:
            args['encrypted_data_key'] = _dict.get('encrypted_data_key')
        if 'encryption_key' in _dict:
            args['encryption_key'] = _dict.get('encryption_key')
        if 'file' in _dict:
            args['file'] = ImageFilePrototype.from_dict(_dict.get('file'))
        else:
            raise ValueError('Required property \'file\' not present in ImagePrototypeImageByFile JSON')
        if 'operating_system' in _dict:
            args['operating_system'] = _dict.get('operating_system')
        else:
            raise ValueError('Required property \'operating_system\' not present in ImagePrototypeImageByFile JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ImagePrototypeImageByFile object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'deprecation_at') and self.deprecation_at is not None:
            _dict['deprecation_at'] = datetime_to_string(self.deprecation_at)
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'obsolescence_at') and self.obsolescence_at is not None:
            _dict['obsolescence_at'] = datetime_to_string(self.obsolescence_at)
        if hasattr(self, 'resource_group') and self.resource_group is not None:
            if isinstance(self.resource_group, dict):
                _dict['resource_group'] = self.resource_group
            else:
                _dict['resource_group'] = self.resource_group.to_dict()
        if hasattr(self, 'encrypted_data_key') and self.encrypted_data_key is not None:
            _dict['encrypted_data_key'] = self.encrypted_data_key
        if hasattr(self, 'encryption_key') and self.encryption_key is not None:
            if isinstance(self.encryption_key, dict):
                _dict['encryption_key'] = self.encryption_key
            else:
                _dict['encryption_key'] = self.encryption_key.to_dict()
        if hasattr(self, 'file') and self.file is not None:
            if isinstance(self.file, dict):
                _dict['file'] = self.file
            else:
                _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 ImagePrototypeImageBySourceVolume(ImagePrototype):
    """
    ImagePrototypeImageBySourceVolume.

    :attr datetime deprecation_at: (optional) The deprecation date and time to set
          for this image.
          The date and time must not be in the past, and must be earlier than
          `obsolescence_at`
          (if `obsolescence_at` is set).
          If unspecified, no deprecation date and time will be set.
          If the deprecation date and time is reached while the image has a status of
          `pending`, the image's status will transition to `deprecated` upon its
          successful creation (or
          `obsolete` if the obsolescence date and time was also reached).
    :attr str name: (optional) The name for this image. The name must not be used by
          another image in the region. Names starting with `ibm-` are reserved for
          system-provided images, and are not allowed. If unspecified, the name will be a
          hyphenated list of randomly-selected words.
    :attr datetime obsolescence_at: (optional) The obsolescence date and time to set
          for this image.
          The date and time must not be in the past, and must be later than
          `deprecation_at` (if
          `deprecation_at` is set).
          If unspecified, no obsolescence date and time will be set.
          If the obsolescence date and time is reached while the image has a status of
          `pending`, the image's status will transition to `obsolete` upon its successful
          creation.
    :attr ResourceGroupIdentity resource_group: (optional)
    :attr EncryptionKeyIdentity encryption_key: (optional) The root key used to wrap
          the system-generated data encryption key for the image.
          If unspecified, the root key from `source_volume` will be used.
    :attr VolumeIdentity source_volume: The volume from which to create the image.
          The specified volume must:
          - Have an `operating_system`, which will be used to populate this image's
            operating system information.
          - Not be `active` or `busy`.
          During image creation, the specified volume may briefly become `busy`.
    """

    def __init__(
        self,
        source_volume: 'VolumeIdentity',
        *,
        deprecation_at: datetime = None,
        name: str = None,
        obsolescence_at: datetime = None,
        resource_group: 'ResourceGroupIdentity' = None,
        encryption_key: 'EncryptionKeyIdentity' = None,
    ) -> None:
        """
        Initialize a ImagePrototypeImageBySourceVolume object.

        :param VolumeIdentity source_volume: The volume from which to create the
               image. The specified volume must:
               - Have an `operating_system`, which will be used to populate this image's
                 operating system information.
               - Not be `active` or `busy`.
               During image creation, the specified volume may briefly become `busy`.
        :param datetime deprecation_at: (optional) The deprecation date and time to
               set for this image.
               The date and time must not be in the past, and must be earlier than
               `obsolescence_at`
               (if `obsolescence_at` is set).
               If unspecified, no deprecation date and time will be set.
               If the deprecation date and time is reached while the image has a status of
               `pending`, the image's status will transition to `deprecated` upon its
               successful creation (or
               `obsolete` if the obsolescence date and time was also reached).
        :param str name: (optional) The name for this image. The name must not be
               used by another image in the region. Names starting with `ibm-` are
               reserved for system-provided images, and are not allowed. If unspecified,
               the name will be a hyphenated list of randomly-selected words.
        :param datetime obsolescence_at: (optional) The obsolescence date and time
               to set for this image.
               The date and time must not be in the past, and must be later than
               `deprecation_at` (if
               `deprecation_at` is set).
               If unspecified, no obsolescence date and time will be set.
               If the obsolescence date and time is reached while the image has a status
               of
               `pending`, the image's status will transition to `obsolete` upon its
               successful creation.
        :param ResourceGroupIdentity resource_group: (optional)
        :param EncryptionKeyIdentity encryption_key: (optional) The root key used
               to wrap the system-generated data encryption key for the image.
               If unspecified, the root key from `source_volume` will be used.
        """
        # pylint: disable=super-init-not-called
        self.deprecation_at = deprecation_at
        self.name = name
        self.obsolescence_at = obsolescence_at
        self.resource_group = resource_group
        self.encryption_key = encryption_key
        self.source_volume = source_volume

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ImagePrototypeImageBySourceVolume':
        """Initialize a ImagePrototypeImageBySourceVolume object from a json dictionary."""
        args = {}
        if 'deprecation_at' in _dict:
            args['deprecation_at'] = string_to_datetime(_dict.get('deprecation_at'))
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        if 'obsolescence_at' in _dict:
            args['obsolescence_at'] = string_to_datetime(_dict.get('obsolescence_at'))
        if 'resource_group' in _dict:
            args['resource_group'] = _dict.get('resource_group')
        if 'encryption_key' in _dict:
            args['encryption_key'] = _dict.get('encryption_key')
        if 'source_volume' in _dict:
            args['source_volume'] = _dict.get('source_volume')
        else:
            raise ValueError('Required property \'source_volume\' not present in ImagePrototypeImageBySourceVolume JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ImagePrototypeImageBySourceVolume object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'deprecation_at') and self.deprecation_at is not None:
            _dict['deprecation_at'] = datetime_to_string(self.deprecation_at)
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'obsolescence_at') and self.obsolescence_at is not None:
            _dict['obsolescence_at'] = datetime_to_string(self.obsolescence_at)
        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, '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, 'source_volume') and self.source_volume is not None:
            if isinstance(self.source_volume, dict):
                _dict['source_volume'] = self.source_volume
            else:
                _dict['source_volume'] = self.source_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 ImagePrototypeImageBySourceVolume object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ImagePrototypeImageBySourceVolume') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ImagePrototypeImageBySourceVolume') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceCatalogOfferingPrototypeCatalogOfferingByOffering(InstanceCatalogOfferingPrototype):
    """
    InstanceCatalogOfferingPrototypeCatalogOfferingByOffering.

    :attr CatalogOfferingIdentity offering: Identifies a
          [catalog](https://cloud.ibm.com/docs/account?topic=account-restrict-by-user)
          offering by a unique property.
    """

    def __init__(
        self,
        offering: 'CatalogOfferingIdentity',
    ) -> None:
        """
        Initialize a InstanceCatalogOfferingPrototypeCatalogOfferingByOffering object.

        :param CatalogOfferingIdentity offering: Identifies a
               [catalog](https://cloud.ibm.com/docs/account?topic=account-restrict-by-user)
               offering by a unique property.
        """
        # pylint: disable=super-init-not-called
        self.offering = offering

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceCatalogOfferingPrototypeCatalogOfferingByOffering':
        """Initialize a InstanceCatalogOfferingPrototypeCatalogOfferingByOffering object from a json dictionary."""
        args = {}
        if 'offering' in _dict:
            args['offering'] = _dict.get('offering')
        else:
            raise ValueError('Required property \'offering\' not present in InstanceCatalogOfferingPrototypeCatalogOfferingByOffering JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceCatalogOfferingPrototypeCatalogOfferingByOffering object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'offering') and self.offering is not None:
            if isinstance(self.offering, dict):
                _dict['offering'] = self.offering
            else:
                _dict['offering'] = self.offering.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 InstanceCatalogOfferingPrototypeCatalogOfferingByOffering object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceCatalogOfferingPrototypeCatalogOfferingByOffering') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceCatalogOfferingPrototypeCatalogOfferingByOffering') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceCatalogOfferingPrototypeCatalogOfferingByVersion(InstanceCatalogOfferingPrototype):
    """
    InstanceCatalogOfferingPrototypeCatalogOfferingByVersion.

    :attr CatalogOfferingVersionIdentity version: Identifies a version of a
          [catalog](https://cloud.ibm.com/docs/account?topic=account-restrict-by-user)
          offering by a
          unique property.
    """

    def __init__(
        self,
        version: 'CatalogOfferingVersionIdentity',
    ) -> None:
        """
        Initialize a InstanceCatalogOfferingPrototypeCatalogOfferingByVersion object.

        :param CatalogOfferingVersionIdentity version: Identifies a version of a
               [catalog](https://cloud.ibm.com/docs/account?topic=account-restrict-by-user)
               offering by a
               unique property.
        """
        # pylint: disable=super-init-not-called
        self.version = version

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceCatalogOfferingPrototypeCatalogOfferingByVersion':
        """Initialize a InstanceCatalogOfferingPrototypeCatalogOfferingByVersion object from a json dictionary."""
        args = {}
        if 'version' in _dict:
            args['version'] = _dict.get('version')
        else:
            raise ValueError('Required property \'version\' not present in InstanceCatalogOfferingPrototypeCatalogOfferingByVersion JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceCatalogOfferingPrototypeCatalogOfferingByVersion object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'version') and self.version is not None:
            if isinstance(self.version, dict):
                _dict['version'] = self.version
            else:
                _dict['version'] = self.version.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 InstanceCatalogOfferingPrototypeCatalogOfferingByVersion object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceCatalogOfferingPrototypeCatalogOfferingByVersion') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceCatalogOfferingPrototypeCatalogOfferingByVersion') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceGroupManagerActionPrototypeScheduledActionPrototype(InstanceGroupManagerActionPrototype):
    """
    InstanceGroupManagerActionPrototypeScheduledActionPrototype.

    :attr str name: (optional) The name for this instance group manager action. The
          name must not be used by another action for the instance group manager. If
          unspecified, the name will be a hyphenated list of randomly-selected words.
    """

    def __init__(
        self,
        *,
        name: str = None,
    ) -> None:
        """
        Initialize a InstanceGroupManagerActionPrototypeScheduledActionPrototype object.

        :param str name: (optional) The name for this instance group manager
               action. The name must not be used by another action for the instance group
               manager. If unspecified, the name will be a hyphenated list of
               randomly-selected words.
        """
        # pylint: disable=super-init-not-called
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['InstanceGroupManagerActionPrototypeScheduledActionPrototypeByRunAt', 'InstanceGroupManagerActionPrototypeScheduledActionPrototypeByCronSpec'])
        )
        raise Exception(msg)


class InstanceGroupManagerActionScheduledAction(InstanceGroupManagerAction):
    """
    InstanceGroupManagerActionScheduledAction.

    :attr bool auto_delete: Indicates whether this scheduled action will be
          automatically deleted after it has completed and `auto_delete_timeout` hours
          have passed. At present, this is always
          `true`, but may be modifiable in the future.
    :attr int auto_delete_timeout: If `auto_delete` is `true`, and this scheduled
          action has finished, the hours after which it will be automatically deleted. If
          the value is `0`, the action will be deleted once it has finished. This value
          may be modifiable in the future.
    :attr datetime created_at: The date and time that the instance group manager
          action was created.
    :attr str href: The URL for this instance group manager action.
    :attr str id: The unique identifier for this instance group manager action.
    :attr str name: The name for this instance group manager action. The name is
          unique across all actions for the instance group manager.
    :attr str resource_type: The resource type.
    :attr str status: The status of the instance group action
          - `active`: Action is ready to be run
          - `completed`: Action was completed successfully
          - `failed`: Action could not be completed successfully
          - `incompatible`: Action parameters are not compatible with the group or manager
          - `omitted`: Action was not applied because this action's manager was disabled.
    :attr datetime updated_at: The date and time that the instance group manager
          action was updated.
    :attr str action_type: The type of action for the instance group.
    :attr str cron_spec: (optional) The cron specification for a recurring scheduled
          action. Actions can be applied a maximum of one time within a 5 min period.
    :attr datetime last_applied_at: (optional) The date and time the scheduled
          action was last applied. If absent, the action has never been applied.
    :attr datetime next_run_at: (optional) The date and time the scheduled action
          will next run. If absent, the system is currently calculating the next run time.
    """

    def __init__(
        self,
        auto_delete: bool,
        auto_delete_timeout: int,
        created_at: datetime,
        href: str,
        id: str,
        name: str,
        resource_type: str,
        status: str,
        updated_at: datetime,
        action_type: str,
        *,
        cron_spec: str = None,
        last_applied_at: datetime = None,
        next_run_at: datetime = None,
    ) -> None:
        """
        Initialize a InstanceGroupManagerActionScheduledAction object.

        :param bool auto_delete: Indicates whether this scheduled action will be
               automatically deleted after it has completed and `auto_delete_timeout`
               hours have passed. At present, this is always
               `true`, but may be modifiable in the future.
        :param int auto_delete_timeout: If `auto_delete` is `true`, and this
               scheduled action has finished, the hours after which it will be
               automatically deleted. If the value is `0`, the action will be deleted once
               it has finished. This value may be modifiable in the future.
        :param datetime created_at: The date and time that the instance group
               manager action was created.
        :param str href: The URL for this instance group manager action.
        :param str id: The unique identifier for this instance group manager
               action.
        :param str name: The name for this instance group manager action. The name
               is unique across all actions for the instance group manager.
        :param str resource_type: The resource type.
        :param str status: The status of the instance group action
               - `active`: Action is ready to be run
               - `completed`: Action was completed successfully
               - `failed`: Action could not be completed successfully
               - `incompatible`: Action parameters are not compatible with the group or
               manager
               - `omitted`: Action was not applied because this action's manager was
               disabled.
        :param datetime updated_at: The date and time that the instance group
               manager action was updated.
        :param str action_type: The type of action for the instance group.
        :param str cron_spec: (optional) The cron specification for a recurring
               scheduled action. Actions can be applied a maximum of one time within a 5
               min period.
        :param datetime last_applied_at: (optional) The date and time the scheduled
               action was last applied. If absent, the action has never been applied.
        :param datetime next_run_at: (optional) The date and time the scheduled
               action will next run. If absent, the system is currently calculating the
               next run time.
        """
        # pylint: disable=super-init-not-called
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['InstanceGroupManagerActionScheduledActionGroupTarget', 'InstanceGroupManagerActionScheduledActionManagerTarget'])
        )
        raise Exception(msg)

    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        INSTANCE_GROUP_MANAGER_ACTION = 'instance_group_manager_action'


    class StatusEnum(str, Enum):
        """
        The status of the instance group action
        - `active`: Action is ready to be run
        - `completed`: Action was completed successfully
        - `failed`: Action could not be completed successfully
        - `incompatible`: Action parameters are not compatible with the group or manager
        - `omitted`: Action was not applied because this action's manager was disabled.
        """

        ACTIVE = 'active'
        COMPLETED = 'completed'
        FAILED = 'failed'
        INCOMPATIBLE = 'incompatible'
        OMITTED = 'omitted'


    class ActionTypeEnum(str, Enum):
        """
        The type of action for the instance group.
        """

        SCHEDULED = 'scheduled'



class InstanceGroupManagerAutoScale(InstanceGroupManager):
    """
    InstanceGroupManagerAutoScale.

    :attr datetime created_at: The date and time that the instance group manager was
          created.
    :attr str href: The URL for this instance group manager.
    :attr str id: The unique identifier for this instance group manager.
    :attr bool management_enabled: Indicates whether this manager will control the
          instance group.
    :attr str name: The name for this instance group manager. The name is unique
          across all managers for the instance group.
    :attr datetime updated_at: The date and time that the instance group manager was
          updated.
    :attr int aggregation_window: The time window in seconds to aggregate metrics
          prior to evaluation.
    :attr int cooldown: The duration of time in seconds to pause further scale
          actions after scaling has taken place.
    :attr str manager_type: The type of instance group manager.
    :attr int max_membership_count: The maximum number of members in a managed
          instance group.
    :attr int min_membership_count: The minimum number of members in a managed
          instance group.
    :attr List[InstanceGroupManagerPolicyReference] policies: The policies of the
          instance group manager.
    """

    def __init__(
        self,
        created_at: datetime,
        href: str,
        id: str,
        management_enabled: bool,
        name: str,
        updated_at: datetime,
        aggregation_window: int,
        cooldown: int,
        manager_type: str,
        max_membership_count: int,
        min_membership_count: int,
        policies: List['InstanceGroupManagerPolicyReference'],
    ) -> None:
        """
        Initialize a InstanceGroupManagerAutoScale object.

        :param datetime created_at: The date and time that the instance group
               manager was created.
        :param str href: The URL for this instance group manager.
        :param str id: The unique identifier for this instance group manager.
        :param bool management_enabled: Indicates whether this manager will control
               the instance group.
        :param str name: The name for this instance group manager. The name is
               unique across all managers for the instance group.
        :param datetime updated_at: The date and time that the instance group
               manager was updated.
        :param int aggregation_window: The time window in seconds to aggregate
               metrics prior to evaluation.
        :param int cooldown: The duration of time in seconds to pause further scale
               actions after scaling has taken place.
        :param str manager_type: The type of instance group manager.
        :param int max_membership_count: The maximum number of members in a managed
               instance group.
        :param int min_membership_count: The minimum number of members in a managed
               instance group.
        :param List[InstanceGroupManagerPolicyReference] policies: The policies of
               the instance group manager.
        """
        # pylint: disable=super-init-not-called
        self.created_at = created_at
        self.href = href
        self.id = id
        self.management_enabled = management_enabled
        self.name = name
        self.updated_at = updated_at
        self.aggregation_window = aggregation_window
        self.cooldown = cooldown
        self.manager_type = manager_type
        self.max_membership_count = max_membership_count
        self.min_membership_count = min_membership_count
        self.policies = policies

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceGroupManagerAutoScale':
        """Initialize a InstanceGroupManagerAutoScale object from a json dictionary."""
        args = {}
        if 'created_at' in _dict:
            args['created_at'] = string_to_datetime(_dict.get('created_at'))
        else:
            raise ValueError('Required property \'created_at\' not present in InstanceGroupManagerAutoScale JSON')
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in InstanceGroupManagerAutoScale JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in InstanceGroupManagerAutoScale JSON')
        if 'management_enabled' in _dict:
            args['management_enabled'] = _dict.get('management_enabled')
        else:
            raise ValueError('Required property \'management_enabled\' not present in InstanceGroupManagerAutoScale JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in InstanceGroupManagerAutoScale JSON')
        if 'updated_at' in _dict:
            args['updated_at'] = string_to_datetime(_dict.get('updated_at'))
        else:
            raise ValueError('Required property \'updated_at\' not present in InstanceGroupManagerAutoScale JSON')
        if 'aggregation_window' in _dict:
            args['aggregation_window'] = _dict.get('aggregation_window')
        else:
            raise ValueError('Required property \'aggregation_window\' not present in InstanceGroupManagerAutoScale JSON')
        if 'cooldown' in _dict:
            args['cooldown'] = _dict.get('cooldown')
        else:
            raise ValueError('Required property \'cooldown\' not present in InstanceGroupManagerAutoScale JSON')
        if 'manager_type' in _dict:
            args['manager_type'] = _dict.get('manager_type')
        else:
            raise ValueError('Required property \'manager_type\' not present in InstanceGroupManagerAutoScale JSON')
        if 'max_membership_count' in _dict:
            args['max_membership_count'] = _dict.get('max_membership_count')
        else:
            raise ValueError('Required property \'max_membership_count\' not present in InstanceGroupManagerAutoScale JSON')
        if 'min_membership_count' in _dict:
            args['min_membership_count'] = _dict.get('min_membership_count')
        else:
            raise ValueError('Required property \'min_membership_count\' not present in InstanceGroupManagerAutoScale JSON')
        if 'policies' in _dict:
            args['policies'] = [InstanceGroupManagerPolicyReference.from_dict(v) for v in _dict.get('policies')]
        else:
            raise ValueError('Required property \'policies\' not present in InstanceGroupManagerAutoScale JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceGroupManagerAutoScale object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'created_at') and self.created_at is not None:
            _dict['created_at'] = datetime_to_string(self.created_at)
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'management_enabled') and self.management_enabled is not None:
            _dict['management_enabled'] = self.management_enabled
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'updated_at') and self.updated_at is not None:
            _dict['updated_at'] = datetime_to_string(self.updated_at)
        if hasattr(self, 'aggregation_window') and self.aggregation_window is not None:
            _dict['aggregation_window'] = self.aggregation_window
        if hasattr(self, 'cooldown') and self.cooldown is not None:
            _dict['cooldown'] = self.cooldown
        if hasattr(self, 'manager_type') and self.manager_type is not None:
            _dict['manager_type'] = self.manager_type
        if hasattr(self, 'max_membership_count') and self.max_membership_count is not None:
            _dict['max_membership_count'] = self.max_membership_count
        if hasattr(self, 'min_membership_count') and self.min_membership_count is not None:
            _dict['min_membership_count'] = self.min_membership_count
        if hasattr(self, 'policies') and self.policies is not None:
            policies_list = []
            for v in self.policies:
                if isinstance(v, dict):
                    policies_list.append(v)
                else:
                    policies_list.append(v.to_dict())
            _dict['policies'] = policies_list
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceGroupManagerAutoScale object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceGroupManagerAutoScale') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceGroupManagerAutoScale') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ManagerTypeEnum(str, Enum):
        """
        The type of instance group manager.
        """

        AUTOSCALE = 'autoscale'



class InstanceGroupManagerPolicyPrototypeInstanceGroupManagerTargetPolicyPrototype(InstanceGroupManagerPolicyPrototype):
    """
    InstanceGroupManagerPolicyPrototypeInstanceGroupManagerTargetPolicyPrototype.

    :attr str name: (optional) The name for this instance group manager policy. The
          name must not be used by another policy for the instance group manager. If
          unspecified, the name will be a hyphenated list of randomly-selected words.
    :attr str metric_type: The type of metric to be evaluated.
    :attr int metric_value: The metric value to be evaluated.
    :attr str policy_type: The type of policy for the instance group.
    """

    def __init__(
        self,
        metric_type: str,
        metric_value: int,
        policy_type: str,
        *,
        name: str = None,
    ) -> None:
        """
        Initialize a InstanceGroupManagerPolicyPrototypeInstanceGroupManagerTargetPolicyPrototype object.

        :param str metric_type: The type of metric to be evaluated.
        :param int metric_value: The metric value to be evaluated.
        :param str policy_type: The type of policy for the instance group.
        :param str name: (optional) The name for this instance group manager
               policy. The name must not be used by another policy for the instance group
               manager. If unspecified, the name will be a hyphenated list of
               randomly-selected words.
        """
        # pylint: disable=super-init-not-called
        self.name = name
        self.metric_type = metric_type
        self.metric_value = metric_value
        self.policy_type = policy_type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceGroupManagerPolicyPrototypeInstanceGroupManagerTargetPolicyPrototype':
        """Initialize a InstanceGroupManagerPolicyPrototypeInstanceGroupManagerTargetPolicyPrototype object from a json dictionary."""
        args = {}
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        if 'metric_type' in _dict:
            args['metric_type'] = _dict.get('metric_type')
        else:
            raise ValueError('Required property \'metric_type\' not present in InstanceGroupManagerPolicyPrototypeInstanceGroupManagerTargetPolicyPrototype JSON')
        if 'metric_value' in _dict:
            args['metric_value'] = _dict.get('metric_value')
        else:
            raise ValueError('Required property \'metric_value\' not present in InstanceGroupManagerPolicyPrototypeInstanceGroupManagerTargetPolicyPrototype JSON')
        if 'policy_type' in _dict:
            args['policy_type'] = _dict.get('policy_type')
        else:
            raise ValueError('Required property \'policy_type\' not present in InstanceGroupManagerPolicyPrototypeInstanceGroupManagerTargetPolicyPrototype JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceGroupManagerPolicyPrototypeInstanceGroupManagerTargetPolicyPrototype object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'metric_type') and self.metric_type is not None:
            _dict['metric_type'] = self.metric_type
        if hasattr(self, 'metric_value') and self.metric_value is not None:
            _dict['metric_value'] = self.metric_value
        if hasattr(self, 'policy_type') and self.policy_type is not None:
            _dict['policy_type'] = self.policy_type
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceGroupManagerPolicyPrototypeInstanceGroupManagerTargetPolicyPrototype object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceGroupManagerPolicyPrototypeInstanceGroupManagerTargetPolicyPrototype') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceGroupManagerPolicyPrototypeInstanceGroupManagerTargetPolicyPrototype') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class MetricTypeEnum(str, Enum):
        """
        The type of metric to be evaluated.
        """

        CPU = 'cpu'
        MEMORY = 'memory'
        NETWORK_IN = 'network_in'
        NETWORK_OUT = 'network_out'


    class PolicyTypeEnum(str, Enum):
        """
        The type of policy for the instance group.
        """

        TARGET = 'target'



class InstanceGroupManagerPolicyInstanceGroupManagerTargetPolicy(InstanceGroupManagerPolicy):
    """
    InstanceGroupManagerPolicyInstanceGroupManagerTargetPolicy.

    :attr datetime created_at: The date and time that the instance group manager
          policy was created.
    :attr str href: The URL for this instance group manager policy.
    :attr str id: The unique identifier for this instance group manager policy.
    :attr str name: The name for this instance group manager policy. The name is
          unique across all policies for the instance group manager.
    :attr datetime updated_at: The date and time that the instance group manager
          policy was updated.
    :attr str metric_type: The type of metric to be evaluated.
    :attr int metric_value: The metric value to be evaluated.
    :attr str policy_type: The type of policy for the instance group.
    """

    def __init__(
        self,
        created_at: datetime,
        href: str,
        id: str,
        name: str,
        updated_at: datetime,
        metric_type: str,
        metric_value: int,
        policy_type: str,
    ) -> None:
        """
        Initialize a InstanceGroupManagerPolicyInstanceGroupManagerTargetPolicy object.

        :param datetime created_at: The date and time that the instance group
               manager policy was created.
        :param str href: The URL for this instance group manager policy.
        :param str id: The unique identifier for this instance group manager
               policy.
        :param str name: The name for this instance group manager policy. The name
               is unique across all policies for the instance group manager.
        :param datetime updated_at: The date and time that the instance group
               manager policy was updated.
        :param str metric_type: The type of metric to be evaluated.
        :param int metric_value: The metric value to be evaluated.
        :param str policy_type: The type of policy for the instance group.
        """
        # pylint: disable=super-init-not-called
        self.created_at = created_at
        self.href = href
        self.id = id
        self.name = name
        self.updated_at = updated_at
        self.metric_type = metric_type
        self.metric_value = metric_value
        self.policy_type = policy_type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceGroupManagerPolicyInstanceGroupManagerTargetPolicy':
        """Initialize a InstanceGroupManagerPolicyInstanceGroupManagerTargetPolicy object from a json dictionary."""
        args = {}
        if 'created_at' in _dict:
            args['created_at'] = string_to_datetime(_dict.get('created_at'))
        else:
            raise ValueError('Required property \'created_at\' not present in InstanceGroupManagerPolicyInstanceGroupManagerTargetPolicy JSON')
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in InstanceGroupManagerPolicyInstanceGroupManagerTargetPolicy JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in InstanceGroupManagerPolicyInstanceGroupManagerTargetPolicy JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in InstanceGroupManagerPolicyInstanceGroupManagerTargetPolicy JSON')
        if 'updated_at' in _dict:
            args['updated_at'] = string_to_datetime(_dict.get('updated_at'))
        else:
            raise ValueError('Required property \'updated_at\' not present in InstanceGroupManagerPolicyInstanceGroupManagerTargetPolicy JSON')
        if 'metric_type' in _dict:
            args['metric_type'] = _dict.get('metric_type')
        else:
            raise ValueError('Required property \'metric_type\' not present in InstanceGroupManagerPolicyInstanceGroupManagerTargetPolicy JSON')
        if 'metric_value' in _dict:
            args['metric_value'] = _dict.get('metric_value')
        else:
            raise ValueError('Required property \'metric_value\' not present in InstanceGroupManagerPolicyInstanceGroupManagerTargetPolicy JSON')
        if 'policy_type' in _dict:
            args['policy_type'] = _dict.get('policy_type')
        else:
            raise ValueError('Required property \'policy_type\' not present in InstanceGroupManagerPolicyInstanceGroupManagerTargetPolicy JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceGroupManagerPolicyInstanceGroupManagerTargetPolicy object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'created_at') and self.created_at is not None:
            _dict['created_at'] = datetime_to_string(self.created_at)
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'updated_at') and self.updated_at is not None:
            _dict['updated_at'] = datetime_to_string(self.updated_at)
        if hasattr(self, 'metric_type') and self.metric_type is not None:
            _dict['metric_type'] = self.metric_type
        if hasattr(self, 'metric_value') and self.metric_value is not None:
            _dict['metric_value'] = self.metric_value
        if hasattr(self, 'policy_type') and self.policy_type is not None:
            _dict['policy_type'] = self.policy_type
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceGroupManagerPolicyInstanceGroupManagerTargetPolicy object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceGroupManagerPolicyInstanceGroupManagerTargetPolicy') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceGroupManagerPolicyInstanceGroupManagerTargetPolicy') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class MetricTypeEnum(str, Enum):
        """
        The type of metric to be evaluated.
        """

        CPU = 'cpu'
        MEMORY = 'memory'
        NETWORK_IN = 'network_in'
        NETWORK_OUT = 'network_out'


    class PolicyTypeEnum(str, Enum):
        """
        The type of policy for the instance group.
        """

        TARGET = 'target'



class InstanceGroupManagerPrototypeInstanceGroupManagerAutoScalePrototype(InstanceGroupManagerPrototype):
    """
    InstanceGroupManagerPrototypeInstanceGroupManagerAutoScalePrototype.

    :attr bool management_enabled: (optional) Indicates whether this manager will
          control the instance group.
    :attr str name: (optional) The name for this instance group manager. The name
          must not be used by another manager for the instance group. If unspecified, the
          name will be a hyphenated list of randomly-selected words.
    :attr int aggregation_window: (optional) The time window in seconds to aggregate
          metrics prior to evaluation.
    :attr int cooldown: (optional) The duration of time in seconds to pause further
          scale actions after scaling has taken place.
    :attr str manager_type: The type of instance group manager.
    :attr int max_membership_count: The maximum number of members in a managed
          instance group.
    :attr int min_membership_count: (optional) The minimum number of members in a
          managed instance group.
    """

    def __init__(
        self,
        manager_type: str,
        max_membership_count: int,
        *,
        management_enabled: bool = None,
        name: str = None,
        aggregation_window: int = None,
        cooldown: int = None,
        min_membership_count: int = None,
    ) -> None:
        """
        Initialize a InstanceGroupManagerPrototypeInstanceGroupManagerAutoScalePrototype object.

        :param str manager_type: The type of instance group manager.
        :param int max_membership_count: The maximum number of members in a managed
               instance group.
        :param bool management_enabled: (optional) Indicates whether this manager
               will control the instance group.
        :param str name: (optional) The name for this instance group manager. The
               name must not be used by another manager for the instance group. If
               unspecified, the name will be a hyphenated list of randomly-selected words.
        :param int aggregation_window: (optional) The time window in seconds to
               aggregate metrics prior to evaluation.
        :param int cooldown: (optional) The duration of time in seconds to pause
               further scale actions after scaling has taken place.
        :param int min_membership_count: (optional) The minimum number of members
               in a managed instance group.
        """
        # pylint: disable=super-init-not-called
        self.management_enabled = management_enabled
        self.name = name
        self.aggregation_window = aggregation_window
        self.cooldown = cooldown
        self.manager_type = manager_type
        self.max_membership_count = max_membership_count
        self.min_membership_count = min_membership_count

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceGroupManagerPrototypeInstanceGroupManagerAutoScalePrototype':
        """Initialize a InstanceGroupManagerPrototypeInstanceGroupManagerAutoScalePrototype object from a json dictionary."""
        args = {}
        if 'management_enabled' in _dict:
            args['management_enabled'] = _dict.get('management_enabled')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        if 'aggregation_window' in _dict:
            args['aggregation_window'] = _dict.get('aggregation_window')
        if 'cooldown' in _dict:
            args['cooldown'] = _dict.get('cooldown')
        if 'manager_type' in _dict:
            args['manager_type'] = _dict.get('manager_type')
        else:
            raise ValueError('Required property \'manager_type\' not present in InstanceGroupManagerPrototypeInstanceGroupManagerAutoScalePrototype JSON')
        if 'max_membership_count' in _dict:
            args['max_membership_count'] = _dict.get('max_membership_count')
        else:
            raise ValueError('Required property \'max_membership_count\' not present in InstanceGroupManagerPrototypeInstanceGroupManagerAutoScalePrototype JSON')
        if 'min_membership_count' in _dict:
            args['min_membership_count'] = _dict.get('min_membership_count')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceGroupManagerPrototypeInstanceGroupManagerAutoScalePrototype object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'management_enabled') and self.management_enabled is not None:
            _dict['management_enabled'] = self.management_enabled
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'aggregation_window') and self.aggregation_window is not None:
            _dict['aggregation_window'] = self.aggregation_window
        if hasattr(self, 'cooldown') and self.cooldown is not None:
            _dict['cooldown'] = self.cooldown
        if hasattr(self, 'manager_type') and self.manager_type is not None:
            _dict['manager_type'] = self.manager_type
        if hasattr(self, 'max_membership_count') and self.max_membership_count is not None:
            _dict['max_membership_count'] = self.max_membership_count
        if hasattr(self, 'min_membership_count') and self.min_membership_count is not None:
            _dict['min_membership_count'] = self.min_membership_count
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceGroupManagerPrototypeInstanceGroupManagerAutoScalePrototype object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceGroupManagerPrototypeInstanceGroupManagerAutoScalePrototype') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceGroupManagerPrototypeInstanceGroupManagerAutoScalePrototype') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ManagerTypeEnum(str, Enum):
        """
        The type of instance group manager.
        """

        AUTOSCALE = 'autoscale'



class InstanceGroupManagerPrototypeInstanceGroupManagerScheduledPrototype(InstanceGroupManagerPrototype):
    """
    InstanceGroupManagerPrototypeInstanceGroupManagerScheduledPrototype.

    :attr bool management_enabled: (optional) Indicates whether this manager will
          control the instance group.
    :attr str name: (optional) The name for this instance group manager. The name
          must not be used by another manager for the instance group. If unspecified, the
          name will be a hyphenated list of randomly-selected words.
    :attr str manager_type: The type of instance group manager.
    """

    def __init__(
        self,
        manager_type: str,
        *,
        management_enabled: bool = None,
        name: str = None,
    ) -> None:
        """
        Initialize a InstanceGroupManagerPrototypeInstanceGroupManagerScheduledPrototype object.

        :param str manager_type: The type of instance group manager.
        :param bool management_enabled: (optional) Indicates whether this manager
               will control the instance group.
        :param str name: (optional) The name for this instance group manager. The
               name must not be used by another manager for the instance group. If
               unspecified, the name will be a hyphenated list of randomly-selected words.
        """
        # pylint: disable=super-init-not-called
        self.management_enabled = management_enabled
        self.name = name
        self.manager_type = manager_type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceGroupManagerPrototypeInstanceGroupManagerScheduledPrototype':
        """Initialize a InstanceGroupManagerPrototypeInstanceGroupManagerScheduledPrototype object from a json dictionary."""
        args = {}
        if 'management_enabled' in _dict:
            args['management_enabled'] = _dict.get('management_enabled')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        if 'manager_type' in _dict:
            args['manager_type'] = _dict.get('manager_type')
        else:
            raise ValueError('Required property \'manager_type\' not present in InstanceGroupManagerPrototypeInstanceGroupManagerScheduledPrototype JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceGroupManagerPrototypeInstanceGroupManagerScheduledPrototype object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'management_enabled') and self.management_enabled is not None:
            _dict['management_enabled'] = self.management_enabled
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'manager_type') and self.manager_type is not None:
            _dict['manager_type'] = self.manager_type
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceGroupManagerPrototypeInstanceGroupManagerScheduledPrototype object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceGroupManagerPrototypeInstanceGroupManagerScheduledPrototype') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceGroupManagerPrototypeInstanceGroupManagerScheduledPrototype') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ManagerTypeEnum(str, Enum):
        """
        The type of instance group manager.
        """

        SCHEDULED = 'scheduled'



class InstanceGroupManagerScheduled(InstanceGroupManager):
    """
    InstanceGroupManagerScheduled.

    :attr datetime created_at: The date and time that the instance group manager was
          created.
    :attr str href: The URL for this instance group manager.
    :attr str id: The unique identifier for this instance group manager.
    :attr bool management_enabled: Indicates whether this manager will control the
          instance group.
    :attr str name: The name for this instance group manager. The name is unique
          across all managers for the instance group.
    :attr datetime updated_at: The date and time that the instance group manager was
          updated.
    :attr List[InstanceGroupManagerActionReference] actions: The actions of the
          instance group manager.
    :attr str manager_type: The type of instance group manager.
    """

    def __init__(
        self,
        created_at: datetime,
        href: str,
        id: str,
        management_enabled: bool,
        name: str,
        updated_at: datetime,
        actions: List['InstanceGroupManagerActionReference'],
        manager_type: str,
    ) -> None:
        """
        Initialize a InstanceGroupManagerScheduled object.

        :param datetime created_at: The date and time that the instance group
               manager was created.
        :param str href: The URL for this instance group manager.
        :param str id: The unique identifier for this instance group manager.
        :param bool management_enabled: Indicates whether this manager will control
               the instance group.
        :param str name: The name for this instance group manager. The name is
               unique across all managers for the instance group.
        :param datetime updated_at: The date and time that the instance group
               manager was updated.
        :param List[InstanceGroupManagerActionReference] actions: The actions of
               the instance group manager.
        :param str manager_type: The type of instance group manager.
        """
        # pylint: disable=super-init-not-called
        self.created_at = created_at
        self.href = href
        self.id = id
        self.management_enabled = management_enabled
        self.name = name
        self.updated_at = updated_at
        self.actions = actions
        self.manager_type = manager_type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceGroupManagerScheduled':
        """Initialize a InstanceGroupManagerScheduled object from a json dictionary."""
        args = {}
        if 'created_at' in _dict:
            args['created_at'] = string_to_datetime(_dict.get('created_at'))
        else:
            raise ValueError('Required property \'created_at\' not present in InstanceGroupManagerScheduled JSON')
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in InstanceGroupManagerScheduled JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in InstanceGroupManagerScheduled JSON')
        if 'management_enabled' in _dict:
            args['management_enabled'] = _dict.get('management_enabled')
        else:
            raise ValueError('Required property \'management_enabled\' not present in InstanceGroupManagerScheduled JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in InstanceGroupManagerScheduled JSON')
        if 'updated_at' in _dict:
            args['updated_at'] = string_to_datetime(_dict.get('updated_at'))
        else:
            raise ValueError('Required property \'updated_at\' not present in InstanceGroupManagerScheduled JSON')
        if 'actions' in _dict:
            args['actions'] = [InstanceGroupManagerActionReference.from_dict(v) for v in _dict.get('actions')]
        else:
            raise ValueError('Required property \'actions\' not present in InstanceGroupManagerScheduled JSON')
        if 'manager_type' in _dict:
            args['manager_type'] = _dict.get('manager_type')
        else:
            raise ValueError('Required property \'manager_type\' not present in InstanceGroupManagerScheduled JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceGroupManagerScheduled object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'created_at') and self.created_at is not None:
            _dict['created_at'] = datetime_to_string(self.created_at)
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'management_enabled') and self.management_enabled is not None:
            _dict['management_enabled'] = self.management_enabled
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'updated_at') and self.updated_at is not None:
            _dict['updated_at'] = datetime_to_string(self.updated_at)
        if hasattr(self, 'actions') and self.actions is not None:
            actions_list = []
            for v in self.actions:
                if isinstance(v, dict):
                    actions_list.append(v)
                else:
                    actions_list.append(v.to_dict())
            _dict['actions'] = actions_list
        if hasattr(self, 'manager_type') and self.manager_type is not None:
            _dict['manager_type'] = self.manager_type
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceGroupManagerScheduled object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceGroupManagerScheduled') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceGroupManagerScheduled') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ManagerTypeEnum(str, Enum):
        """
        The type of instance group manager.
        """

        SCHEDULED = 'scheduled'



class InstanceGroupManagerScheduledActionManagerAutoScale(InstanceGroupManagerScheduledActionManager):
    """
    InstanceGroupManagerScheduledActionManagerAutoScale.

    :attr InstanceGroupManagerReferenceDeleted deleted: (optional) If present, this
          property indicates the referenced resource has been deleted, and provides
          some supplementary information.
    :attr str href: The URL for this instance group manager.
    :attr str id: The unique identifier for this instance group manager.
    :attr str name: The name for this instance group manager. The name is unique
          across all managers for the instance group.
    :attr int max_membership_count: (optional) The desired maximum number of
          instance group members at the scheduled time.
    :attr int min_membership_count: (optional) The desired minimum number of
          instance group members at the scheduled time.
    """

    def __init__(
        self,
        href: str,
        id: str,
        name: str,
        *,
        deleted: 'InstanceGroupManagerReferenceDeleted' = None,
        max_membership_count: int = None,
        min_membership_count: int = None,
    ) -> None:
        """
        Initialize a InstanceGroupManagerScheduledActionManagerAutoScale object.

        :param str href: The URL for this instance group manager.
        :param str id: The unique identifier for this instance group manager.
        :param str name: The name for this instance group manager. The name is
               unique across all managers for the instance group.
        :param InstanceGroupManagerReferenceDeleted deleted: (optional) If present,
               this property indicates the referenced resource has been deleted, and
               provides
               some supplementary information.
        :param int max_membership_count: (optional) The desired maximum number of
               instance group members at the scheduled time.
        :param int min_membership_count: (optional) The desired minimum number of
               instance group members at the scheduled time.
        """
        # pylint: disable=super-init-not-called
        self.deleted = deleted
        self.href = href
        self.id = id
        self.name = name
        self.max_membership_count = max_membership_count
        self.min_membership_count = min_membership_count

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceGroupManagerScheduledActionManagerAutoScale':
        """Initialize a InstanceGroupManagerScheduledActionManagerAutoScale object from a json dictionary."""
        args = {}
        if 'deleted' in _dict:
            args['deleted'] = InstanceGroupManagerReferenceDeleted.from_dict(_dict.get('deleted'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in InstanceGroupManagerScheduledActionManagerAutoScale JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in InstanceGroupManagerScheduledActionManagerAutoScale JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in InstanceGroupManagerScheduledActionManagerAutoScale JSON')
        if 'max_membership_count' in _dict:
            args['max_membership_count'] = _dict.get('max_membership_count')
        if 'min_membership_count' in _dict:
            args['min_membership_count'] = _dict.get('min_membership_count')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceGroupManagerScheduledActionManagerAutoScale object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'deleted') and self.deleted is not None:
            if isinstance(self.deleted, dict):
                _dict['deleted'] = self.deleted
            else:
                _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'max_membership_count') and self.max_membership_count is not None:
            _dict['max_membership_count'] = self.max_membership_count
        if hasattr(self, 'min_membership_count') and self.min_membership_count is not None:
            _dict['min_membership_count'] = self.min_membership_count
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceGroupManagerScheduledActionManagerAutoScale object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceGroupManagerScheduledActionManagerAutoScale') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceGroupManagerScheduledActionManagerAutoScale') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceGroupManagerScheduledActionManagerPrototypeAutoScalePrototype(InstanceGroupManagerScheduledActionManagerPrototype):
    """
    The auto scale manager to update, and one or more properties to be updated. Either
    `id` or `href` must be specified, in addition to at least one of
    `min_membership_count` and
    `max_membership_count`.

    :attr int max_membership_count: (optional) The desired maximum number of
          instance group members at the scheduled time.
    :attr int min_membership_count: (optional) The desired minimum number of
          instance group members at the scheduled time.
    """

    def __init__(
        self,
        *,
        max_membership_count: int = None,
        min_membership_count: int = None,
    ) -> None:
        """
        Initialize a InstanceGroupManagerScheduledActionManagerPrototypeAutoScalePrototype object.

        :param int max_membership_count: (optional) The desired maximum number of
               instance group members at the scheduled time.
        :param int min_membership_count: (optional) The desired minimum number of
               instance group members at the scheduled time.
        """
        # pylint: disable=super-init-not-called
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['InstanceGroupManagerScheduledActionManagerPrototypeAutoScalePrototypeById', 'InstanceGroupManagerScheduledActionManagerPrototypeAutoScalePrototypeByHref'])
        )
        raise Exception(msg)


class InstancePatchProfileInstanceProfileIdentityByHref(InstancePatchProfile):
    """
    InstancePatchProfileInstanceProfileIdentityByHref.

    :attr str href: The URL for this virtual server instance profile.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a InstancePatchProfileInstanceProfileIdentityByHref object.

        :param str href: The URL for this virtual server instance profile.
        """
        # pylint: disable=super-init-not-called
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstancePatchProfileInstanceProfileIdentityByHref':
        """Initialize a InstancePatchProfileInstanceProfileIdentityByHref object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in InstancePatchProfileInstanceProfileIdentityByHref JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstancePatchProfileInstanceProfileIdentityByHref object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstancePatchProfileInstanceProfileIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstancePatchProfileInstanceProfileIdentityByHref') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstancePatchProfileInstanceProfileIdentityByHref') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstancePatchProfileInstanceProfileIdentityByName(InstancePatchProfile):
    """
    InstancePatchProfileInstanceProfileIdentityByName.

    :attr str name: The globally unique name for this virtual server instance
          profile.
    """

    def __init__(
        self,
        name: str,
    ) -> None:
        """
        Initialize a InstancePatchProfileInstanceProfileIdentityByName object.

        :param str name: The globally unique name for this virtual server instance
               profile.
        """
        # pylint: disable=super-init-not-called
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstancePatchProfileInstanceProfileIdentityByName':
        """Initialize a InstancePatchProfileInstanceProfileIdentityByName object from a json dictionary."""
        args = {}
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in InstancePatchProfileInstanceProfileIdentityByName JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstancePatchProfileInstanceProfileIdentityByName object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstancePatchProfileInstanceProfileIdentityByName object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstancePatchProfileInstanceProfileIdentityByName') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstancePatchProfileInstanceProfileIdentityByName') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstancePlacementTargetPatchDedicatedHostGroupIdentity(InstancePlacementTargetPatch):
    """
    Identifies a dedicated host group by a unique property.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a InstancePlacementTargetPatchDedicatedHostGroupIdentity object.

        """
        # pylint: disable=super-init-not-called
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['InstancePlacementTargetPatchDedicatedHostGroupIdentityDedicatedHostGroupIdentityById', 'InstancePlacementTargetPatchDedicatedHostGroupIdentityDedicatedHostGroupIdentityByCRN', 'InstancePlacementTargetPatchDedicatedHostGroupIdentityDedicatedHostGroupIdentityByHref'])
        )
        raise Exception(msg)


class InstancePlacementTargetPatchDedicatedHostIdentity(InstancePlacementTargetPatch):
    """
    Identifies a dedicated host by a unique property.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a InstancePlacementTargetPatchDedicatedHostIdentity object.

        """
        # pylint: disable=super-init-not-called
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['InstancePlacementTargetPatchDedicatedHostIdentityDedicatedHostIdentityById', 'InstancePlacementTargetPatchDedicatedHostIdentityDedicatedHostIdentityByCRN', 'InstancePlacementTargetPatchDedicatedHostIdentityDedicatedHostIdentityByHref'])
        )
        raise Exception(msg)


class InstancePlacementTargetPrototypeDedicatedHostGroupIdentity(InstancePlacementTargetPrototype):
    """
    Identifies a dedicated host group by a unique property.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a InstancePlacementTargetPrototypeDedicatedHostGroupIdentity object.

        """
        # pylint: disable=super-init-not-called
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['InstancePlacementTargetPrototypeDedicatedHostGroupIdentityDedicatedHostGroupIdentityById', 'InstancePlacementTargetPrototypeDedicatedHostGroupIdentityDedicatedHostGroupIdentityByCRN', 'InstancePlacementTargetPrototypeDedicatedHostGroupIdentityDedicatedHostGroupIdentityByHref'])
        )
        raise Exception(msg)


class InstancePlacementTargetPrototypeDedicatedHostIdentity(InstancePlacementTargetPrototype):
    """
    Identifies a dedicated host by a unique property.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a InstancePlacementTargetPrototypeDedicatedHostIdentity object.

        """
        # pylint: disable=super-init-not-called
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['InstancePlacementTargetPrototypeDedicatedHostIdentityDedicatedHostIdentityById', 'InstancePlacementTargetPrototypeDedicatedHostIdentityDedicatedHostIdentityByCRN', 'InstancePlacementTargetPrototypeDedicatedHostIdentityDedicatedHostIdentityByHref'])
        )
        raise Exception(msg)


class InstancePlacementTargetPrototypePlacementGroupIdentity(InstancePlacementTargetPrototype):
    """
    Identifies a placement group by a unique property.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a InstancePlacementTargetPrototypePlacementGroupIdentity object.

        """
        # pylint: disable=super-init-not-called
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['InstancePlacementTargetPrototypePlacementGroupIdentityPlacementGroupIdentityById', 'InstancePlacementTargetPrototypePlacementGroupIdentityPlacementGroupIdentityByCRN', 'InstancePlacementTargetPrototypePlacementGroupIdentityPlacementGroupIdentityByHref'])
        )
        raise Exception(msg)


class InstancePlacementTargetDedicatedHostGroupReference(InstancePlacementTarget):
    """
    InstancePlacementTargetDedicatedHostGroupReference.

    :attr str crn: The CRN for this dedicated host group.
    :attr DedicatedHostGroupReferenceDeleted deleted: (optional) If present, this
          property indicates the referenced resource has been deleted, and provides
          some supplementary information.
    :attr str href: The URL for this dedicated host group.
    :attr str id: The unique identifier for this dedicated host group.
    :attr str name: The name for this dedicated host group. The name is unique
          across all dedicated host groups in the region.
    :attr str resource_type: The resource type.
    """

    def __init__(
        self,
        crn: str,
        href: str,
        id: str,
        name: str,
        resource_type: str,
        *,
        deleted: 'DedicatedHostGroupReferenceDeleted' = None,
    ) -> None:
        """
        Initialize a InstancePlacementTargetDedicatedHostGroupReference object.

        :param str crn: The CRN for this dedicated host group.
        :param str href: The URL for this dedicated host group.
        :param str id: The unique identifier for this dedicated host group.
        :param str name: The name for this dedicated host group. The name is unique
               across all dedicated host groups in the region.
        :param str resource_type: The resource type.
        :param DedicatedHostGroupReferenceDeleted deleted: (optional) If present,
               this property indicates the referenced resource has been deleted, and
               provides
               some supplementary information.
        """
        # pylint: disable=super-init-not-called
        self.crn = crn
        self.deleted = deleted
        self.href = href
        self.id = id
        self.name = name
        self.resource_type = resource_type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstancePlacementTargetDedicatedHostGroupReference':
        """Initialize a InstancePlacementTargetDedicatedHostGroupReference object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError('Required property \'crn\' not present in InstancePlacementTargetDedicatedHostGroupReference JSON')
        if 'deleted' in _dict:
            args['deleted'] = DedicatedHostGroupReferenceDeleted.from_dict(_dict.get('deleted'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in InstancePlacementTargetDedicatedHostGroupReference JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in InstancePlacementTargetDedicatedHostGroupReference JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in InstancePlacementTargetDedicatedHostGroupReference JSON')
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError('Required property \'resource_type\' not present in InstancePlacementTargetDedicatedHostGroupReference JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstancePlacementTargetDedicatedHostGroupReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'deleted') and self.deleted is not None:
            if isinstance(self.deleted, dict):
                _dict['deleted'] = self.deleted
            else:
                _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'resource_type') and self.resource_type is not None:
            _dict['resource_type'] = self.resource_type
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstancePlacementTargetDedicatedHostGroupReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstancePlacementTargetDedicatedHostGroupReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstancePlacementTargetDedicatedHostGroupReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        DEDICATED_HOST_GROUP = 'dedicated_host_group'



class InstancePlacementTargetDedicatedHostReference(InstancePlacementTarget):
    """
    InstancePlacementTargetDedicatedHostReference.

    :attr str crn: The CRN for this dedicated host.
    :attr DedicatedHostReferenceDeleted deleted: (optional) If present, this
          property indicates the referenced resource has been deleted, and provides
          some supplementary information.
    :attr str href: The URL for this dedicated host.
    :attr str id: The unique identifier for this dedicated host.
    :attr str name: The name for this dedicated host. The name is unique across all
          dedicated hosts in the region.
    :attr str resource_type: The resource type.
    """

    def __init__(
        self,
        crn: str,
        href: str,
        id: str,
        name: str,
        resource_type: str,
        *,
        deleted: 'DedicatedHostReferenceDeleted' = None,
    ) -> None:
        """
        Initialize a InstancePlacementTargetDedicatedHostReference object.

        :param str crn: The CRN for this dedicated host.
        :param str href: The URL for this dedicated host.
        :param str id: The unique identifier for this dedicated host.
        :param str name: The name for this dedicated host. The name is unique
               across all dedicated hosts in the region.
        :param str resource_type: The resource type.
        :param DedicatedHostReferenceDeleted deleted: (optional) If present, this
               property indicates the referenced resource has been deleted, and provides
               some supplementary information.
        """
        # pylint: disable=super-init-not-called
        self.crn = crn
        self.deleted = deleted
        self.href = href
        self.id = id
        self.name = name
        self.resource_type = resource_type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstancePlacementTargetDedicatedHostReference':
        """Initialize a InstancePlacementTargetDedicatedHostReference object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError('Required property \'crn\' not present in InstancePlacementTargetDedicatedHostReference JSON')
        if 'deleted' in _dict:
            args['deleted'] = DedicatedHostReferenceDeleted.from_dict(_dict.get('deleted'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in InstancePlacementTargetDedicatedHostReference JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in InstancePlacementTargetDedicatedHostReference JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in InstancePlacementTargetDedicatedHostReference JSON')
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError('Required property \'resource_type\' not present in InstancePlacementTargetDedicatedHostReference JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstancePlacementTargetDedicatedHostReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'deleted') and self.deleted is not None:
            if isinstance(self.deleted, dict):
                _dict['deleted'] = self.deleted
            else:
                _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'resource_type') and self.resource_type is not None:
            _dict['resource_type'] = self.resource_type
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstancePlacementTargetDedicatedHostReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstancePlacementTargetDedicatedHostReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstancePlacementTargetDedicatedHostReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        DEDICATED_HOST = 'dedicated_host'



class InstancePlacementTargetPlacementGroupReference(InstancePlacementTarget):
    """
    InstancePlacementTargetPlacementGroupReference.

    :attr str crn: The CRN for this placement group.
    :attr PlacementGroupReferenceDeleted deleted: (optional) If present, this
          property indicates the referenced resource has been deleted, and provides
          some supplementary information.
    :attr str href: The URL for this placement group.
    :attr str id: The unique identifier for this placement group.
    :attr str name: The name for this placement group. The name is unique across all
          placement groups in the region.
    :attr str resource_type: The resource type.
    """

    def __init__(
        self,
        crn: str,
        href: str,
        id: str,
        name: str,
        resource_type: str,
        *,
        deleted: 'PlacementGroupReferenceDeleted' = None,
    ) -> None:
        """
        Initialize a InstancePlacementTargetPlacementGroupReference object.

        :param str crn: The CRN for this placement group.
        :param str href: The URL for this placement group.
        :param str id: The unique identifier for this placement group.
        :param str name: The name for this placement group. The name is unique
               across all placement groups in the region.
        :param str resource_type: The resource type.
        :param PlacementGroupReferenceDeleted deleted: (optional) If present, this
               property indicates the referenced resource has been deleted, and provides
               some supplementary information.
        """
        # pylint: disable=super-init-not-called
        self.crn = crn
        self.deleted = deleted
        self.href = href
        self.id = id
        self.name = name
        self.resource_type = resource_type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstancePlacementTargetPlacementGroupReference':
        """Initialize a InstancePlacementTargetPlacementGroupReference object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError('Required property \'crn\' not present in InstancePlacementTargetPlacementGroupReference JSON')
        if 'deleted' in _dict:
            args['deleted'] = PlacementGroupReferenceDeleted.from_dict(_dict.get('deleted'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in InstancePlacementTargetPlacementGroupReference JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in InstancePlacementTargetPlacementGroupReference JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in InstancePlacementTargetPlacementGroupReference JSON')
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError('Required property \'resource_type\' not present in InstancePlacementTargetPlacementGroupReference JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstancePlacementTargetPlacementGroupReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'deleted') and self.deleted is not None:
            if isinstance(self.deleted, dict):
                _dict['deleted'] = self.deleted
            else:
                _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'resource_type') and self.resource_type is not None:
            _dict['resource_type'] = self.resource_type
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstancePlacementTargetPlacementGroupReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstancePlacementTargetPlacementGroupReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstancePlacementTargetPlacementGroupReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        PLACEMENT_GROUP = 'placement_group'



class InstanceProfileBandwidthDependent(InstanceProfileBandwidth):
    """
    The total bandwidth shared across the network interfaces and storage volumes of an
    instance with this profile depends on its configuration.

    :attr str type: The type for this profile field.
    """

    def __init__(
        self,
        type: str,
    ) -> None:
        """
        Initialize a InstanceProfileBandwidthDependent object.

        :param str type: The type for this profile field.
        """
        # pylint: disable=super-init-not-called
        self.type = type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceProfileBandwidthDependent':
        """Initialize a InstanceProfileBandwidthDependent object from a json dictionary."""
        args = {}
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in InstanceProfileBandwidthDependent JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceProfileBandwidthDependent object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'type') and self.type is not None:
            _dict['type'] = self.type
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceProfileBandwidthDependent object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceProfileBandwidthDependent') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceProfileBandwidthDependent') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class TypeEnum(str, Enum):
        """
        The type for this profile field.
        """

        DEPENDENT = 'dependent'



class InstanceProfileBandwidthEnum(InstanceProfileBandwidth):
    """
    The permitted total bandwidth values (in megabits per second) shared across the
    network interfaces and storage volumes of an instance with this profile.

    :attr int default: The default value for this profile field.
    :attr str type: The type for this profile field.
    :attr List[int] values: The permitted values for this profile field.
    """

    def __init__(
        self,
        default: int,
        type: str,
        values: List[int],
    ) -> None:
        """
        Initialize a InstanceProfileBandwidthEnum object.

        :param int default: The default value for this profile field.
        :param str type: The type for this profile field.
        :param List[int] values: The permitted values for this profile field.
        """
        # pylint: disable=super-init-not-called
        self.default = default
        self.type = type
        self.values = values

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceProfileBandwidthEnum':
        """Initialize a InstanceProfileBandwidthEnum object from a json dictionary."""
        args = {}
        if 'default' in _dict:
            args['default'] = _dict.get('default')
        else:
            raise ValueError('Required property \'default\' not present in InstanceProfileBandwidthEnum JSON')
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in InstanceProfileBandwidthEnum JSON')
        if 'values' in _dict:
            args['values'] = _dict.get('values')
        else:
            raise ValueError('Required property \'values\' not present in InstanceProfileBandwidthEnum JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceProfileBandwidthEnum object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'default') and self.default is not None:
            _dict['default'] = self.default
        if hasattr(self, 'type') and self.type is not None:
            _dict['type'] = self.type
        if hasattr(self, 'values') and self.values is not None:
            _dict['values'] = self.values
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceProfileBandwidthEnum object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceProfileBandwidthEnum') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceProfileBandwidthEnum') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class TypeEnum(str, Enum):
        """
        The type for this profile field.
        """

        ENUM = 'enum'



class InstanceProfileBandwidthFixed(InstanceProfileBandwidth):
    """
    The total bandwidth (in megabits per second) shared across the network interfaces and
    storage volumes of an instance with this profile.

    :attr str type: The type for this profile field.
    :attr int value: The value for this profile field.
    """

    def __init__(
        self,
        type: str,
        value: int,
    ) -> None:
        """
        Initialize a InstanceProfileBandwidthFixed object.

        :param str type: The type for this profile field.
        :param int value: The value for this profile field.
        """
        # pylint: disable=super-init-not-called
        self.type = type
        self.value = value

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceProfileBandwidthFixed':
        """Initialize a InstanceProfileBandwidthFixed object from a json dictionary."""
        args = {}
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in InstanceProfileBandwidthFixed JSON')
        if 'value' in _dict:
            args['value'] = _dict.get('value')
        else:
            raise ValueError('Required property \'value\' not present in InstanceProfileBandwidthFixed JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceProfileBandwidthFixed object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'type') and self.type is not None:
            _dict['type'] = self.type
        if hasattr(self, 'value') and self.value is not None:
            _dict['value'] = self.value
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceProfileBandwidthFixed object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceProfileBandwidthFixed') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceProfileBandwidthFixed') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class TypeEnum(str, Enum):
        """
        The type for this profile field.
        """

        FIXED = 'fixed'



class InstanceProfileBandwidthRange(InstanceProfileBandwidth):
    """
    The permitted total bandwidth range (in megabits per second) shared across the network
    interfaces and storage volumes of an instance with this profile.

    :attr int default: The default value for this profile field.
    :attr int max: The maximum value for this profile field.
    :attr int min: The minimum value for this profile field.
    :attr int step: The increment step value for this profile field.
    :attr str type: The type for this profile field.
    """

    def __init__(
        self,
        default: int,
        max: int,
        min: int,
        step: int,
        type: str,
    ) -> None:
        """
        Initialize a InstanceProfileBandwidthRange object.

        :param int default: The default value for this profile field.
        :param int max: The maximum value for this profile field.
        :param int min: The minimum value for this profile field.
        :param int step: The increment step value for this profile field.
        :param str type: The type for this profile field.
        """
        # pylint: disable=super-init-not-called
        self.default = default
        self.max = max
        self.min = min
        self.step = step
        self.type = type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceProfileBandwidthRange':
        """Initialize a InstanceProfileBandwidthRange object from a json dictionary."""
        args = {}
        if 'default' in _dict:
            args['default'] = _dict.get('default')
        else:
            raise ValueError('Required property \'default\' not present in InstanceProfileBandwidthRange JSON')
        if 'max' in _dict:
            args['max'] = _dict.get('max')
        else:
            raise ValueError('Required property \'max\' not present in InstanceProfileBandwidthRange JSON')
        if 'min' in _dict:
            args['min'] = _dict.get('min')
        else:
            raise ValueError('Required property \'min\' not present in InstanceProfileBandwidthRange JSON')
        if 'step' in _dict:
            args['step'] = _dict.get('step')
        else:
            raise ValueError('Required property \'step\' not present in InstanceProfileBandwidthRange JSON')
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in InstanceProfileBandwidthRange JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceProfileBandwidthRange object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'default') and self.default is not None:
            _dict['default'] = self.default
        if hasattr(self, 'max') and self.max is not None:
            _dict['max'] = self.max
        if hasattr(self, 'min') and self.min is not None:
            _dict['min'] = self.min
        if hasattr(self, 'step') and self.step is not None:
            _dict['step'] = self.step
        if hasattr(self, 'type') and self.type is not None:
            _dict['type'] = self.type
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceProfileBandwidthRange object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceProfileBandwidthRange') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceProfileBandwidthRange') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class TypeEnum(str, Enum):
        """
        The type for this profile field.
        """

        RANGE = 'range'



class InstanceProfileDiskQuantityDependent(InstanceProfileDiskQuantity):
    """
    The number of disks of this configuration for an instance with this profile depends on
    its instance configuration.

    :attr str type: The type for this profile field.
    """

    def __init__(
        self,
        type: str,
    ) -> None:
        """
        Initialize a InstanceProfileDiskQuantityDependent object.

        :param str type: The type for this profile field.
        """
        # pylint: disable=super-init-not-called
        self.type = type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceProfileDiskQuantityDependent':
        """Initialize a InstanceProfileDiskQuantityDependent object from a json dictionary."""
        args = {}
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in InstanceProfileDiskQuantityDependent JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceProfileDiskQuantityDependent object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'type') and self.type is not None:
            _dict['type'] = self.type
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceProfileDiskQuantityDependent object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceProfileDiskQuantityDependent') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceProfileDiskQuantityDependent') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class TypeEnum(str, Enum):
        """
        The type for this profile field.
        """

        DEPENDENT = 'dependent'



class InstanceProfileDiskQuantityEnum(InstanceProfileDiskQuantity):
    """
    The permitted the number of disks of this configuration for an instance with this
    profile.

    :attr int default: The default value for this profile field.
    :attr str type: The type for this profile field.
    :attr List[int] values: The permitted values for this profile field.
    """

    def __init__(
        self,
        default: int,
        type: str,
        values: List[int],
    ) -> None:
        """
        Initialize a InstanceProfileDiskQuantityEnum object.

        :param int default: The default value for this profile field.
        :param str type: The type for this profile field.
        :param List[int] values: The permitted values for this profile field.
        """
        # pylint: disable=super-init-not-called
        self.default = default
        self.type = type
        self.values = values

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceProfileDiskQuantityEnum':
        """Initialize a InstanceProfileDiskQuantityEnum object from a json dictionary."""
        args = {}
        if 'default' in _dict:
            args['default'] = _dict.get('default')
        else:
            raise ValueError('Required property \'default\' not present in InstanceProfileDiskQuantityEnum JSON')
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in InstanceProfileDiskQuantityEnum JSON')
        if 'values' in _dict:
            args['values'] = _dict.get('values')
        else:
            raise ValueError('Required property \'values\' not present in InstanceProfileDiskQuantityEnum JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceProfileDiskQuantityEnum object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'default') and self.default is not None:
            _dict['default'] = self.default
        if hasattr(self, 'type') and self.type is not None:
            _dict['type'] = self.type
        if hasattr(self, 'values') and self.values is not None:
            _dict['values'] = self.values
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceProfileDiskQuantityEnum object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceProfileDiskQuantityEnum') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceProfileDiskQuantityEnum') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class TypeEnum(str, Enum):
        """
        The type for this profile field.
        """

        ENUM = 'enum'



class InstanceProfileDiskQuantityFixed(InstanceProfileDiskQuantity):
    """
    The number of disks of this configuration for an instance with this profile.

    :attr str type: The type for this profile field.
    :attr int value: The value for this profile field.
    """

    def __init__(
        self,
        type: str,
        value: int,
    ) -> None:
        """
        Initialize a InstanceProfileDiskQuantityFixed object.

        :param str type: The type for this profile field.
        :param int value: The value for this profile field.
        """
        # pylint: disable=super-init-not-called
        self.type = type
        self.value = value

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceProfileDiskQuantityFixed':
        """Initialize a InstanceProfileDiskQuantityFixed object from a json dictionary."""
        args = {}
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in InstanceProfileDiskQuantityFixed JSON')
        if 'value' in _dict:
            args['value'] = _dict.get('value')
        else:
            raise ValueError('Required property \'value\' not present in InstanceProfileDiskQuantityFixed JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceProfileDiskQuantityFixed object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'type') and self.type is not None:
            _dict['type'] = self.type
        if hasattr(self, 'value') and self.value is not None:
            _dict['value'] = self.value
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceProfileDiskQuantityFixed object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceProfileDiskQuantityFixed') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceProfileDiskQuantityFixed') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class TypeEnum(str, Enum):
        """
        The type for this profile field.
        """

        FIXED = 'fixed'



class InstanceProfileDiskQuantityRange(InstanceProfileDiskQuantity):
    """
    The permitted range for the number of disks of this configuration for an instance with
    this profile.

    :attr int default: The default value for this profile field.
    :attr int max: The maximum value for this profile field.
    :attr int min: The minimum value for this profile field.
    :attr int step: The increment step value for this profile field.
    :attr str type: The type for this profile field.
    """

    def __init__(
        self,
        default: int,
        max: int,
        min: int,
        step: int,
        type: str,
    ) -> None:
        """
        Initialize a InstanceProfileDiskQuantityRange object.

        :param int default: The default value for this profile field.
        :param int max: The maximum value for this profile field.
        :param int min: The minimum value for this profile field.
        :param int step: The increment step value for this profile field.
        :param str type: The type for this profile field.
        """
        # pylint: disable=super-init-not-called
        self.default = default
        self.max = max
        self.min = min
        self.step = step
        self.type = type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceProfileDiskQuantityRange':
        """Initialize a InstanceProfileDiskQuantityRange object from a json dictionary."""
        args = {}
        if 'default' in _dict:
            args['default'] = _dict.get('default')
        else:
            raise ValueError('Required property \'default\' not present in InstanceProfileDiskQuantityRange JSON')
        if 'max' in _dict:
            args['max'] = _dict.get('max')
        else:
            raise ValueError('Required property \'max\' not present in InstanceProfileDiskQuantityRange JSON')
        if 'min' in _dict:
            args['min'] = _dict.get('min')
        else:
            raise ValueError('Required property \'min\' not present in InstanceProfileDiskQuantityRange JSON')
        if 'step' in _dict:
            args['step'] = _dict.get('step')
        else:
            raise ValueError('Required property \'step\' not present in InstanceProfileDiskQuantityRange JSON')
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in InstanceProfileDiskQuantityRange JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceProfileDiskQuantityRange object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'default') and self.default is not None:
            _dict['default'] = self.default
        if hasattr(self, 'max') and self.max is not None:
            _dict['max'] = self.max
        if hasattr(self, 'min') and self.min is not None:
            _dict['min'] = self.min
        if hasattr(self, 'step') and self.step is not None:
            _dict['step'] = self.step
        if hasattr(self, 'type') and self.type is not None:
            _dict['type'] = self.type
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceProfileDiskQuantityRange object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceProfileDiskQuantityRange') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceProfileDiskQuantityRange') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class TypeEnum(str, Enum):
        """
        The type for this profile field.
        """

        RANGE = 'range'



class InstanceProfileDiskSizeDependent(InstanceProfileDiskSize):
    """
    The disk size in GB (gigabytes) of this configuration for an instance with this
    profile depends on its instance configuration.

    :attr str type: The type for this profile field.
    """

    def __init__(
        self,
        type: str,
    ) -> None:
        """
        Initialize a InstanceProfileDiskSizeDependent object.

        :param str type: The type for this profile field.
        """
        # pylint: disable=super-init-not-called
        self.type = type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceProfileDiskSizeDependent':
        """Initialize a InstanceProfileDiskSizeDependent object from a json dictionary."""
        args = {}
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in InstanceProfileDiskSizeDependent JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceProfileDiskSizeDependent object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'type') and self.type is not None:
            _dict['type'] = self.type
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceProfileDiskSizeDependent object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceProfileDiskSizeDependent') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceProfileDiskSizeDependent') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class TypeEnum(str, Enum):
        """
        The type for this profile field.
        """

        DEPENDENT = 'dependent'



class InstanceProfileDiskSizeEnum(InstanceProfileDiskSize):
    """
    The permitted disk size in GB (gigabytes) of this configuration for an instance with
    this profile.

    :attr int default: The default value for this profile field.
    :attr str type: The type for this profile field.
    :attr List[int] values: The permitted values for this profile field.
    """

    def __init__(
        self,
        default: int,
        type: str,
        values: List[int],
    ) -> None:
        """
        Initialize a InstanceProfileDiskSizeEnum object.

        :param int default: The default value for this profile field.
        :param str type: The type for this profile field.
        :param List[int] values: The permitted values for this profile field.
        """
        # pylint: disable=super-init-not-called
        self.default = default
        self.type = type
        self.values = values

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceProfileDiskSizeEnum':
        """Initialize a InstanceProfileDiskSizeEnum object from a json dictionary."""
        args = {}
        if 'default' in _dict:
            args['default'] = _dict.get('default')
        else:
            raise ValueError('Required property \'default\' not present in InstanceProfileDiskSizeEnum JSON')
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in InstanceProfileDiskSizeEnum JSON')
        if 'values' in _dict:
            args['values'] = _dict.get('values')
        else:
            raise ValueError('Required property \'values\' not present in InstanceProfileDiskSizeEnum JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceProfileDiskSizeEnum object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'default') and self.default is not None:
            _dict['default'] = self.default
        if hasattr(self, 'type') and self.type is not None:
            _dict['type'] = self.type
        if hasattr(self, 'values') and self.values is not None:
            _dict['values'] = self.values
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceProfileDiskSizeEnum object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceProfileDiskSizeEnum') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceProfileDiskSizeEnum') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class TypeEnum(str, Enum):
        """
        The type for this profile field.
        """

        ENUM = 'enum'



class InstanceProfileDiskSizeFixed(InstanceProfileDiskSize):
    """
    The size of the disk in GB (gigabytes).

    :attr str type: The type for this profile field.
    :attr int value: The value for this profile field.
    """

    def __init__(
        self,
        type: str,
        value: int,
    ) -> None:
        """
        Initialize a InstanceProfileDiskSizeFixed object.

        :param str type: The type for this profile field.
        :param int value: The value for this profile field.
        """
        # pylint: disable=super-init-not-called
        self.type = type
        self.value = value

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceProfileDiskSizeFixed':
        """Initialize a InstanceProfileDiskSizeFixed object from a json dictionary."""
        args = {}
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in InstanceProfileDiskSizeFixed JSON')
        if 'value' in _dict:
            args['value'] = _dict.get('value')
        else:
            raise ValueError('Required property \'value\' not present in InstanceProfileDiskSizeFixed JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceProfileDiskSizeFixed object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'type') and self.type is not None:
            _dict['type'] = self.type
        if hasattr(self, 'value') and self.value is not None:
            _dict['value'] = self.value
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceProfileDiskSizeFixed object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceProfileDiskSizeFixed') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceProfileDiskSizeFixed') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class TypeEnum(str, Enum):
        """
        The type for this profile field.
        """

        FIXED = 'fixed'



class InstanceProfileDiskSizeRange(InstanceProfileDiskSize):
    """
    The permitted range for the disk size of this configuration in GB (gigabytes) for an
    instance with this profile.

    :attr int default: The default value for this profile field.
    :attr int max: The maximum value for this profile field.
    :attr int min: The minimum value for this profile field.
    :attr int step: The increment step value for this profile field.
    :attr str type: The type for this profile field.
    """

    def __init__(
        self,
        default: int,
        max: int,
        min: int,
        step: int,
        type: str,
    ) -> None:
        """
        Initialize a InstanceProfileDiskSizeRange object.

        :param int default: The default value for this profile field.
        :param int max: The maximum value for this profile field.
        :param int min: The minimum value for this profile field.
        :param int step: The increment step value for this profile field.
        :param str type: The type for this profile field.
        """
        # pylint: disable=super-init-not-called
        self.default = default
        self.max = max
        self.min = min
        self.step = step
        self.type = type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceProfileDiskSizeRange':
        """Initialize a InstanceProfileDiskSizeRange object from a json dictionary."""
        args = {}
        if 'default' in _dict:
            args['default'] = _dict.get('default')
        else:
            raise ValueError('Required property \'default\' not present in InstanceProfileDiskSizeRange JSON')
        if 'max' in _dict:
            args['max'] = _dict.get('max')
        else:
            raise ValueError('Required property \'max\' not present in InstanceProfileDiskSizeRange JSON')
        if 'min' in _dict:
            args['min'] = _dict.get('min')
        else:
            raise ValueError('Required property \'min\' not present in InstanceProfileDiskSizeRange JSON')
        if 'step' in _dict:
            args['step'] = _dict.get('step')
        else:
            raise ValueError('Required property \'step\' not present in InstanceProfileDiskSizeRange JSON')
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in InstanceProfileDiskSizeRange JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceProfileDiskSizeRange object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'default') and self.default is not None:
            _dict['default'] = self.default
        if hasattr(self, 'max') and self.max is not None:
            _dict['max'] = self.max
        if hasattr(self, 'min') and self.min is not None:
            _dict['min'] = self.min
        if hasattr(self, 'step') and self.step is not None:
            _dict['step'] = self.step
        if hasattr(self, 'type') and self.type is not None:
            _dict['type'] = self.type
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceProfileDiskSizeRange object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceProfileDiskSizeRange') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceProfileDiskSizeRange') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class TypeEnum(str, Enum):
        """
        The type for this profile field.
        """

        RANGE = 'range'



class InstanceProfileGPUDependent(InstanceProfileGPU):
    """
    The GPU count for an instance with this profile depends on its configuration.

    :attr str type: The type for this profile field.
    """

    def __init__(
        self,
        type: str,
    ) -> None:
        """
        Initialize a InstanceProfileGPUDependent 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) -> 'InstanceProfileGPUDependent':
        """Initialize a InstanceProfileGPUDependent object from a json dictionary."""
        args = {}
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in InstanceProfileGPUDependent JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceProfileGPUDependent object from 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 InstanceProfileGPUDependent object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceProfileGPUDependent') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceProfileGPUDependent') -> 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 InstanceProfileGPUEnum(InstanceProfileGPU):
    """
    The permitted GPU count values for an instance with this profile.

    :attr int default: The default value for this profile field.
    :attr str type: The type for this profile field.
    :attr List[int] values: The permitted values for this profile field.
    """

    def __init__(
        self,
        default: int,
        type: str,
        values: List[int],
    ) -> None:
        """
        Initialize a InstanceProfileGPUEnum 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) -> 'InstanceProfileGPUEnum':
        """Initialize a InstanceProfileGPUEnum object from a json dictionary."""
        args = {}
        if 'default' in _dict:
            args['default'] = _dict.get('default')
        else:
            raise ValueError('Required property \'default\' not present in InstanceProfileGPUEnum JSON')
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in InstanceProfileGPUEnum JSON')
        if 'values' in _dict:
            args['values'] = _dict.get('values')
        else:
            raise ValueError('Required property \'values\' not present in InstanceProfileGPUEnum JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceProfileGPUEnum object from 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 InstanceProfileGPUEnum object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceProfileGPUEnum') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceProfileGPUEnum') -> 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 InstanceProfileGPUFixed(InstanceProfileGPU):
    """
    The GPU count for an instance with this profile.

    :attr str type: The type for this profile field.
    :attr int value: The value for this profile field.
    """

    def __init__(
        self,
        type: str,
        value: int,
    ) -> None:
        """
        Initialize a InstanceProfileGPUFixed 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) -> 'InstanceProfileGPUFixed':
        """Initialize a InstanceProfileGPUFixed object from a json dictionary."""
        args = {}
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in InstanceProfileGPUFixed JSON')
        if 'value' in _dict:
            args['value'] = _dict.get('value')
        else:
            raise ValueError('Required property \'value\' not present in InstanceProfileGPUFixed JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceProfileGPUFixed object from 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 InstanceProfileGPUFixed object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceProfileGPUFixed') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceProfileGPUFixed') -> 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 InstanceProfileGPUMemoryDependent(InstanceProfileGPUMemory):
    """
    The overall GPU memory value for an instance with this profile depends on its
    configuration.

    :attr str type: The type for this profile field.
    """

    def __init__(
        self,
        type: str,
    ) -> None:
        """
        Initialize a InstanceProfileGPUMemoryDependent 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) -> 'InstanceProfileGPUMemoryDependent':
        """Initialize a InstanceProfileGPUMemoryDependent object from a json dictionary."""
        args = {}
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in InstanceProfileGPUMemoryDependent JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceProfileGPUMemoryDependent object from 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 InstanceProfileGPUMemoryDependent object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceProfileGPUMemoryDependent') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceProfileGPUMemoryDependent') -> 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 InstanceProfileGPUMemoryEnum(InstanceProfileGPUMemory):
    """
    The permitted overall GPU memory values in GiB (gibibytes) for an instance with this
    profile.

    :attr int default: The default value for this profile field.
    :attr str type: The type for this profile field.
    :attr List[int] values: The permitted values for this profile field.
    """

    def __init__(
        self,
        default: int,
        type: str,
        values: List[int],
    ) -> None:
        """
        Initialize a InstanceProfileGPUMemoryEnum 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) -> 'InstanceProfileGPUMemoryEnum':
        """Initialize a InstanceProfileGPUMemoryEnum object from a json dictionary."""
        args = {}
        if 'default' in _dict:
            args['default'] = _dict.get('default')
        else:
            raise ValueError('Required property \'default\' not present in InstanceProfileGPUMemoryEnum JSON')
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in InstanceProfileGPUMemoryEnum JSON')
        if 'values' in _dict:
            args['values'] = _dict.get('values')
        else:
            raise ValueError('Required property \'values\' not present in InstanceProfileGPUMemoryEnum JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceProfileGPUMemoryEnum object from 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 InstanceProfileGPUMemoryEnum object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceProfileGPUMemoryEnum') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceProfileGPUMemoryEnum') -> 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 InstanceProfileGPUMemoryFixed(InstanceProfileGPUMemory):
    """
    The overall GPU memory in GiB (gibibytes) for an instance with this profile.

    :attr str type: The type for this profile field.
    :attr int value: The value for this profile field.
    """

    def __init__(
        self,
        type: str,
        value: int,
    ) -> None:
        """
        Initialize a InstanceProfileGPUMemoryFixed 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) -> 'InstanceProfileGPUMemoryFixed':
        """Initialize a InstanceProfileGPUMemoryFixed object from a json dictionary."""
        args = {}
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in InstanceProfileGPUMemoryFixed JSON')
        if 'value' in _dict:
            args['value'] = _dict.get('value')
        else:
            raise ValueError('Required property \'value\' not present in InstanceProfileGPUMemoryFixed JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceProfileGPUMemoryFixed object from 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 InstanceProfileGPUMemoryFixed object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceProfileGPUMemoryFixed') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceProfileGPUMemoryFixed') -> 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 InstanceProfileGPUMemoryRange(InstanceProfileGPUMemory):
    """
    The permitted overall GPU memory range in GiB (gibibytes) for an instance with this
    profile.

    :attr int default: The default value for this profile field.
    :attr int max: The maximum value for this profile field.
    :attr int min: The minimum value for this profile field.
    :attr int step: The increment step value for this profile field.
    :attr str type: The type for this profile field.
    """

    def __init__(
        self,
        default: int,
        max: int,
        min: int,
        step: int,
        type: str,
    ) -> None:
        """
        Initialize a InstanceProfileGPUMemoryRange 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) -> 'InstanceProfileGPUMemoryRange':
        """Initialize a InstanceProfileGPUMemoryRange object from a json dictionary."""
        args = {}
        if 'default' in _dict:
            args['default'] = _dict.get('default')
        else:
            raise ValueError('Required property \'default\' not present in InstanceProfileGPUMemoryRange JSON')
        if 'max' in _dict:
            args['max'] = _dict.get('max')
        else:
            raise ValueError('Required property \'max\' not present in InstanceProfileGPUMemoryRange JSON')
        if 'min' in _dict:
            args['min'] = _dict.get('min')
        else:
            raise ValueError('Required property \'min\' not present in InstanceProfileGPUMemoryRange JSON')
        if 'step' in _dict:
            args['step'] = _dict.get('step')
        else:
            raise ValueError('Required property \'step\' not present in InstanceProfileGPUMemoryRange JSON')
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in InstanceProfileGPUMemoryRange JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceProfileGPUMemoryRange object from 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 InstanceProfileGPUMemoryRange object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceProfileGPUMemoryRange') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceProfileGPUMemoryRange') -> 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 InstanceProfileGPURange(InstanceProfileGPU):
    """
    The permitted GPU count range for an instance with this profile.

    :attr int default: The default value for this profile field.
    :attr int max: The maximum value for this profile field.
    :attr int min: The minimum value for this profile field.
    :attr int step: The increment step value for this profile field.
    :attr str type: The type for this profile field.
    """

    def __init__(
        self,
        default: int,
        max: int,
        min: int,
        step: int,
        type: str,
    ) -> None:
        """
        Initialize a InstanceProfileGPURange 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) -> 'InstanceProfileGPURange':
        """Initialize a InstanceProfileGPURange object from a json dictionary."""
        args = {}
        if 'default' in _dict:
            args['default'] = _dict.get('default')
        else:
            raise ValueError('Required property \'default\' not present in InstanceProfileGPURange JSON')
        if 'max' in _dict:
            args['max'] = _dict.get('max')
        else:
            raise ValueError('Required property \'max\' not present in InstanceProfileGPURange JSON')
        if 'min' in _dict:
            args['min'] = _dict.get('min')
        else:
            raise ValueError('Required property \'min\' not present in InstanceProfileGPURange JSON')
        if 'step' in _dict:
            args['step'] = _dict.get('step')
        else:
            raise ValueError('Required property \'step\' not present in InstanceProfileGPURange JSON')
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in InstanceProfileGPURange JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceProfileGPURange object from 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 InstanceProfileGPURange object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceProfileGPURange') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceProfileGPURange') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class TypeEnum(str, Enum):
        """
        The type for this profile field.
        """

        RANGE = 'range'



class InstanceProfileIdentityByHref(InstanceProfileIdentity):
    """
    InstanceProfileIdentityByHref.

    :attr str href: The URL for this virtual server instance profile.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a InstanceProfileIdentityByHref object.

        :param str href: The URL for this virtual server instance profile.
        """
        # pylint: disable=super-init-not-called
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceProfileIdentityByHref':
        """Initialize a InstanceProfileIdentityByHref object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in InstanceProfileIdentityByHref JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceProfileIdentityByHref object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceProfileIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceProfileIdentityByHref') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceProfileIdentityByHref') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceProfileIdentityByName(InstanceProfileIdentity):
    """
    InstanceProfileIdentityByName.

    :attr str name: The globally unique name for this virtual server instance
          profile.
    """

    def __init__(
        self,
        name: str,
    ) -> None:
        """
        Initialize a InstanceProfileIdentityByName object.

        :param str name: The globally unique name for this virtual server instance
               profile.
        """
        # pylint: disable=super-init-not-called
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceProfileIdentityByName':
        """Initialize a InstanceProfileIdentityByName object from a json dictionary."""
        args = {}
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in InstanceProfileIdentityByName JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceProfileIdentityByName object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceProfileIdentityByName object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceProfileIdentityByName') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceProfileIdentityByName') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceProfileMemoryDependent(InstanceProfileMemory):
    """
    The memory value for an instance with this profile depends on its configuration.

    :attr str type: The type for this profile field.
    """

    def __init__(
        self,
        type: str,
    ) -> None:
        """
        Initialize a InstanceProfileMemoryDependent object.

        :param str type: The type for this profile field.
        """
        # pylint: disable=super-init-not-called
        self.type = type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceProfileMemoryDependent':
        """Initialize a InstanceProfileMemoryDependent object from a json dictionary."""
        args = {}
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in InstanceProfileMemoryDependent JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceProfileMemoryDependent object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'type') and self.type is not None:
            _dict['type'] = self.type
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceProfileMemoryDependent object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceProfileMemoryDependent') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceProfileMemoryDependent') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class TypeEnum(str, Enum):
        """
        The type for this profile field.
        """

        DEPENDENT = 'dependent'



class InstanceProfileMemoryEnum(InstanceProfileMemory):
    """
    The permitted memory values (in gibibytes) for an instance with this profile.

    :attr int default: The default value for this profile field.
    :attr str type: The type for this profile field.
    :attr List[int] values: The permitted values for this profile field.
    """

    def __init__(
        self,
        default: int,
        type: str,
        values: List[int],
    ) -> None:
        """
        Initialize a InstanceProfileMemoryEnum object.

        :param int default: The default value for this profile field.
        :param str type: The type for this profile field.
        :param List[int] values: The permitted values for this profile field.
        """
        # pylint: disable=super-init-not-called
        self.default = default
        self.type = type
        self.values = values

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceProfileMemoryEnum':
        """Initialize a InstanceProfileMemoryEnum object from a json dictionary."""
        args = {}
        if 'default' in _dict:
            args['default'] = _dict.get('default')
        else:
            raise ValueError('Required property \'default\' not present in InstanceProfileMemoryEnum JSON')
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in InstanceProfileMemoryEnum JSON')
        if 'values' in _dict:
            args['values'] = _dict.get('values')
        else:
            raise ValueError('Required property \'values\' not present in InstanceProfileMemoryEnum JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceProfileMemoryEnum object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'default') and self.default is not None:
            _dict['default'] = self.default
        if hasattr(self, 'type') and self.type is not None:
            _dict['type'] = self.type
        if hasattr(self, 'values') and self.values is not None:
            _dict['values'] = self.values
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceProfileMemoryEnum object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceProfileMemoryEnum') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceProfileMemoryEnum') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class TypeEnum(str, Enum):
        """
        The type for this profile field.
        """

        ENUM = 'enum'



class InstanceProfileMemoryFixed(InstanceProfileMemory):
    """
    The memory (in gibibytes) for an instance with this profile.

    :attr str type: The type for this profile field.
    :attr int value: The value for this profile field.
    """

    def __init__(
        self,
        type: str,
        value: int,
    ) -> None:
        """
        Initialize a InstanceProfileMemoryFixed object.

        :param str type: The type for this profile field.
        :param int value: The value for this profile field.
        """
        # pylint: disable=super-init-not-called
        self.type = type
        self.value = value

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceProfileMemoryFixed':
        """Initialize a InstanceProfileMemoryFixed object from a json dictionary."""
        args = {}
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in InstanceProfileMemoryFixed JSON')
        if 'value' in _dict:
            args['value'] = _dict.get('value')
        else:
            raise ValueError('Required property \'value\' not present in InstanceProfileMemoryFixed JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceProfileMemoryFixed object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'type') and self.type is not None:
            _dict['type'] = self.type
        if hasattr(self, 'value') and self.value is not None:
            _dict['value'] = self.value
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceProfileMemoryFixed object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceProfileMemoryFixed') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceProfileMemoryFixed') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class TypeEnum(str, Enum):
        """
        The type for this profile field.
        """

        FIXED = 'fixed'



class InstanceProfileMemoryRange(InstanceProfileMemory):
    """
    The permitted memory range (in gibibytes) for an instance with this profile.

    :attr int default: The default value for this profile field.
    :attr int max: The maximum value for this profile field.
    :attr int min: The minimum value for this profile field.
    :attr int step: The increment step value for this profile field.
    :attr str type: The type for this profile field.
    """

    def __init__(
        self,
        default: int,
        max: int,
        min: int,
        step: int,
        type: str,
    ) -> None:
        """
        Initialize a InstanceProfileMemoryRange object.

        :param int default: The default value for this profile field.
        :param int max: The maximum value for this profile field.
        :param int min: The minimum value for this profile field.
        :param int step: The increment step value for this profile field.
        :param str type: The type for this profile field.
        """
        # pylint: disable=super-init-not-called
        self.default = default
        self.max = max
        self.min = min
        self.step = step
        self.type = type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceProfileMemoryRange':
        """Initialize a InstanceProfileMemoryRange object from a json dictionary."""
        args = {}
        if 'default' in _dict:
            args['default'] = _dict.get('default')
        else:
            raise ValueError('Required property \'default\' not present in InstanceProfileMemoryRange JSON')
        if 'max' in _dict:
            args['max'] = _dict.get('max')
        else:
            raise ValueError('Required property \'max\' not present in InstanceProfileMemoryRange JSON')
        if 'min' in _dict:
            args['min'] = _dict.get('min')
        else:
            raise ValueError('Required property \'min\' not present in InstanceProfileMemoryRange JSON')
        if 'step' in _dict:
            args['step'] = _dict.get('step')
        else:
            raise ValueError('Required property \'step\' not present in InstanceProfileMemoryRange JSON')
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in InstanceProfileMemoryRange JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceProfileMemoryRange object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'default') and self.default is not None:
            _dict['default'] = self.default
        if hasattr(self, 'max') and self.max is not None:
            _dict['max'] = self.max
        if hasattr(self, 'min') and self.min is not None:
            _dict['min'] = self.min
        if hasattr(self, 'step') and self.step is not None:
            _dict['step'] = self.step
        if hasattr(self, 'type') and self.type is not None:
            _dict['type'] = self.type
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceProfileMemoryRange object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceProfileMemoryRange') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceProfileMemoryRange') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class TypeEnum(str, Enum):
        """
        The type for this profile field.
        """

        RANGE = 'range'



class InstanceProfileNUMACountDependent(InstanceProfileNUMACount):
    """
    The total number of NUMA nodes for an instance with this profile depends on its
    configuration and the capacity constraints within the zone.

    :attr str type: The type for this profile field.
    """

    def __init__(
        self,
        type: str,
    ) -> None:
        """
        Initialize a InstanceProfileNUMACountDependent 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) -> 'InstanceProfileNUMACountDependent':
        """Initialize a InstanceProfileNUMACountDependent object from a json dictionary."""
        args = {}
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in InstanceProfileNUMACountDependent JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceProfileNUMACountDependent object from 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 InstanceProfileNUMACountDependent object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceProfileNUMACountDependent') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceProfileNUMACountDependent') -> 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 InstanceProfileNUMACountFixed(InstanceProfileNUMACount):
    """
    The total number of NUMA nodes for an instance with this profile.

    :attr str type: The type for this profile field.
    :attr int value: The value for this profile field.
    """

    def __init__(
        self,
        type: str,
        value: int,
    ) -> None:
        """
        Initialize a InstanceProfileNUMACountFixed 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) -> 'InstanceProfileNUMACountFixed':
        """Initialize a InstanceProfileNUMACountFixed object from a json dictionary."""
        args = {}
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in InstanceProfileNUMACountFixed JSON')
        if 'value' in _dict:
            args['value'] = _dict.get('value')
        else:
            raise ValueError('Required property \'value\' not present in InstanceProfileNUMACountFixed JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceProfileNUMACountFixed object from 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 InstanceProfileNUMACountFixed object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceProfileNUMACountFixed') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceProfileNUMACountFixed') -> 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 InstanceProfileNetworkInterfaceCountDependent(InstanceProfileNetworkInterfaceCount):
    """
    The number of network interfaces supported on an instance with this profile is
    dependent on its configuration.

    :attr str type: The type for this profile field.
    """

    def __init__(
        self,
        type: str,
    ) -> None:
        """
        Initialize a InstanceProfileNetworkInterfaceCountDependent 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) -> 'InstanceProfileNetworkInterfaceCountDependent':
        """Initialize a InstanceProfileNetworkInterfaceCountDependent object from a json dictionary."""
        args = {}
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in InstanceProfileNetworkInterfaceCountDependent JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceProfileNetworkInterfaceCountDependent object from 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 InstanceProfileNetworkInterfaceCountDependent object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceProfileNetworkInterfaceCountDependent') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceProfileNetworkInterfaceCountDependent') -> 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 InstanceProfileNetworkInterfaceCountRange(InstanceProfileNetworkInterfaceCount):
    """
    The number of network interfaces supported on an instance with this profile.

    :attr int max: (optional) The maximum value for this profile field.
    :attr int min: (optional) The minimum value for this profile field.
    :attr str type: The type for this profile field.
    """

    def __init__(
        self,
        type: str,
        *,
        max: int = None,
        min: int = None,
    ) -> None:
        """
        Initialize a InstanceProfileNetworkInterfaceCountRange object.

        :param str type: The type for this profile field.
        :param int max: (optional) The maximum value for this profile field.
        :param int min: (optional) The minimum value for this profile field.
        """
        # pylint: disable=super-init-not-called
        self.max = max
        self.min = min
        self.type = type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceProfileNetworkInterfaceCountRange':
        """Initialize a InstanceProfileNetworkInterfaceCountRange object from a json dictionary."""
        args = {}
        if 'max' in _dict:
            args['max'] = _dict.get('max')
        if 'min' in _dict:
            args['min'] = _dict.get('min')
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in InstanceProfileNetworkInterfaceCountRange JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceProfileNetworkInterfaceCountRange object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'max') 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, '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 InstanceProfileNetworkInterfaceCountRange object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceProfileNetworkInterfaceCountRange') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceProfileNetworkInterfaceCountRange') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class TypeEnum(str, Enum):
        """
        The type for this profile field.
        """

        RANGE = 'range'



class InstanceProfilePortSpeedDependent(InstanceProfilePortSpeed):
    """
    The port speed of each network interface of an instance with this profile depends on
    its configuration.

    :attr str type: The type for this profile field.
    """

    def __init__(
        self,
        type: str,
    ) -> None:
        """
        Initialize a InstanceProfilePortSpeedDependent object.

        :param str type: The type for this profile field.
        """
        # pylint: disable=super-init-not-called
        self.type = type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceProfilePortSpeedDependent':
        """Initialize a InstanceProfilePortSpeedDependent object from a json dictionary."""
        args = {}
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in InstanceProfilePortSpeedDependent JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceProfilePortSpeedDependent object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'type') and self.type is not None:
            _dict['type'] = self.type
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceProfilePortSpeedDependent object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceProfilePortSpeedDependent') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceProfilePortSpeedDependent') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class TypeEnum(str, Enum):
        """
        The type for this profile field.
        """

        DEPENDENT = 'dependent'



class InstanceProfilePortSpeedFixed(InstanceProfilePortSpeed):
    """
    The maximum speed (in megabits per second) of each network interface of an instance
    with this profile.

    :attr str type: The type for this profile field.
    :attr int value: The value for this profile field.
    """

    def __init__(
        self,
        type: str,
        value: int,
    ) -> None:
        """
        Initialize a InstanceProfilePortSpeedFixed object.

        :param str type: The type for this profile field.
        :param int value: The value for this profile field.
        """
        # pylint: disable=super-init-not-called
        self.type = type
        self.value = value

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceProfilePortSpeedFixed':
        """Initialize a InstanceProfilePortSpeedFixed object from a json dictionary."""
        args = {}
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in InstanceProfilePortSpeedFixed JSON')
        if 'value' in _dict:
            args['value'] = _dict.get('value')
        else:
            raise ValueError('Required property \'value\' not present in InstanceProfilePortSpeedFixed JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceProfilePortSpeedFixed object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'type') and self.type is not None:
            _dict['type'] = self.type
        if hasattr(self, 'value') and self.value is not None:
            _dict['value'] = self.value
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceProfilePortSpeedFixed object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceProfilePortSpeedFixed') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceProfilePortSpeedFixed') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class TypeEnum(str, Enum):
        """
        The type for this profile field.
        """

        FIXED = 'fixed'



class InstanceProfileVCPUDependent(InstanceProfileVCPU):
    """
    The VCPU count for an instance with this profile depends on its configuration.

    :attr str type: The type for this profile field.
    """

    def __init__(
        self,
        type: str,
    ) -> None:
        """
        Initialize a InstanceProfileVCPUDependent object.

        :param str type: The type for this profile field.
        """
        # pylint: disable=super-init-not-called
        self.type = type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceProfileVCPUDependent':
        """Initialize a InstanceProfileVCPUDependent object from a json dictionary."""
        args = {}
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in InstanceProfileVCPUDependent JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceProfileVCPUDependent object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'type') and self.type is not None:
            _dict['type'] = self.type
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceProfileVCPUDependent object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceProfileVCPUDependent') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceProfileVCPUDependent') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class TypeEnum(str, Enum):
        """
        The type for this profile field.
        """

        DEPENDENT = 'dependent'



class InstanceProfileVCPUEnum(InstanceProfileVCPU):
    """
    The permitted values for VCPU count for an instance with this profile.

    :attr int default: The default value for this profile field.
    :attr str type: The type for this profile field.
    :attr List[int] values: The permitted values for this profile field.
    """

    def __init__(
        self,
        default: int,
        type: str,
        values: List[int],
    ) -> None:
        """
        Initialize a InstanceProfileVCPUEnum object.

        :param int default: The default value for this profile field.
        :param str type: The type for this profile field.
        :param List[int] values: The permitted values for this profile field.
        """
        # pylint: disable=super-init-not-called
        self.default = default
        self.type = type
        self.values = values

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceProfileVCPUEnum':
        """Initialize a InstanceProfileVCPUEnum object from a json dictionary."""
        args = {}
        if 'default' in _dict:
            args['default'] = _dict.get('default')
        else:
            raise ValueError('Required property \'default\' not present in InstanceProfileVCPUEnum JSON')
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in InstanceProfileVCPUEnum JSON')
        if 'values' in _dict:
            args['values'] = _dict.get('values')
        else:
            raise ValueError('Required property \'values\' not present in InstanceProfileVCPUEnum JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceProfileVCPUEnum object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'default') and self.default is not None:
            _dict['default'] = self.default
        if hasattr(self, 'type') and self.type is not None:
            _dict['type'] = self.type
        if hasattr(self, 'values') and self.values is not None:
            _dict['values'] = self.values
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceProfileVCPUEnum object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceProfileVCPUEnum') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceProfileVCPUEnum') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class TypeEnum(str, Enum):
        """
        The type for this profile field.
        """

        ENUM = 'enum'



class InstanceProfileVCPUFixed(InstanceProfileVCPU):
    """
    The VCPU count for an instance with this profile.

    :attr str type: The type for this profile field.
    :attr int value: The value for this profile field.
    """

    def __init__(
        self,
        type: str,
        value: int,
    ) -> None:
        """
        Initialize a InstanceProfileVCPUFixed object.

        :param str type: The type for this profile field.
        :param int value: The value for this profile field.
        """
        # pylint: disable=super-init-not-called
        self.type = type
        self.value = value

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceProfileVCPUFixed':
        """Initialize a InstanceProfileVCPUFixed object from a json dictionary."""
        args = {}
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in InstanceProfileVCPUFixed JSON')
        if 'value' in _dict:
            args['value'] = _dict.get('value')
        else:
            raise ValueError('Required property \'value\' not present in InstanceProfileVCPUFixed JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceProfileVCPUFixed object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'type') and self.type is not None:
            _dict['type'] = self.type
        if hasattr(self, 'value') and self.value is not None:
            _dict['value'] = self.value
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceProfileVCPUFixed object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceProfileVCPUFixed') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceProfileVCPUFixed') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class TypeEnum(str, Enum):
        """
        The type for this profile field.
        """

        FIXED = 'fixed'



class InstanceProfileVCPURange(InstanceProfileVCPU):
    """
    The permitted range for VCPU count for an instance with this profile.

    :attr int default: The default value for this profile field.
    :attr int max: The maximum value for this profile field.
    :attr int min: The minimum value for this profile field.
    :attr int step: The increment step value for this profile field.
    :attr str type: The type for this profile field.
    """

    def __init__(
        self,
        default: int,
        max: int,
        min: int,
        step: int,
        type: str,
    ) -> None:
        """
        Initialize a InstanceProfileVCPURange object.

        :param int default: The default value for this profile field.
        :param int max: The maximum value for this profile field.
        :param int min: The minimum value for this profile field.
        :param int step: The increment step value for this profile field.
        :param str type: The type for this profile field.
        """
        # pylint: disable=super-init-not-called
        self.default = default
        self.max = max
        self.min = min
        self.step = step
        self.type = type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceProfileVCPURange':
        """Initialize a InstanceProfileVCPURange object from a json dictionary."""
        args = {}
        if 'default' in _dict:
            args['default'] = _dict.get('default')
        else:
            raise ValueError('Required property \'default\' not present in InstanceProfileVCPURange JSON')
        if 'max' in _dict:
            args['max'] = _dict.get('max')
        else:
            raise ValueError('Required property \'max\' not present in InstanceProfileVCPURange JSON')
        if 'min' in _dict:
            args['min'] = _dict.get('min')
        else:
            raise ValueError('Required property \'min\' not present in InstanceProfileVCPURange JSON')
        if 'step' in _dict:
            args['step'] = _dict.get('step')
        else:
            raise ValueError('Required property \'step\' not present in InstanceProfileVCPURange JSON')
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in InstanceProfileVCPURange JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceProfileVCPURange object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'default') and self.default is not None:
            _dict['default'] = self.default
        if hasattr(self, 'max') and self.max is not None:
            _dict['max'] = self.max
        if hasattr(self, 'min') and self.min is not None:
            _dict['min'] = self.min
        if hasattr(self, 'step') and self.step is not None:
            _dict['step'] = self.step
        if hasattr(self, 'type') and self.type is not None:
            _dict['type'] = self.type
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceProfileVCPURange object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceProfileVCPURange') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceProfileVCPURange') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class TypeEnum(str, Enum):
        """
        The type for this profile field.
        """

        RANGE = 'range'



class InstanceProfileVolumeBandwidthDependent(InstanceProfileVolumeBandwidth):
    """
    The storage bandwidth shared across the storage volumes of an instance with this
    profile depends on its configuration.

    :attr str type: The type for this profile field.
    """

    def __init__(
        self,
        type: str,
    ) -> None:
        """
        Initialize a InstanceProfileVolumeBandwidthDependent 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) -> 'InstanceProfileVolumeBandwidthDependent':
        """Initialize a InstanceProfileVolumeBandwidthDependent object from a json dictionary."""
        args = {}
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in InstanceProfileVolumeBandwidthDependent JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceProfileVolumeBandwidthDependent object from 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 InstanceProfileVolumeBandwidthDependent object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceProfileVolumeBandwidthDependent') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceProfileVolumeBandwidthDependent') -> 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 InstanceProfileVolumeBandwidthEnum(InstanceProfileVolumeBandwidth):
    """
    The permitted storage bandwidth values (in megabits per second) shared across the
    storage volumes 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 InstanceProfileVolumeBandwidthEnum 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) -> 'InstanceProfileVolumeBandwidthEnum':
        """Initialize a InstanceProfileVolumeBandwidthEnum object from a json dictionary."""
        args = {}
        if 'default' in _dict:
            args['default'] = _dict.get('default')
        else:
            raise ValueError('Required property \'default\' not present in InstanceProfileVolumeBandwidthEnum JSON')
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in InstanceProfileVolumeBandwidthEnum JSON')
        if 'values' in _dict:
            args['values'] = _dict.get('values')
        else:
            raise ValueError('Required property \'values\' not present in InstanceProfileVolumeBandwidthEnum JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceProfileVolumeBandwidthEnum object from 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 InstanceProfileVolumeBandwidthEnum object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceProfileVolumeBandwidthEnum') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceProfileVolumeBandwidthEnum') -> 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 InstanceProfileVolumeBandwidthFixed(InstanceProfileVolumeBandwidth):
    """
    The storage bandwidth (in megabits per second) shared across the storage volumes of an
    instance with this profile.

    :attr str type: The type for this profile field.
    :attr int value: The value for this profile field.
    """

    def __init__(
        self,
        type: str,
        value: int,
    ) -> None:
        """
        Initialize a InstanceProfileVolumeBandwidthFixed 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) -> 'InstanceProfileVolumeBandwidthFixed':
        """Initialize a InstanceProfileVolumeBandwidthFixed object from a json dictionary."""
        args = {}
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in InstanceProfileVolumeBandwidthFixed JSON')
        if 'value' in _dict:
            args['value'] = _dict.get('value')
        else:
            raise ValueError('Required property \'value\' not present in InstanceProfileVolumeBandwidthFixed JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceProfileVolumeBandwidthFixed object from 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 InstanceProfileVolumeBandwidthFixed object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceProfileVolumeBandwidthFixed') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceProfileVolumeBandwidthFixed') -> 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 InstanceProfileVolumeBandwidthRange(InstanceProfileVolumeBandwidth):
    """
    The permitted storage bandwidth range (in megabits per second) shared across the
    storage volumes of an instance with this profile.

    :attr int default: The default value for this profile field.
    :attr int max: The maximum value for this profile field.
    :attr int min: The minimum value for this profile field.
    :attr int step: The increment step value for this profile field.
    :attr str type: The type for this profile field.
    """

    def __init__(
        self,
        default: int,
        max: int,
        min: int,
        step: int,
        type: str,
    ) -> None:
        """
        Initialize a InstanceProfileVolumeBandwidthRange 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) -> 'InstanceProfileVolumeBandwidthRange':
        """Initialize a InstanceProfileVolumeBandwidthRange object from a json dictionary."""
        args = {}
        if 'default' in _dict:
            args['default'] = _dict.get('default')
        else:
            raise ValueError('Required property \'default\' not present in InstanceProfileVolumeBandwidthRange JSON')
        if 'max' in _dict:
            args['max'] = _dict.get('max')
        else:
            raise ValueError('Required property \'max\' not present in InstanceProfileVolumeBandwidthRange JSON')
        if 'min' in _dict:
            args['min'] = _dict.get('min')
        else:
            raise ValueError('Required property \'min\' not present in InstanceProfileVolumeBandwidthRange JSON')
        if 'step' in _dict:
            args['step'] = _dict.get('step')
        else:
            raise ValueError('Required property \'step\' not present in InstanceProfileVolumeBandwidthRange JSON')
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in InstanceProfileVolumeBandwidthRange JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceProfileVolumeBandwidthRange object from 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 InstanceProfileVolumeBandwidthRange object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceProfileVolumeBandwidthRange') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceProfileVolumeBandwidthRange') -> 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 InstancePrototypeInstanceByCatalogOffering(InstancePrototype):
    """
    Create an instance by using a catalog offering.

    :attr InstanceAvailabilityPolicyPrototype availability_policy: (optional) The
          availability policy to use for this virtual server instance.
    :attr InstanceDefaultTrustedProfilePrototype default_trusted_profile: (optional)
          The default trusted profile configuration to use for this virtual server
          instance
          This property's value is used when provisioning the virtual server instance, but
          not subsequently managed. Accordingly, it is reflected as an [instance
          initialization](https://cloud.ibm.com/apidocs/vpc#get-instance-initialization)
          property.
    :attr List[KeyIdentity] keys: (optional) The public SSH keys for the
          administrative user of the virtual server instance. 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.
          For Windows images, the keys of type `rsa` must be specified, and one will be
          selected to encrypt [the administrator
          password](https://cloud.ibm.com/apidocs/vpc#get-instance-initialization). Keys
          are optional for other images, but if no keys are specified, the instance will
          be inaccessible unless the specified image provides another means of access.
          This property's value is used when provisioning the virtual server instance, but
          not subsequently managed. Accordingly, it is reflected as an [instance
          initialization](https://cloud.ibm.com/apidocs/vpc#get-instance-initialization)
          property.
    :attr InstanceMetadataServicePrototype metadata_service: (optional)
    :attr str name: (optional) The name for this virtual server instance. The name
          must not be used by another virtual server instance in the region. If
          unspecified, the name will be a hyphenated list of randomly-selected words.
          The system hostname will be based on this name.
    :attr InstancePlacementTargetPrototype placement_target: (optional) The
          placement restrictions to use for the virtual server instance.
    :attr InstanceProfileIdentity profile: (optional) The
          [profile](https://cloud.ibm.com/docs/vpc?topic=vpc-profiles) to use for this
          virtual server instance.
          If unspecified, `bx2-2x8` will be used, but this default value is expected to
          change in the future.
    :attr ResourceGroupIdentity resource_group: (optional)
    :attr int total_volume_bandwidth: (optional) The amount of bandwidth (in
          megabits per second) allocated exclusively to instance storage volumes. An
          increase in this value will result in a corresponding decrease to
          `total_network_bandwidth`.
    :attr str user_data: (optional) [User
          data](https://cloud.ibm.com/docs/vpc?topic=vpc-user-data) to make available when
          setting up the virtual server instance.
    :attr List[VolumeAttachmentPrototype] volume_attachments: (optional) The
          additional volume attachments to create for the virtual server instance.
    :attr VPCIdentity vpc: (optional) The VPC this virtual server instance will
          reside in.
          If specified, it must match the VPC for the subnets of the instance network
          interfaces.
    :attr VolumeAttachmentPrototypeInstanceByImageContext boot_volume_attachment:
          (optional) The boot volume attachment to create for the virtual server instance.
    :attr InstanceCatalogOfferingPrototype catalog_offering: The
          [catalog](https://cloud.ibm.com/docs/account?topic=account-restrict-by-user)
          offering
          or offering version to use when provisioning this virtual server instance.
          If an offering is specified, the latest version of that offering will be used.
          The specified offering or offering version may be in a different account in the
          same
          [enterprise](https://cloud.ibm.com/docs/account?topic=account-what-is-enterprise),
          subject
          to IAM policies.
    :attr List[NetworkInterfacePrototype] network_interfaces: (optional) The
          additional instance network interfaces to create.
    :attr NetworkInterfacePrototype primary_network_interface: The primary instance
          network interface to create.
    :attr ZoneIdentity zone: The zone this virtual server instance will reside in.
    """

    def __init__(
        self,
        catalog_offering: 'InstanceCatalogOfferingPrototype',
        primary_network_interface: 'NetworkInterfacePrototype',
        zone: 'ZoneIdentity',
        *,
        availability_policy: 'InstanceAvailabilityPolicyPrototype' = None,
        default_trusted_profile: 'InstanceDefaultTrustedProfilePrototype' = None,
        keys: List['KeyIdentity'] = None,
        metadata_service: 'InstanceMetadataServicePrototype' = None,
        name: str = None,
        placement_target: 'InstancePlacementTargetPrototype' = None,
        profile: 'InstanceProfileIdentity' = None,
        resource_group: 'ResourceGroupIdentity' = None,
        total_volume_bandwidth: int = None,
        user_data: str = None,
        volume_attachments: List['VolumeAttachmentPrototype'] = None,
        vpc: 'VPCIdentity' = None,
        boot_volume_attachment: 'VolumeAttachmentPrototypeInstanceByImageContext' = None,
        network_interfaces: List['NetworkInterfacePrototype'] = None,
    ) -> None:
        """
        Initialize a InstancePrototypeInstanceByCatalogOffering object.

        :param InstanceCatalogOfferingPrototype catalog_offering: The
               [catalog](https://cloud.ibm.com/docs/account?topic=account-restrict-by-user)
               offering
               or offering version to use when provisioning this virtual server instance.
               If an offering is specified, the latest version of that offering will be
               used.
               The specified offering or offering version may be in a different account in
               the same
               [enterprise](https://cloud.ibm.com/docs/account?topic=account-what-is-enterprise),
               subject
               to IAM policies.
        :param NetworkInterfacePrototype primary_network_interface: The primary
               instance network interface to create.
        :param ZoneIdentity zone: The zone this virtual server instance will reside
               in.
        :param InstanceAvailabilityPolicyPrototype availability_policy: (optional)
               The availability policy to use for this virtual server instance.
        :param InstanceDefaultTrustedProfilePrototype default_trusted_profile:
               (optional) The default trusted profile configuration to use for this
               virtual server instance
               This property's value is used when provisioning the virtual server
               instance, but not subsequently managed. Accordingly, it is reflected as an
               [instance
               initialization](https://cloud.ibm.com/apidocs/vpc#get-instance-initialization)
               property.
        :param List[KeyIdentity] keys: (optional) The public SSH keys for the
               administrative user of the virtual server instance. 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.
               For Windows images, the keys of type `rsa` must be specified, and one will
               be selected to encrypt [the administrator
               password](https://cloud.ibm.com/apidocs/vpc#get-instance-initialization).
               Keys are optional for other images, but if no keys are specified, the
               instance will be inaccessible unless the specified image provides another
               means of access.
               This property's value is used when provisioning the virtual server
               instance, but not subsequently managed. Accordingly, it is reflected as an
               [instance
               initialization](https://cloud.ibm.com/apidocs/vpc#get-instance-initialization)
               property.
        :param InstanceMetadataServicePrototype metadata_service: (optional)
        :param str name: (optional) The name for this virtual server instance. The
               name must not be used by another virtual server instance in the region. If
               unspecified, the name will be a hyphenated list of randomly-selected words.
               The system hostname will be based on this name.
        :param InstancePlacementTargetPrototype placement_target: (optional) The
               placement restrictions to use for the virtual server instance.
        :param InstanceProfileIdentity profile: (optional) The
               [profile](https://cloud.ibm.com/docs/vpc?topic=vpc-profiles) to use for
               this virtual server instance.
               If unspecified, `bx2-2x8` will be used, but this default value is expected
               to change in the future.
        :param ResourceGroupIdentity resource_group: (optional)
        :param int total_volume_bandwidth: (optional) The amount of bandwidth (in
               megabits per second) allocated exclusively to instance storage volumes. An
               increase in this value will result in a corresponding decrease to
               `total_network_bandwidth`.
        :param str user_data: (optional) [User
               data](https://cloud.ibm.com/docs/vpc?topic=vpc-user-data) to make available
               when setting up the virtual server instance.
        :param List[VolumeAttachmentPrototype] volume_attachments: (optional) The
               additional volume attachments to create for the virtual server instance.
        :param VPCIdentity vpc: (optional) The VPC this virtual server instance
               will reside in.
               If specified, it must match the VPC for the subnets of the instance network
               interfaces.
        :param VolumeAttachmentPrototypeInstanceByImageContext
               boot_volume_attachment: (optional) The boot volume attachment to create for
               the virtual server instance.
        :param List[NetworkInterfacePrototype] network_interfaces: (optional) The
               additional instance network interfaces to create.
        """
        # pylint: disable=super-init-not-called
        self.availability_policy = availability_policy
        self.default_trusted_profile = default_trusted_profile
        self.keys = keys
        self.metadata_service = metadata_service
        self.name = name
        self.placement_target = placement_target
        self.profile = profile
        self.resource_group = resource_group
        self.total_volume_bandwidth = total_volume_bandwidth
        self.user_data = user_data
        self.volume_attachments = volume_attachments
        self.vpc = vpc
        self.boot_volume_attachment = boot_volume_attachment
        self.catalog_offering = catalog_offering
        self.network_interfaces = network_interfaces
        self.primary_network_interface = primary_network_interface
        self.zone = zone

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstancePrototypeInstanceByCatalogOffering':
        """Initialize a InstancePrototypeInstanceByCatalogOffering object from a json dictionary."""
        args = {}
        if 'availability_policy' in _dict:
            args['availability_policy'] = InstanceAvailabilityPolicyPrototype.from_dict(_dict.get('availability_policy'))
        if 'default_trusted_profile' in _dict:
            args['default_trusted_profile'] = InstanceDefaultTrustedProfilePrototype.from_dict(_dict.get('default_trusted_profile'))
        if 'keys' in _dict:
            args['keys'] = _dict.get('keys')
        if 'metadata_service' in _dict:
            args['metadata_service'] = InstanceMetadataServicePrototype.from_dict(_dict.get('metadata_service'))
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        if 'placement_target' in _dict:
            args['placement_target'] = _dict.get('placement_target')
        if 'profile' in _dict:
            args['profile'] = _dict.get('profile')
        if 'resource_group' in _dict:
            args['resource_group'] = _dict.get('resource_group')
        if 'total_volume_bandwidth' in _dict:
            args['total_volume_bandwidth'] = _dict.get('total_volume_bandwidth')
        if 'user_data' in _dict:
            args['user_data'] = _dict.get('user_data')
        if 'volume_attachments' in _dict:
            args['volume_attachments'] = [VolumeAttachmentPrototype.from_dict(v) for v 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 'catalog_offering' in _dict:
            args['catalog_offering'] = _dict.get('catalog_offering')
        else:
            raise ValueError('Required property \'catalog_offering\' not present in InstancePrototypeInstanceByCatalogOffering JSON')
        if 'network_interfaces' in _dict:
            args['network_interfaces'] = [NetworkInterfacePrototype.from_dict(v) for v in _dict.get('network_interfaces')]
        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 InstancePrototypeInstanceByCatalogOffering JSON')
        if 'zone' in _dict:
            args['zone'] = _dict.get('zone')
        else:
            raise ValueError('Required property \'zone\' not present in InstancePrototypeInstanceByCatalogOffering JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstancePrototypeInstanceByCatalogOffering object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'availability_policy') and self.availability_policy is not None:
            if isinstance(self.availability_policy, dict):
                _dict['availability_policy'] = self.availability_policy
            else:
                _dict['availability_policy'] = self.availability_policy.to_dict()
        if hasattr(self, 'default_trusted_profile') and self.default_trusted_profile is not None:
            if isinstance(self.default_trusted_profile, dict):
                _dict['default_trusted_profile'] = self.default_trusted_profile
            else:
                _dict['default_trusted_profile'] = self.default_trusted_profile.to_dict()
        if hasattr(self, 'keys') and self.keys is not None:
            keys_list = []
            for v in self.keys:
                if isinstance(v, dict):
                    keys_list.append(v)
                else:
                    keys_list.append(v.to_dict())
            _dict['keys'] = keys_list
        if hasattr(self, 'metadata_service') and self.metadata_service is not None:
            if isinstance(self.metadata_service, dict):
                _dict['metadata_service'] = self.metadata_service
            else:
                _dict['metadata_service'] = self.metadata_service.to_dict()
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'placement_target') and self.placement_target is not None:
            if isinstance(self.placement_target, dict):
                _dict['placement_target'] = self.placement_target
            else:
                _dict['placement_target'] = self.placement_target.to_dict()
        if hasattr(self, 'profile') and self.profile is not None:
            if isinstance(self.profile, dict):
                _dict['profile'] = self.profile
            else:
                _dict['profile'] = self.profile.to_dict()
        if hasattr(self, 'resource_group') and self.resource_group is not None:
            if isinstance(self.resource_group, dict):
                _dict['resource_group'] = self.resource_group
            else:
                _dict['resource_group'] = self.resource_group.to_dict()
        if hasattr(self, 'total_volume_bandwidth') and self.total_volume_bandwidth is not None:
            _dict['total_volume_bandwidth'] = self.total_volume_bandwidth
        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:
            volume_attachments_list = []
            for v in self.volume_attachments:
                if isinstance(v, dict):
                    volume_attachments_list.append(v)
                else:
                    volume_attachments_list.append(v.to_dict())
            _dict['volume_attachments'] = volume_attachments_list
        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:
            if isinstance(self.boot_volume_attachment, dict):
                _dict['boot_volume_attachment'] = self.boot_volume_attachment
            else:
                _dict['boot_volume_attachment'] = self.boot_volume_attachment.to_dict()
        if hasattr(self, 'catalog_offering') and self.catalog_offering is not None:
            if isinstance(self.catalog_offering, dict):
                _dict['catalog_offering'] = self.catalog_offering
            else:
                _dict['catalog_offering'] = self.catalog_offering.to_dict()
        if hasattr(self, 'network_interfaces') and self.network_interfaces is not None:
            network_interfaces_list = []
            for v in self.network_interfaces:
                if isinstance(v, dict):
                    network_interfaces_list.append(v)
                else:
                    network_interfaces_list.append(v.to_dict())
            _dict['network_interfaces'] = network_interfaces_list
        if hasattr(self, 'primary_network_interface') and self.primary_network_interface is not None:
            if isinstance(self.primary_network_interface, dict):
                _dict['primary_network_interface'] = self.primary_network_interface
            else:
                _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 InstancePrototypeInstanceByCatalogOffering object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstancePrototypeInstanceByCatalogOffering') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstancePrototypeInstanceByCatalogOffering') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstancePrototypeInstanceByImage(InstancePrototype):
    """
    Create an instance by using an image.

    :attr InstanceAvailabilityPolicyPrototype availability_policy: (optional) The
          availability policy to use for this virtual server instance.
    :attr InstanceDefaultTrustedProfilePrototype default_trusted_profile: (optional)
          The default trusted profile configuration to use for this virtual server
          instance
          This property's value is used when provisioning the virtual server instance, but
          not subsequently managed. Accordingly, it is reflected as an [instance
          initialization](https://cloud.ibm.com/apidocs/vpc#get-instance-initialization)
          property.
    :attr List[KeyIdentity] keys: (optional) The public SSH keys for the
          administrative user of the virtual server instance. 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.
          For Windows images, the keys of type `rsa` must be specified, and one will be
          selected to encrypt [the administrator
          password](https://cloud.ibm.com/apidocs/vpc#get-instance-initialization). Keys
          are optional for other images, but if no keys are specified, the instance will
          be inaccessible unless the specified image provides another means of access.
          This property's value is used when provisioning the virtual server instance, but
          not subsequently managed. Accordingly, it is reflected as an [instance
          initialization](https://cloud.ibm.com/apidocs/vpc#get-instance-initialization)
          property.
    :attr InstanceMetadataServicePrototype metadata_service: (optional)
    :attr str name: (optional) The name for this virtual server instance. The name
          must not be used by another virtual server instance in the region. If
          unspecified, the name will be a hyphenated list of randomly-selected words.
          The system hostname will be based on this name.
    :attr InstancePlacementTargetPrototype placement_target: (optional) The
          placement restrictions to use for the virtual server instance.
    :attr InstanceProfileIdentity profile: (optional) The
          [profile](https://cloud.ibm.com/docs/vpc?topic=vpc-profiles) to use for this
          virtual server instance.
          If unspecified, `bx2-2x8` will be used, but this default value is expected to
          change in the future.
    :attr ResourceGroupIdentity resource_group: (optional)
    :attr int total_volume_bandwidth: (optional) The amount of bandwidth (in
          megabits per second) allocated exclusively to instance storage volumes. An
          increase in this value will result in a corresponding decrease to
          `total_network_bandwidth`.
    :attr str user_data: (optional) [User
          data](https://cloud.ibm.com/docs/vpc?topic=vpc-user-data) to make available when
          setting up the virtual server instance.
    :attr List[VolumeAttachmentPrototype] volume_attachments: (optional) The
          additional volume attachments to create for the virtual server instance.
    :attr VPCIdentity vpc: (optional) The VPC this virtual server instance will
          reside in.
          If specified, it must match the VPC for the subnets of the instance network
          interfaces.
    :attr VolumeAttachmentPrototypeInstanceByImageContext boot_volume_attachment:
          (optional) The boot volume attachment to create for the virtual server instance.
    :attr ImageIdentity image: The image to use when provisioning the virtual server
          instance.
    :attr List[NetworkInterfacePrototype] network_interfaces: (optional) The
          additional instance network interfaces to create.
    :attr NetworkInterfacePrototype primary_network_interface: The primary instance
          network interface to create.
    :attr ZoneIdentity zone: The zone this virtual server instance will reside in.
    """

    def __init__(
        self,
        image: 'ImageIdentity',
        primary_network_interface: 'NetworkInterfacePrototype',
        zone: 'ZoneIdentity',
        *,
        availability_policy: 'InstanceAvailabilityPolicyPrototype' = None,
        default_trusted_profile: 'InstanceDefaultTrustedProfilePrototype' = None,
        keys: List['KeyIdentity'] = None,
        metadata_service: 'InstanceMetadataServicePrototype' = None,
        name: str = None,
        placement_target: 'InstancePlacementTargetPrototype' = None,
        profile: 'InstanceProfileIdentity' = None,
        resource_group: 'ResourceGroupIdentity' = None,
        total_volume_bandwidth: int = None,
        user_data: str = None,
        volume_attachments: List['VolumeAttachmentPrototype'] = None,
        vpc: 'VPCIdentity' = None,
        boot_volume_attachment: 'VolumeAttachmentPrototypeInstanceByImageContext' = None,
        network_interfaces: List['NetworkInterfacePrototype'] = None,
    ) -> None:
        """
        Initialize a InstancePrototypeInstanceByImage object.

        :param ImageIdentity image: The image to use when provisioning the virtual
               server instance.
        :param NetworkInterfacePrototype primary_network_interface: The primary
               instance network interface to create.
        :param ZoneIdentity zone: The zone this virtual server instance will reside
               in.
        :param InstanceAvailabilityPolicyPrototype availability_policy: (optional)
               The availability policy to use for this virtual server instance.
        :param InstanceDefaultTrustedProfilePrototype default_trusted_profile:
               (optional) The default trusted profile configuration to use for this
               virtual server instance
               This property's value is used when provisioning the virtual server
               instance, but not subsequently managed. Accordingly, it is reflected as an
               [instance
               initialization](https://cloud.ibm.com/apidocs/vpc#get-instance-initialization)
               property.
        :param List[KeyIdentity] keys: (optional) The public SSH keys for the
               administrative user of the virtual server instance. 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.
               For Windows images, the keys of type `rsa` must be specified, and one will
               be selected to encrypt [the administrator
               password](https://cloud.ibm.com/apidocs/vpc#get-instance-initialization).
               Keys are optional for other images, but if no keys are specified, the
               instance will be inaccessible unless the specified image provides another
               means of access.
               This property's value is used when provisioning the virtual server
               instance, but not subsequently managed. Accordingly, it is reflected as an
               [instance
               initialization](https://cloud.ibm.com/apidocs/vpc#get-instance-initialization)
               property.
        :param InstanceMetadataServicePrototype metadata_service: (optional)
        :param str name: (optional) The name for this virtual server instance. The
               name must not be used by another virtual server instance in the region. If
               unspecified, the name will be a hyphenated list of randomly-selected words.
               The system hostname will be based on this name.
        :param InstancePlacementTargetPrototype placement_target: (optional) The
               placement restrictions to use for the virtual server instance.
        :param InstanceProfileIdentity profile: (optional) The
               [profile](https://cloud.ibm.com/docs/vpc?topic=vpc-profiles) to use for
               this virtual server instance.
               If unspecified, `bx2-2x8` will be used, but this default value is expected
               to change in the future.
        :param ResourceGroupIdentity resource_group: (optional)
        :param int total_volume_bandwidth: (optional) The amount of bandwidth (in
               megabits per second) allocated exclusively to instance storage volumes. An
               increase in this value will result in a corresponding decrease to
               `total_network_bandwidth`.
        :param str user_data: (optional) [User
               data](https://cloud.ibm.com/docs/vpc?topic=vpc-user-data) to make available
               when setting up the virtual server instance.
        :param List[VolumeAttachmentPrototype] volume_attachments: (optional) The
               additional volume attachments to create for the virtual server instance.
        :param VPCIdentity vpc: (optional) The VPC this virtual server instance
               will reside in.
               If specified, it must match the VPC for the subnets of the instance network
               interfaces.
        :param VolumeAttachmentPrototypeInstanceByImageContext
               boot_volume_attachment: (optional) The boot volume attachment to create for
               the virtual server instance.
        :param List[NetworkInterfacePrototype] network_interfaces: (optional) The
               additional instance network interfaces to create.
        """
        # pylint: disable=super-init-not-called
        self.availability_policy = availability_policy
        self.default_trusted_profile = default_trusted_profile
        self.keys = keys
        self.metadata_service = metadata_service
        self.name = name
        self.placement_target = placement_target
        self.profile = profile
        self.resource_group = resource_group
        self.total_volume_bandwidth = total_volume_bandwidth
        self.user_data = user_data
        self.volume_attachments = volume_attachments
        self.vpc = vpc
        self.boot_volume_attachment = boot_volume_attachment
        self.image = image
        self.network_interfaces = network_interfaces
        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 'availability_policy' in _dict:
            args['availability_policy'] = InstanceAvailabilityPolicyPrototype.from_dict(_dict.get('availability_policy'))
        if 'default_trusted_profile' in _dict:
            args['default_trusted_profile'] = InstanceDefaultTrustedProfilePrototype.from_dict(_dict.get('default_trusted_profile'))
        if 'keys' in _dict:
            args['keys'] = _dict.get('keys')
        if 'metadata_service' in _dict:
            args['metadata_service'] = InstanceMetadataServicePrototype.from_dict(_dict.get('metadata_service'))
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        if 'placement_target' in _dict:
            args['placement_target'] = _dict.get('placement_target')
        if 'profile' in _dict:
            args['profile'] = _dict.get('profile')
        if 'resource_group' in _dict:
            args['resource_group'] = _dict.get('resource_group')
        if 'total_volume_bandwidth' in _dict:
            args['total_volume_bandwidth'] = _dict.get('total_volume_bandwidth')
        if 'user_data' in _dict:
            args['user_data'] = _dict.get('user_data')
        if 'volume_attachments' in _dict:
            args['volume_attachments'] = [VolumeAttachmentPrototype.from_dict(v) for v 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 'network_interfaces' in _dict:
            args['network_interfaces'] = [NetworkInterfacePrototype.from_dict(v) for v in _dict.get('network_interfaces')]
        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, 'availability_policy') and self.availability_policy is not None:
            if isinstance(self.availability_policy, dict):
                _dict['availability_policy'] = self.availability_policy
            else:
                _dict['availability_policy'] = self.availability_policy.to_dict()
        if hasattr(self, 'default_trusted_profile') and self.default_trusted_profile is not None:
            if isinstance(self.default_trusted_profile, dict):
                _dict['default_trusted_profile'] = self.default_trusted_profile
            else:
                _dict['default_trusted_profile'] = self.default_trusted_profile.to_dict()
        if hasattr(self, 'keys') and self.keys is not None:
            keys_list = []
            for v in self.keys:
                if isinstance(v, dict):
                    keys_list.append(v)
                else:
                    keys_list.append(v.to_dict())
            _dict['keys'] = keys_list
        if hasattr(self, 'metadata_service') and self.metadata_service is not None:
            if isinstance(self.metadata_service, dict):
                _dict['metadata_service'] = self.metadata_service
            else:
                _dict['metadata_service'] = self.metadata_service.to_dict()
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'placement_target') and self.placement_target is not None:
            if isinstance(self.placement_target, dict):
                _dict['placement_target'] = self.placement_target
            else:
                _dict['placement_target'] = self.placement_target.to_dict()
        if hasattr(self, 'profile') and self.profile is not None:
            if isinstance(self.profile, dict):
                _dict['profile'] = self.profile
            else:
                _dict['profile'] = self.profile.to_dict()
        if hasattr(self, 'resource_group') and self.resource_group is not None:
            if isinstance(self.resource_group, dict):
                _dict['resource_group'] = self.resource_group
            else:
                _dict['resource_group'] = self.resource_group.to_dict()
        if hasattr(self, 'total_volume_bandwidth') and self.total_volume_bandwidth is not None:
            _dict['total_volume_bandwidth'] = self.total_volume_bandwidth
        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:
            volume_attachments_list = []
            for v in self.volume_attachments:
                if isinstance(v, dict):
                    volume_attachments_list.append(v)
                else:
                    volume_attachments_list.append(v.to_dict())
            _dict['volume_attachments'] = volume_attachments_list
        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:
            if isinstance(self.boot_volume_attachment, dict):
                _dict['boot_volume_attachment'] = self.boot_volume_attachment
            else:
                _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, 'network_interfaces') and self.network_interfaces is not None:
            network_interfaces_list = []
            for v in self.network_interfaces:
                if isinstance(v, dict):
                    network_interfaces_list.append(v)
                else:
                    network_interfaces_list.append(v.to_dict())
            _dict['network_interfaces'] = network_interfaces_list
        if hasattr(self, 'primary_network_interface') and self.primary_network_interface is not None:
            if isinstance(self.primary_network_interface, dict):
                _dict['primary_network_interface'] = self.primary_network_interface
            else:
                _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 InstancePrototypeInstanceBySourceSnapshot(InstancePrototype):
    """
    Create an instance by using a snapshot.

    :attr InstanceAvailabilityPolicyPrototype availability_policy: (optional) The
          availability policy to use for this virtual server instance.
    :attr InstanceDefaultTrustedProfilePrototype default_trusted_profile: (optional)
          The default trusted profile configuration to use for this virtual server
          instance
          This property's value is used when provisioning the virtual server instance, but
          not subsequently managed. Accordingly, it is reflected as an [instance
          initialization](https://cloud.ibm.com/apidocs/vpc#get-instance-initialization)
          property.
    :attr List[KeyIdentity] keys: (optional) The public SSH keys for the
          administrative user of the virtual server instance. 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.
          For Windows images, the keys of type `rsa` must be specified, and one will be
          selected to encrypt [the administrator
          password](https://cloud.ibm.com/apidocs/vpc#get-instance-initialization). Keys
          are optional for other images, but if no keys are specified, the instance will
          be inaccessible unless the specified image provides another means of access.
          This property's value is used when provisioning the virtual server instance, but
          not subsequently managed. Accordingly, it is reflected as an [instance
          initialization](https://cloud.ibm.com/apidocs/vpc#get-instance-initialization)
          property.
    :attr InstanceMetadataServicePrototype metadata_service: (optional)
    :attr str name: (optional) The name for this virtual server instance. The name
          must not be used by another virtual server instance in the region. If
          unspecified, the name will be a hyphenated list of randomly-selected words.
          The system hostname will be based on this name.
    :attr InstancePlacementTargetPrototype placement_target: (optional) The
          placement restrictions to use for the virtual server instance.
    :attr InstanceProfileIdentity profile: (optional) The
          [profile](https://cloud.ibm.com/docs/vpc?topic=vpc-profiles) to use for this
          virtual server instance.
          If unspecified, `bx2-2x8` will be used, but this default value is expected to
          change in the future.
    :attr ResourceGroupIdentity resource_group: (optional)
    :attr int total_volume_bandwidth: (optional) The amount of bandwidth (in
          megabits per second) allocated exclusively to instance storage volumes. An
          increase in this value will result in a corresponding decrease to
          `total_network_bandwidth`.
    :attr str user_data: (optional) [User
          data](https://cloud.ibm.com/docs/vpc?topic=vpc-user-data) to make available when
          setting up the virtual server instance.
    :attr List[VolumeAttachmentPrototype] volume_attachments: (optional) The
          additional volume attachments to create for the virtual server instance.
    :attr VPCIdentity vpc: (optional) The VPC this virtual server instance will
          reside in.
          If specified, it must match the VPC for the subnets of the instance network
          interfaces.
    :attr VolumeAttachmentPrototypeInstanceBySourceSnapshotContext
          boot_volume_attachment: The boot volume attachment to create for the virtual
          server instance.
    :attr List[NetworkInterfacePrototype] network_interfaces: (optional) The
          additional instance network interfaces to create.
    :attr NetworkInterfacePrototype primary_network_interface: The primary instance
          network interface to create.
    :attr ZoneIdentity zone: The zone this virtual server instance will reside in.
    """

    def __init__(
        self,
        boot_volume_attachment: 'VolumeAttachmentPrototypeInstanceBySourceSnapshotContext',
        primary_network_interface: 'NetworkInterfacePrototype',
        zone: 'ZoneIdentity',
        *,
        availability_policy: 'InstanceAvailabilityPolicyPrototype' = None,
        default_trusted_profile: 'InstanceDefaultTrustedProfilePrototype' = None,
        keys: List['KeyIdentity'] = None,
        metadata_service: 'InstanceMetadataServicePrototype' = None,
        name: str = None,
        placement_target: 'InstancePlacementTargetPrototype' = None,
        profile: 'InstanceProfileIdentity' = None,
        resource_group: 'ResourceGroupIdentity' = None,
        total_volume_bandwidth: int = None,
        user_data: str = None,
        volume_attachments: List['VolumeAttachmentPrototype'] = None,
        vpc: 'VPCIdentity' = None,
        network_interfaces: List['NetworkInterfacePrototype'] = None,
    ) -> None:
        """
        Initialize a InstancePrototypeInstanceBySourceSnapshot object.

        :param VolumeAttachmentPrototypeInstanceBySourceSnapshotContext
               boot_volume_attachment: The boot volume attachment to create for the
               virtual server instance.
        :param NetworkInterfacePrototype primary_network_interface: The primary
               instance network interface to create.
        :param ZoneIdentity zone: The zone this virtual server instance will reside
               in.
        :param InstanceAvailabilityPolicyPrototype availability_policy: (optional)
               The availability policy to use for this virtual server instance.
        :param InstanceDefaultTrustedProfilePrototype default_trusted_profile:
               (optional) The default trusted profile configuration to use for this
               virtual server instance
               This property's value is used when provisioning the virtual server
               instance, but not subsequently managed. Accordingly, it is reflected as an
               [instance
               initialization](https://cloud.ibm.com/apidocs/vpc#get-instance-initialization)
               property.
        :param List[KeyIdentity] keys: (optional) The public SSH keys for the
               administrative user of the virtual server instance. 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.
               For Windows images, the keys of type `rsa` must be specified, and one will
               be selected to encrypt [the administrator
               password](https://cloud.ibm.com/apidocs/vpc#get-instance-initialization).
               Keys are optional for other images, but if no keys are specified, the
               instance will be inaccessible unless the specified image provides another
               means of access.
               This property's value is used when provisioning the virtual server
               instance, but not subsequently managed. Accordingly, it is reflected as an
               [instance
               initialization](https://cloud.ibm.com/apidocs/vpc#get-instance-initialization)
               property.
        :param InstanceMetadataServicePrototype metadata_service: (optional)
        :param str name: (optional) The name for this virtual server instance. The
               name must not be used by another virtual server instance in the region. If
               unspecified, the name will be a hyphenated list of randomly-selected words.
               The system hostname will be based on this name.
        :param InstancePlacementTargetPrototype placement_target: (optional) The
               placement restrictions to use for the virtual server instance.
        :param InstanceProfileIdentity profile: (optional) The
               [profile](https://cloud.ibm.com/docs/vpc?topic=vpc-profiles) to use for
               this virtual server instance.
               If unspecified, `bx2-2x8` will be used, but this default value is expected
               to change in the future.
        :param ResourceGroupIdentity resource_group: (optional)
        :param int total_volume_bandwidth: (optional) The amount of bandwidth (in
               megabits per second) allocated exclusively to instance storage volumes. An
               increase in this value will result in a corresponding decrease to
               `total_network_bandwidth`.
        :param str user_data: (optional) [User
               data](https://cloud.ibm.com/docs/vpc?topic=vpc-user-data) to make available
               when setting up the virtual server instance.
        :param List[VolumeAttachmentPrototype] volume_attachments: (optional) The
               additional volume attachments to create for the virtual server instance.
        :param VPCIdentity vpc: (optional) The VPC this virtual server instance
               will reside in.
               If specified, it must match the VPC for the subnets of the instance network
               interfaces.
        :param List[NetworkInterfacePrototype] network_interfaces: (optional) The
               additional instance network interfaces to create.
        """
        # pylint: disable=super-init-not-called
        self.availability_policy = availability_policy
        self.default_trusted_profile = default_trusted_profile
        self.keys = keys
        self.metadata_service = metadata_service
        self.name = name
        self.placement_target = placement_target
        self.profile = profile
        self.resource_group = resource_group
        self.total_volume_bandwidth = total_volume_bandwidth
        self.user_data = user_data
        self.volume_attachments = volume_attachments
        self.vpc = vpc
        self.boot_volume_attachment = boot_volume_attachment
        self.network_interfaces = network_interfaces
        self.primary_network_interface = primary_network_interface
        self.zone = zone

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstancePrototypeInstanceBySourceSnapshot':
        """Initialize a InstancePrototypeInstanceBySourceSnapshot object from a json dictionary."""
        args = {}
        if 'availability_policy' in _dict:
            args['availability_policy'] = InstanceAvailabilityPolicyPrototype.from_dict(_dict.get('availability_policy'))
        if 'default_trusted_profile' in _dict:
            args['default_trusted_profile'] = InstanceDefaultTrustedProfilePrototype.from_dict(_dict.get('default_trusted_profile'))
        if 'keys' in _dict:
            args['keys'] = _dict.get('keys')
        if 'metadata_service' in _dict:
            args['metadata_service'] = InstanceMetadataServicePrototype.from_dict(_dict.get('metadata_service'))
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        if 'placement_target' in _dict:
            args['placement_target'] = _dict.get('placement_target')
        if 'profile' in _dict:
            args['profile'] = _dict.get('profile')
        if 'resource_group' in _dict:
            args['resource_group'] = _dict.get('resource_group')
        if 'total_volume_bandwidth' in _dict:
            args['total_volume_bandwidth'] = _dict.get('total_volume_bandwidth')
        if 'user_data' in _dict:
            args['user_data'] = _dict.get('user_data')
        if 'volume_attachments' in _dict:
            args['volume_attachments'] = [VolumeAttachmentPrototype.from_dict(v) for v in _dict.get('volume_attachments')]
        if 'vpc' in _dict:
            args['vpc'] = _dict.get('vpc')
        if 'boot_volume_attachment' in _dict:
            args['boot_volume_attachment'] = VolumeAttachmentPrototypeInstanceBySourceSnapshotContext.from_dict(_dict.get('boot_volume_attachment'))
        else:
            raise ValueError('Required property \'boot_volume_attachment\' not present in InstancePrototypeInstanceBySourceSnapshot JSON')
        if 'network_interfaces' in _dict:
            args['network_interfaces'] = [NetworkInterfacePrototype.from_dict(v) for v in _dict.get('network_interfaces')]
        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 InstancePrototypeInstanceBySourceSnapshot JSON')
        if 'zone' in _dict:
            args['zone'] = _dict.get('zone')
        else:
            raise ValueError('Required property \'zone\' not present in InstancePrototypeInstanceBySourceSnapshot JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstancePrototypeInstanceBySourceSnapshot object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'availability_policy') and self.availability_policy is not None:
            if isinstance(self.availability_policy, dict):
                _dict['availability_policy'] = self.availability_policy
            else:
                _dict['availability_policy'] = self.availability_policy.to_dict()
        if hasattr(self, 'default_trusted_profile') and self.default_trusted_profile is not None:
            if isinstance(self.default_trusted_profile, dict):
                _dict['default_trusted_profile'] = self.default_trusted_profile
            else:
                _dict['default_trusted_profile'] = self.default_trusted_profile.to_dict()
        if hasattr(self, 'keys') and self.keys is not None:
            keys_list = []
            for v in self.keys:
                if isinstance(v, dict):
                    keys_list.append(v)
                else:
                    keys_list.append(v.to_dict())
            _dict['keys'] = keys_list
        if hasattr(self, 'metadata_service') and self.metadata_service is not None:
            if isinstance(self.metadata_service, dict):
                _dict['metadata_service'] = self.metadata_service
            else:
                _dict['metadata_service'] = self.metadata_service.to_dict()
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'placement_target') and self.placement_target is not None:
            if isinstance(self.placement_target, dict):
                _dict['placement_target'] = self.placement_target
            else:
                _dict['placement_target'] = self.placement_target.to_dict()
        if hasattr(self, 'profile') and self.profile is not None:
            if isinstance(self.profile, dict):
                _dict['profile'] = self.profile
            else:
                _dict['profile'] = self.profile.to_dict()
        if hasattr(self, 'resource_group') and self.resource_group is not None:
            if isinstance(self.resource_group, dict):
                _dict['resource_group'] = self.resource_group
            else:
                _dict['resource_group'] = self.resource_group.to_dict()
        if hasattr(self, 'total_volume_bandwidth') and self.total_volume_bandwidth is not None:
            _dict['total_volume_bandwidth'] = self.total_volume_bandwidth
        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:
            volume_attachments_list = []
            for v in self.volume_attachments:
                if isinstance(v, dict):
                    volume_attachments_list.append(v)
                else:
                    volume_attachments_list.append(v.to_dict())
            _dict['volume_attachments'] = volume_attachments_list
        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:
            if isinstance(self.boot_volume_attachment, dict):
                _dict['boot_volume_attachment'] = self.boot_volume_attachment
            else:
                _dict['boot_volume_attachment'] = self.boot_volume_attachment.to_dict()
        if hasattr(self, 'network_interfaces') and self.network_interfaces is not None:
            network_interfaces_list = []
            for v in self.network_interfaces:
                if isinstance(v, dict):
                    network_interfaces_list.append(v)
                else:
                    network_interfaces_list.append(v.to_dict())
            _dict['network_interfaces'] = network_interfaces_list
        if hasattr(self, 'primary_network_interface') and self.primary_network_interface is not None:
            if isinstance(self.primary_network_interface, dict):
                _dict['primary_network_interface'] = self.primary_network_interface
            else:
                _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 InstancePrototypeInstanceBySourceSnapshot object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstancePrototypeInstanceBySourceSnapshot') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstancePrototypeInstanceBySourceSnapshot') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstancePrototypeInstanceBySourceTemplate(InstancePrototype):
    """
    Create an instance by using an instance template.
    The `primary_network_interface` and `network_interfaces` properties may only be
    specified if `primary_network_interface` is specified in the source template.

    :attr InstanceAvailabilityPolicyPrototype availability_policy: (optional) The
          availability policy to use for this virtual server instance.
    :attr InstanceDefaultTrustedProfilePrototype default_trusted_profile: (optional)
          The default trusted profile configuration to use for this virtual server
          instance
          This property's value is used when provisioning the virtual server instance, but
          not subsequently managed. Accordingly, it is reflected as an [instance
          initialization](https://cloud.ibm.com/apidocs/vpc#get-instance-initialization)
          property.
    :attr List[KeyIdentity] keys: (optional) The public SSH keys for the
          administrative user of the virtual server instance. 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.
          For Windows images, the keys of type `rsa` must be specified, and one will be
          selected to encrypt [the administrator
          password](https://cloud.ibm.com/apidocs/vpc#get-instance-initialization). Keys
          are optional for other images, but if no keys are specified, the instance will
          be inaccessible unless the specified image provides another means of access.
          This property's value is used when provisioning the virtual server instance, but
          not subsequently managed. Accordingly, it is reflected as an [instance
          initialization](https://cloud.ibm.com/apidocs/vpc#get-instance-initialization)
          property.
    :attr InstanceMetadataServicePrototype metadata_service: (optional)
    :attr str name: (optional) The name for this virtual server instance. The name
          must not be used by another virtual server instance in the region. If
          unspecified, the name will be a hyphenated list of randomly-selected words.
          The system hostname will be based on this name.
    :attr InstancePlacementTargetPrototype placement_target: (optional) The
          placement restrictions to use for the virtual server instance.
    :attr InstanceProfileIdentity profile: (optional) The
          [profile](https://cloud.ibm.com/docs/vpc?topic=vpc-profiles) to use for this
          virtual server instance.
          If unspecified, `bx2-2x8` will be used, but this default value is expected to
          change in the future.
    :attr ResourceGroupIdentity resource_group: (optional)
    :attr int total_volume_bandwidth: (optional) The amount of bandwidth (in
          megabits per second) allocated exclusively to instance storage volumes. An
          increase in this value will result in a corresponding decrease to
          `total_network_bandwidth`.
    :attr str user_data: (optional) [User
          data](https://cloud.ibm.com/docs/vpc?topic=vpc-user-data) to make available when
          setting up the virtual server instance.
    :attr List[VolumeAttachmentPrototype] volume_attachments: (optional) The
          additional volume attachments to create for the virtual server instance.
    :attr VPCIdentity vpc: (optional) The VPC this virtual server instance will
          reside in.
          If specified, it must match the VPC for the subnets of the instance network
          interfaces.
    :attr VolumeAttachmentPrototypeInstanceByImageContext boot_volume_attachment:
          (optional) The boot volume attachment to create for the virtual server instance.
    :attr InstanceCatalogOfferingPrototype catalog_offering: (optional) The
          [catalog](https://cloud.ibm.com/docs/account?topic=account-restrict-by-user)
          offering version to use when provisioning this virtual server instance.
          If an offering is specified, the latest version of that offering will be used.
          The specified offering or offering version may be in a different account,
          subject to
          IAM policies.
          If specified, `image` must not be specified, and `source_template` must not have
          `image` specified.
    :attr ImageIdentity image: (optional) The image to use when provisioning the
          virtual server instance.
    :attr List[NetworkInterfacePrototype] network_interfaces: (optional) The
          additional instance network interfaces to create.
    :attr NetworkInterfacePrototype primary_network_interface: (optional) The
          primary instance network interface to create.
    :attr InstanceTemplateIdentity source_template: The template to create this
          virtual server instance from.
    :attr ZoneIdentity zone: (optional) The zone this virtual server instance will
          reside in.
    """

    def __init__(
        self,
        source_template: 'InstanceTemplateIdentity',
        *,
        availability_policy: 'InstanceAvailabilityPolicyPrototype' = None,
        default_trusted_profile: 'InstanceDefaultTrustedProfilePrototype' = None,
        keys: List['KeyIdentity'] = None,
        metadata_service: 'InstanceMetadataServicePrototype' = None,
        name: str = None,
        placement_target: 'InstancePlacementTargetPrototype' = None,
        profile: 'InstanceProfileIdentity' = None,
        resource_group: 'ResourceGroupIdentity' = None,
        total_volume_bandwidth: int = None,
        user_data: str = None,
        volume_attachments: List['VolumeAttachmentPrototype'] = None,
        vpc: 'VPCIdentity' = None,
        boot_volume_attachment: 'VolumeAttachmentPrototypeInstanceByImageContext' = None,
        catalog_offering: 'InstanceCatalogOfferingPrototype' = None,
        image: 'ImageIdentity' = None,
        network_interfaces: List['NetworkInterfacePrototype'] = None,
        primary_network_interface: 'NetworkInterfacePrototype' = None,
        zone: 'ZoneIdentity' = None,
    ) -> None:
        """
        Initialize a InstancePrototypeInstanceBySourceTemplate object.

        :param InstanceTemplateIdentity source_template: The template to create
               this virtual server instance from.
        :param InstanceAvailabilityPolicyPrototype availability_policy: (optional)
               The availability policy to use for this virtual server instance.
        :param InstanceDefaultTrustedProfilePrototype default_trusted_profile:
               (optional) The default trusted profile configuration to use for this
               virtual server instance
               This property's value is used when provisioning the virtual server
               instance, but not subsequently managed. Accordingly, it is reflected as an
               [instance
               initialization](https://cloud.ibm.com/apidocs/vpc#get-instance-initialization)
               property.
        :param List[KeyIdentity] keys: (optional) The public SSH keys for the
               administrative user of the virtual server instance. 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.
               For Windows images, the keys of type `rsa` must be specified, and one will
               be selected to encrypt [the administrator
               password](https://cloud.ibm.com/apidocs/vpc#get-instance-initialization).
               Keys are optional for other images, but if no keys are specified, the
               instance will be inaccessible unless the specified image provides another
               means of access.
               This property's value is used when provisioning the virtual server
               instance, but not subsequently managed. Accordingly, it is reflected as an
               [instance
               initialization](https://cloud.ibm.com/apidocs/vpc#get-instance-initialization)
               property.
        :param InstanceMetadataServicePrototype metadata_service: (optional)
        :param str name: (optional) The name for this virtual server instance. The
               name must not be used by another virtual server instance in the region. If
               unspecified, the name will be a hyphenated list of randomly-selected words.
               The system hostname will be based on this name.
        :param InstancePlacementTargetPrototype placement_target: (optional) The
               placement restrictions to use for the virtual server instance.
        :param InstanceProfileIdentity profile: (optional) The
               [profile](https://cloud.ibm.com/docs/vpc?topic=vpc-profiles) to use for
               this virtual server instance.
               If unspecified, `bx2-2x8` will be used, but this default value is expected
               to change in the future.
        :param ResourceGroupIdentity resource_group: (optional)
        :param int total_volume_bandwidth: (optional) The amount of bandwidth (in
               megabits per second) allocated exclusively to instance storage volumes. An
               increase in this value will result in a corresponding decrease to
               `total_network_bandwidth`.
        :param str user_data: (optional) [User
               data](https://cloud.ibm.com/docs/vpc?topic=vpc-user-data) to make available
               when setting up the virtual server instance.
        :param List[VolumeAttachmentPrototype] volume_attachments: (optional) The
               additional volume attachments to create for the virtual server instance.
        :param VPCIdentity vpc: (optional) The VPC this virtual server instance
               will reside in.
               If specified, it must match the VPC for the subnets of the instance network
               interfaces.
        :param VolumeAttachmentPrototypeInstanceByImageContext
               boot_volume_attachment: (optional) The boot volume attachment to create for
               the virtual server instance.
        :param InstanceCatalogOfferingPrototype catalog_offering: (optional) The
               [catalog](https://cloud.ibm.com/docs/account?topic=account-restrict-by-user)
               offering version to use when provisioning this virtual server instance.
               If an offering is specified, the latest version of that offering will be
               used.
               The specified offering or offering version may be in a different account,
               subject to
               IAM policies.
               If specified, `image` must not be specified, and `source_template` must not
               have
               `image` specified.
        :param ImageIdentity image: (optional) The image to use when provisioning
               the virtual server instance.
        :param List[NetworkInterfacePrototype] network_interfaces: (optional) The
               additional instance network interfaces to create.
        :param NetworkInterfacePrototype primary_network_interface: (optional) The
               primary instance network interface to create.
        :param ZoneIdentity zone: (optional) The zone this virtual server instance
               will reside in.
        """
        # pylint: disable=super-init-not-called
        self.availability_policy = availability_policy
        self.default_trusted_profile = default_trusted_profile
        self.keys = keys
        self.metadata_service = metadata_service
        self.name = name
        self.placement_target = placement_target
        self.profile = profile
        self.resource_group = resource_group
        self.total_volume_bandwidth = total_volume_bandwidth
        self.user_data = user_data
        self.volume_attachments = volume_attachments
        self.vpc = vpc
        self.boot_volume_attachment = boot_volume_attachment
        self.catalog_offering = catalog_offering
        self.image = image
        self.network_interfaces = network_interfaces
        self.primary_network_interface = primary_network_interface
        self.source_template = source_template
        self.zone = zone

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstancePrototypeInstanceBySourceTemplate':
        """Initialize a InstancePrototypeInstanceBySourceTemplate object from a json dictionary."""
        args = {}
        if 'availability_policy' in _dict:
            args['availability_policy'] = InstanceAvailabilityPolicyPrototype.from_dict(_dict.get('availability_policy'))
        if 'default_trusted_profile' in _dict:
            args['default_trusted_profile'] = InstanceDefaultTrustedProfilePrototype.from_dict(_dict.get('default_trusted_profile'))
        if 'keys' in _dict:
            args['keys'] = _dict.get('keys')
        if 'metadata_service' in _dict:
            args['metadata_service'] = InstanceMetadataServicePrototype.from_dict(_dict.get('metadata_service'))
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        if 'placement_target' in _dict:
            args['placement_target'] = _dict.get('placement_target')
        if 'profile' in _dict:
            args['profile'] = _dict.get('profile')
        if 'resource_group' in _dict:
            args['resource_group'] = _dict.get('resource_group')
        if 'total_volume_bandwidth' in _dict:
            args['total_volume_bandwidth'] = _dict.get('total_volume_bandwidth')
        if 'user_data' in _dict:
            args['user_data'] = _dict.get('user_data')
        if 'volume_attachments' in _dict:
            args['volume_attachments'] = [VolumeAttachmentPrototype.from_dict(v) for v 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 'catalog_offering' in _dict:
            args['catalog_offering'] = _dict.get('catalog_offering')
        if 'image' in _dict:
            args['image'] = _dict.get('image')
        if 'network_interfaces' in _dict:
            args['network_interfaces'] = [NetworkInterfacePrototype.from_dict(v) for v in _dict.get('network_interfaces')]
        if 'primary_network_interface' in _dict:
            args['primary_network_interface'] = NetworkInterfacePrototype.from_dict(_dict.get('primary_network_interface'))
        if 'source_template' in _dict:
            args['source_template'] = _dict.get('source_template')
        else:
            raise ValueError('Required property \'source_template\' not present in InstancePrototypeInstanceBySourceTemplate JSON')
        if 'zone' in _dict:
            args['zone'] = _dict.get('zone')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstancePrototypeInstanceBySourceTemplate object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'availability_policy') and self.availability_policy is not None:
            if isinstance(self.availability_policy, dict):
                _dict['availability_policy'] = self.availability_policy
            else:
                _dict['availability_policy'] = self.availability_policy.to_dict()
        if hasattr(self, 'default_trusted_profile') and self.default_trusted_profile is not None:
            if isinstance(self.default_trusted_profile, dict):
                _dict['default_trusted_profile'] = self.default_trusted_profile
            else:
                _dict['default_trusted_profile'] = self.default_trusted_profile.to_dict()
        if hasattr(self, 'keys') and self.keys is not None:
            keys_list = []
            for v in self.keys:
                if isinstance(v, dict):
                    keys_list.append(v)
                else:
                    keys_list.append(v.to_dict())
            _dict['keys'] = keys_list
        if hasattr(self, 'metadata_service') and self.metadata_service is not None:
            if isinstance(self.metadata_service, dict):
                _dict['metadata_service'] = self.metadata_service
            else:
                _dict['metadata_service'] = self.metadata_service.to_dict()
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'placement_target') and self.placement_target is not None:
            if isinstance(self.placement_target, dict):
                _dict['placement_target'] = self.placement_target
            else:
                _dict['placement_target'] = self.placement_target.to_dict()
        if hasattr(self, 'profile') and self.profile is not None:
            if isinstance(self.profile, dict):
                _dict['profile'] = self.profile
            else:
                _dict['profile'] = self.profile.to_dict()
        if hasattr(self, 'resource_group') and self.resource_group is not None:
            if isinstance(self.resource_group, dict):
                _dict['resource_group'] = self.resource_group
            else:
                _dict['resource_group'] = self.resource_group.to_dict()
        if hasattr(self, 'total_volume_bandwidth') and self.total_volume_bandwidth is not None:
            _dict['total_volume_bandwidth'] = self.total_volume_bandwidth
        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:
            volume_attachments_list = []
            for v in self.volume_attachments:
                if isinstance(v, dict):
                    volume_attachments_list.append(v)
                else:
                    volume_attachments_list.append(v.to_dict())
            _dict['volume_attachments'] = volume_attachments_list
        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:
            if isinstance(self.boot_volume_attachment, dict):
                _dict['boot_volume_attachment'] = self.boot_volume_attachment
            else:
                _dict['boot_volume_attachment'] = self.boot_volume_attachment.to_dict()
        if hasattr(self, 'catalog_offering') and self.catalog_offering is not None:
            if isinstance(self.catalog_offering, dict):
                _dict['catalog_offering'] = self.catalog_offering
            else:
                _dict['catalog_offering'] = self.catalog_offering.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, 'network_interfaces') and self.network_interfaces is not None:
            network_interfaces_list = []
            for v in self.network_interfaces:
                if isinstance(v, dict):
                    network_interfaces_list.append(v)
                else:
                    network_interfaces_list.append(v.to_dict())
            _dict['network_interfaces'] = network_interfaces_list
        if hasattr(self, 'primary_network_interface') and self.primary_network_interface is not None:
            if isinstance(self.primary_network_interface, dict):
                _dict['primary_network_interface'] = self.primary_network_interface
            else:
                _dict['primary_network_interface'] = self.primary_network_interface.to_dict()
        if hasattr(self, 'source_template') and self.source_template is not None:
            if isinstance(self.source_template, dict):
                _dict['source_template'] = self.source_template
            else:
                _dict['source_template'] = self.source_template.to_dict()
        if hasattr(self, 'zone') and self.zone is not None:
            if isinstance(self.zone, dict):
                _dict['zone'] = self.zone
            else:
                _dict['zone'] = self.zone.to_dict()
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstancePrototypeInstanceBySourceTemplate object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstancePrototypeInstanceBySourceTemplate') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstancePrototypeInstanceBySourceTemplate') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstancePrototypeInstanceByVolume(InstancePrototype):
    """
    Create an instance by using a boot volume.

    :attr InstanceAvailabilityPolicyPrototype availability_policy: (optional) The
          availability policy to use for this virtual server instance.
    :attr InstanceDefaultTrustedProfilePrototype default_trusted_profile: (optional)
          The default trusted profile configuration to use for this virtual server
          instance
          This property's value is used when provisioning the virtual server instance, but
          not subsequently managed. Accordingly, it is reflected as an [instance
          initialization](https://cloud.ibm.com/apidocs/vpc#get-instance-initialization)
          property.
    :attr List[KeyIdentity] keys: (optional) The public SSH keys for the
          administrative user of the virtual server instance. 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.
          For Windows images, the keys of type `rsa` must be specified, and one will be
          selected to encrypt [the administrator
          password](https://cloud.ibm.com/apidocs/vpc#get-instance-initialization). Keys
          are optional for other images, but if no keys are specified, the instance will
          be inaccessible unless the specified image provides another means of access.
          This property's value is used when provisioning the virtual server instance, but
          not subsequently managed. Accordingly, it is reflected as an [instance
          initialization](https://cloud.ibm.com/apidocs/vpc#get-instance-initialization)
          property.
    :attr InstanceMetadataServicePrototype metadata_service: (optional)
    :attr str name: (optional) The name for this virtual server instance. The name
          must not be used by another virtual server instance in the region. If
          unspecified, the name will be a hyphenated list of randomly-selected words.
          The system hostname will be based on this name.
    :attr InstancePlacementTargetPrototype placement_target: (optional) The
          placement restrictions to use for the virtual server instance.
    :attr InstanceProfileIdentity profile: (optional) The
          [profile](https://cloud.ibm.com/docs/vpc?topic=vpc-profiles) to use for this
          virtual server instance.
          If unspecified, `bx2-2x8` will be used, but this default value is expected to
          change in the future.
    :attr ResourceGroupIdentity resource_group: (optional)
    :attr int total_volume_bandwidth: (optional) The amount of bandwidth (in
          megabits per second) allocated exclusively to instance storage volumes. An
          increase in this value will result in a corresponding decrease to
          `total_network_bandwidth`.
    :attr str user_data: (optional) [User
          data](https://cloud.ibm.com/docs/vpc?topic=vpc-user-data) to make available when
          setting up the virtual server instance.
    :attr List[VolumeAttachmentPrototype] volume_attachments: (optional) The
          additional volume attachments to create for the virtual server instance.
    :attr VPCIdentity vpc: (optional) The VPC this virtual server instance will
          reside in.
          If specified, it must match the VPC for the subnets of the instance network
          interfaces.
    :attr VolumeAttachmentPrototypeInstanceByVolumeContext boot_volume_attachment:
          The boot volume attachment for the virtual server instance.
    :attr List[NetworkInterfacePrototype] network_interfaces: (optional) The
          additional instance network interfaces to create.
    :attr NetworkInterfacePrototype primary_network_interface: The primary instance
          network interface to create.
    :attr ZoneIdentity zone: The zone this virtual server instance will reside in.
    """

    def __init__(
        self,
        boot_volume_attachment: 'VolumeAttachmentPrototypeInstanceByVolumeContext',
        primary_network_interface: 'NetworkInterfacePrototype',
        zone: 'ZoneIdentity',
        *,
        availability_policy: 'InstanceAvailabilityPolicyPrototype' = None,
        default_trusted_profile: 'InstanceDefaultTrustedProfilePrototype' = None,
        keys: List['KeyIdentity'] = None,
        metadata_service: 'InstanceMetadataServicePrototype' = None,
        name: str = None,
        placement_target: 'InstancePlacementTargetPrototype' = None,
        profile: 'InstanceProfileIdentity' = None,
        resource_group: 'ResourceGroupIdentity' = None,
        total_volume_bandwidth: int = None,
        user_data: str = None,
        volume_attachments: List['VolumeAttachmentPrototype'] = None,
        vpc: 'VPCIdentity' = None,
        network_interfaces: List['NetworkInterfacePrototype'] = None,
    ) -> None:
        """
        Initialize a InstancePrototypeInstanceByVolume object.

        :param VolumeAttachmentPrototypeInstanceByVolumeContext
               boot_volume_attachment: The boot volume attachment for the virtual server
               instance.
        :param NetworkInterfacePrototype primary_network_interface: The primary
               instance network interface to create.
        :param ZoneIdentity zone: The zone this virtual server instance will reside
               in.
        :param InstanceAvailabilityPolicyPrototype availability_policy: (optional)
               The availability policy to use for this virtual server instance.
        :param InstanceDefaultTrustedProfilePrototype default_trusted_profile:
               (optional) The default trusted profile configuration to use for this
               virtual server instance
               This property's value is used when provisioning the virtual server
               instance, but not subsequently managed. Accordingly, it is reflected as an
               [instance
               initialization](https://cloud.ibm.com/apidocs/vpc#get-instance-initialization)
               property.
        :param List[KeyIdentity] keys: (optional) The public SSH keys for the
               administrative user of the virtual server instance. 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.
               For Windows images, the keys of type `rsa` must be specified, and one will
               be selected to encrypt [the administrator
               password](https://cloud.ibm.com/apidocs/vpc#get-instance-initialization).
               Keys are optional for other images, but if no keys are specified, the
               instance will be inaccessible unless the specified image provides another
               means of access.
               This property's value is used when provisioning the virtual server
               instance, but not subsequently managed. Accordingly, it is reflected as an
               [instance
               initialization](https://cloud.ibm.com/apidocs/vpc#get-instance-initialization)
               property.
        :param InstanceMetadataServicePrototype metadata_service: (optional)
        :param str name: (optional) The name for this virtual server instance. The
               name must not be used by another virtual server instance in the region. If
               unspecified, the name will be a hyphenated list of randomly-selected words.
               The system hostname will be based on this name.
        :param InstancePlacementTargetPrototype placement_target: (optional) The
               placement restrictions to use for the virtual server instance.
        :param InstanceProfileIdentity profile: (optional) The
               [profile](https://cloud.ibm.com/docs/vpc?topic=vpc-profiles) to use for
               this virtual server instance.
               If unspecified, `bx2-2x8` will be used, but this default value is expected
               to change in the future.
        :param ResourceGroupIdentity resource_group: (optional)
        :param int total_volume_bandwidth: (optional) The amount of bandwidth (in
               megabits per second) allocated exclusively to instance storage volumes. An
               increase in this value will result in a corresponding decrease to
               `total_network_bandwidth`.
        :param str user_data: (optional) [User
               data](https://cloud.ibm.com/docs/vpc?topic=vpc-user-data) to make available
               when setting up the virtual server instance.
        :param List[VolumeAttachmentPrototype] volume_attachments: (optional) The
               additional volume attachments to create for the virtual server instance.
        :param VPCIdentity vpc: (optional) The VPC this virtual server instance
               will reside in.
               If specified, it must match the VPC for the subnets of the instance network
               interfaces.
        :param List[NetworkInterfacePrototype] network_interfaces: (optional) The
               additional instance network interfaces to create.
        """
        # pylint: disable=super-init-not-called
        self.availability_policy = availability_policy
        self.default_trusted_profile = default_trusted_profile
        self.keys = keys
        self.metadata_service = metadata_service
        self.name = name
        self.placement_target = placement_target
        self.profile = profile
        self.resource_group = resource_group
        self.total_volume_bandwidth = total_volume_bandwidth
        self.user_data = user_data
        self.volume_attachments = volume_attachments
        self.vpc = vpc
        self.boot_volume_attachment = boot_volume_attachment
        self.network_interfaces = network_interfaces
        self.primary_network_interface = primary_network_interface
        self.zone = zone

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstancePrototypeInstanceByVolume':
        """Initialize a InstancePrototypeInstanceByVolume object from a json dictionary."""
        args = {}
        if 'availability_policy' in _dict:
            args['availability_policy'] = InstanceAvailabilityPolicyPrototype.from_dict(_dict.get('availability_policy'))
        if 'default_trusted_profile' in _dict:
            args['default_trusted_profile'] = InstanceDefaultTrustedProfilePrototype.from_dict(_dict.get('default_trusted_profile'))
        if 'keys' in _dict:
            args['keys'] = _dict.get('keys')
        if 'metadata_service' in _dict:
            args['metadata_service'] = InstanceMetadataServicePrototype.from_dict(_dict.get('metadata_service'))
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        if 'placement_target' in _dict:
            args['placement_target'] = _dict.get('placement_target')
        if 'profile' in _dict:
            args['profile'] = _dict.get('profile')
        if 'resource_group' in _dict:
            args['resource_group'] = _dict.get('resource_group')
        if 'total_volume_bandwidth' in _dict:
            args['total_volume_bandwidth'] = _dict.get('total_volume_bandwidth')
        if 'user_data' in _dict:
            args['user_data'] = _dict.get('user_data')
        if 'volume_attachments' in _dict:
            args['volume_attachments'] = [VolumeAttachmentPrototype.from_dict(v) for v in _dict.get('volume_attachments')]
        if 'vpc' in _dict:
            args['vpc'] = _dict.get('vpc')
        if 'boot_volume_attachment' in _dict:
            args['boot_volume_attachment'] = VolumeAttachmentPrototypeInstanceByVolumeContext.from_dict(_dict.get('boot_volume_attachment'))
        else:
            raise ValueError('Required property \'boot_volume_attachment\' not present in InstancePrototypeInstanceByVolume JSON')
        if 'network_interfaces' in _dict:
            args['network_interfaces'] = [NetworkInterfacePrototype.from_dict(v) for v in _dict.get('network_interfaces')]
        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 InstancePrototypeInstanceByVolume JSON')
        if 'zone' in _dict:
            args['zone'] = _dict.get('zone')
        else:
            raise ValueError('Required property \'zone\' not present in InstancePrototypeInstanceByVolume JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstancePrototypeInstanceByVolume object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'availability_policy') and self.availability_policy is not None:
            if isinstance(self.availability_policy, dict):
                _dict['availability_policy'] = self.availability_policy
            else:
                _dict['availability_policy'] = self.availability_policy.to_dict()
        if hasattr(self, 'default_trusted_profile') and self.default_trusted_profile is not None:
            if isinstance(self.default_trusted_profile, dict):
                _dict['default_trusted_profile'] = self.default_trusted_profile
            else:
                _dict['default_trusted_profile'] = self.default_trusted_profile.to_dict()
        if hasattr(self, 'keys') and self.keys is not None:
            keys_list = []
            for v in self.keys:
                if isinstance(v, dict):
                    keys_list.append(v)
                else:
                    keys_list.append(v.to_dict())
            _dict['keys'] = keys_list
        if hasattr(self, 'metadata_service') and self.metadata_service is not None:
            if isinstance(self.metadata_service, dict):
                _dict['metadata_service'] = self.metadata_service
            else:
                _dict['metadata_service'] = self.metadata_service.to_dict()
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'placement_target') and self.placement_target is not None:
            if isinstance(self.placement_target, dict):
                _dict['placement_target'] = self.placement_target
            else:
                _dict['placement_target'] = self.placement_target.to_dict()
        if hasattr(self, 'profile') and self.profile is not None:
            if isinstance(self.profile, dict):
                _dict['profile'] = self.profile
            else:
                _dict['profile'] = self.profile.to_dict()
        if hasattr(self, 'resource_group') and self.resource_group is not None:
            if isinstance(self.resource_group, dict):
                _dict['resource_group'] = self.resource_group
            else:
                _dict['resource_group'] = self.resource_group.to_dict()
        if hasattr(self, 'total_volume_bandwidth') and self.total_volume_bandwidth is not None:
            _dict['total_volume_bandwidth'] = self.total_volume_bandwidth
        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:
            volume_attachments_list = []
            for v in self.volume_attachments:
                if isinstance(v, dict):
                    volume_attachments_list.append(v)
                else:
                    volume_attachments_list.append(v.to_dict())
            _dict['volume_attachments'] = volume_attachments_list
        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:
            if isinstance(self.boot_volume_attachment, dict):
                _dict['boot_volume_attachment'] = self.boot_volume_attachment
            else:
                _dict['boot_volume_attachment'] = self.boot_volume_attachment.to_dict()
        if hasattr(self, 'network_interfaces') and self.network_interfaces is not None:
            network_interfaces_list = []
            for v in self.network_interfaces:
                if isinstance(v, dict):
                    network_interfaces_list.append(v)
                else:
                    network_interfaces_list.append(v.to_dict())
            _dict['network_interfaces'] = network_interfaces_list
        if hasattr(self, 'primary_network_interface') and self.primary_network_interface is not None:
            if isinstance(self.primary_network_interface, dict):
                _dict['primary_network_interface'] = self.primary_network_interface
            else:
                _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 InstancePrototypeInstanceByVolume object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstancePrototypeInstanceByVolume') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstancePrototypeInstanceByVolume') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceTemplateIdentityByCRN(InstanceTemplateIdentity):
    """
    InstanceTemplateIdentityByCRN.

    :attr str crn: The CRN for this instance template.
    """

    def __init__(
        self,
        crn: str,
    ) -> None:
        """
        Initialize a InstanceTemplateIdentityByCRN object.

        :param str crn: The CRN for this instance template.
        """
        # pylint: disable=super-init-not-called
        self.crn = crn

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceTemplateIdentityByCRN':
        """Initialize a InstanceTemplateIdentityByCRN object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError('Required property \'crn\' not present in InstanceTemplateIdentityByCRN JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceTemplateIdentityByCRN object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceTemplateIdentityByCRN object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceTemplateIdentityByCRN') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceTemplateIdentityByCRN') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceTemplateIdentityByHref(InstanceTemplateIdentity):
    """
    InstanceTemplateIdentityByHref.

    :attr str href: The URL for this instance template.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a InstanceTemplateIdentityByHref object.

        :param str href: The URL for this instance template.
        """
        # pylint: disable=super-init-not-called
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceTemplateIdentityByHref':
        """Initialize a InstanceTemplateIdentityByHref object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in InstanceTemplateIdentityByHref JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceTemplateIdentityByHref object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceTemplateIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceTemplateIdentityByHref') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceTemplateIdentityByHref') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceTemplateIdentityById(InstanceTemplateIdentity):
    """
    InstanceTemplateIdentityById.

    :attr str id: The unique identifier for this instance template.
    """

    def __init__(
        self,
        id: str,
    ) -> None:
        """
        Initialize a InstanceTemplateIdentityById object.

        :param str id: The unique identifier for this instance template.
        """
        # pylint: disable=super-init-not-called
        self.id = id

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceTemplateIdentityById':
        """Initialize a InstanceTemplateIdentityById object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in InstanceTemplateIdentityById JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceTemplateIdentityById object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceTemplateIdentityById object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceTemplateIdentityById') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceTemplateIdentityById') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceTemplatePrototypeInstanceTemplateByCatalogOffering(InstanceTemplatePrototype):
    """
    Create an instance template that creates instances by using a catalog offering.

    :attr InstanceAvailabilityPolicyPrototype availability_policy: (optional) The
          availability policy to use for this virtual server instance.
    :attr InstanceDefaultTrustedProfilePrototype default_trusted_profile: (optional)
          The default trusted profile configuration to use for this virtual server
          instance
          This property's value is used when provisioning the virtual server instance, but
          not subsequently managed. Accordingly, it is reflected as an [instance
          initialization](https://cloud.ibm.com/apidocs/vpc#get-instance-initialization)
          property.
    :attr List[KeyIdentity] keys: (optional) The public SSH keys for the
          administrative user of the virtual server instance. 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.
          For Windows images, the keys of type `rsa` must be specified, and one will be
          selected to encrypt [the administrator
          password](https://cloud.ibm.com/apidocs/vpc#get-instance-initialization). Keys
          are optional for other images, but if no keys are specified, the instance will
          be inaccessible unless the specified image provides another means of access.
          This property's value is used when provisioning the virtual server instance, but
          not subsequently managed. Accordingly, it is reflected as an [instance
          initialization](https://cloud.ibm.com/apidocs/vpc#get-instance-initialization)
          property.
    :attr InstanceMetadataServicePrototype metadata_service: (optional)
    :attr str name: (optional) The name for this instance template. The name must
          not be used by another instance template in the region. If unspecified, the name
          will be a hyphenated list of randomly-selected words.
    :attr InstancePlacementTargetPrototype placement_target: (optional) The
          placement restrictions to use for the virtual server instance.
    :attr InstanceProfileIdentity profile: (optional) The
          [profile](https://cloud.ibm.com/docs/vpc?topic=vpc-profiles) to use for this
          virtual server instance.
          If unspecified, `bx2-2x8` will be used, but this default value is expected to
          change in the future.
    :attr ResourceGroupIdentity resource_group: (optional)
    :attr int total_volume_bandwidth: (optional) The amount of bandwidth (in
          megabits per second) allocated exclusively to instance storage volumes. An
          increase in this value will result in a corresponding decrease to
          `total_network_bandwidth`.
    :attr str user_data: (optional) [User
          data](https://cloud.ibm.com/docs/vpc?topic=vpc-user-data) to make available when
          setting up the virtual server instance.
    :attr List[VolumeAttachmentPrototype] volume_attachments: (optional) The
          additional volume attachments to create for the virtual server instance.
    :attr VPCIdentity vpc: (optional) The VPC this virtual server instance will
          reside in.
          If specified, it must match the VPC for the subnets of the instance network
          interfaces.
    :attr VolumeAttachmentPrototypeInstanceByImageContext boot_volume_attachment:
          (optional) The boot volume attachment to create for the virtual server instance.
    :attr InstanceCatalogOfferingPrototype catalog_offering: The
          [catalog](https://cloud.ibm.com/docs/account?topic=account-restrict-by-user)
          offering
          or offering version to use when provisioning this virtual server instance.
          If an offering is specified, the latest version of that offering will be used.
          The specified offering or offering version may be in a different account in the
          same
          [enterprise](https://cloud.ibm.com/docs/account?topic=account-what-is-enterprise),
          subject
          to IAM policies.
    :attr List[NetworkInterfacePrototype] network_interfaces: (optional) The
          additional instance network interfaces to create.
    :attr NetworkInterfacePrototype primary_network_interface: The primary instance
          network interface to create.
    :attr ZoneIdentity zone: The zone this virtual server instance will reside in.
    """

    def __init__(
        self,
        catalog_offering: 'InstanceCatalogOfferingPrototype',
        primary_network_interface: 'NetworkInterfacePrototype',
        zone: 'ZoneIdentity',
        *,
        availability_policy: 'InstanceAvailabilityPolicyPrototype' = None,
        default_trusted_profile: 'InstanceDefaultTrustedProfilePrototype' = None,
        keys: List['KeyIdentity'] = None,
        metadata_service: 'InstanceMetadataServicePrototype' = None,
        name: str = None,
        placement_target: 'InstancePlacementTargetPrototype' = None,
        profile: 'InstanceProfileIdentity' = None,
        resource_group: 'ResourceGroupIdentity' = None,
        total_volume_bandwidth: int = None,
        user_data: str = None,
        volume_attachments: List['VolumeAttachmentPrototype'] = None,
        vpc: 'VPCIdentity' = None,
        boot_volume_attachment: 'VolumeAttachmentPrototypeInstanceByImageContext' = None,
        network_interfaces: List['NetworkInterfacePrototype'] = None,
    ) -> None:
        """
        Initialize a InstanceTemplatePrototypeInstanceTemplateByCatalogOffering object.

        :param InstanceCatalogOfferingPrototype catalog_offering: The
               [catalog](https://cloud.ibm.com/docs/account?topic=account-restrict-by-user)
               offering
               or offering version to use when provisioning this virtual server instance.
               If an offering is specified, the latest version of that offering will be
               used.
               The specified offering or offering version may be in a different account in
               the same
               [enterprise](https://cloud.ibm.com/docs/account?topic=account-what-is-enterprise),
               subject
               to IAM policies.
        :param NetworkInterfacePrototype primary_network_interface: The primary
               instance network interface to create.
        :param ZoneIdentity zone: The zone this virtual server instance will reside
               in.
        :param InstanceAvailabilityPolicyPrototype availability_policy: (optional)
               The availability policy to use for this virtual server instance.
        :param InstanceDefaultTrustedProfilePrototype default_trusted_profile:
               (optional) The default trusted profile configuration to use for this
               virtual server instance
               This property's value is used when provisioning the virtual server
               instance, but not subsequently managed. Accordingly, it is reflected as an
               [instance
               initialization](https://cloud.ibm.com/apidocs/vpc#get-instance-initialization)
               property.
        :param List[KeyIdentity] keys: (optional) The public SSH keys for the
               administrative user of the virtual server instance. 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.
               For Windows images, the keys of type `rsa` must be specified, and one will
               be selected to encrypt [the administrator
               password](https://cloud.ibm.com/apidocs/vpc#get-instance-initialization).
               Keys are optional for other images, but if no keys are specified, the
               instance will be inaccessible unless the specified image provides another
               means of access.
               This property's value is used when provisioning the virtual server
               instance, but not subsequently managed. Accordingly, it is reflected as an
               [instance
               initialization](https://cloud.ibm.com/apidocs/vpc#get-instance-initialization)
               property.
        :param InstanceMetadataServicePrototype metadata_service: (optional)
        :param str name: (optional) The name for this instance template. The name
               must not be used by another instance template in the region. If
               unspecified, the name will be a hyphenated list of randomly-selected words.
        :param InstancePlacementTargetPrototype placement_target: (optional) The
               placement restrictions to use for the virtual server instance.
        :param InstanceProfileIdentity profile: (optional) The
               [profile](https://cloud.ibm.com/docs/vpc?topic=vpc-profiles) to use for
               this virtual server instance.
               If unspecified, `bx2-2x8` will be used, but this default value is expected
               to change in the future.
        :param ResourceGroupIdentity resource_group: (optional)
        :param int total_volume_bandwidth: (optional) The amount of bandwidth (in
               megabits per second) allocated exclusively to instance storage volumes. An
               increase in this value will result in a corresponding decrease to
               `total_network_bandwidth`.
        :param str user_data: (optional) [User
               data](https://cloud.ibm.com/docs/vpc?topic=vpc-user-data) to make available
               when setting up the virtual server instance.
        :param List[VolumeAttachmentPrototype] volume_attachments: (optional) The
               additional volume attachments to create for the virtual server instance.
        :param VPCIdentity vpc: (optional) The VPC this virtual server instance
               will reside in.
               If specified, it must match the VPC for the subnets of the instance network
               interfaces.
        :param VolumeAttachmentPrototypeInstanceByImageContext
               boot_volume_attachment: (optional) The boot volume attachment to create for
               the virtual server instance.
        :param List[NetworkInterfacePrototype] network_interfaces: (optional) The
               additional instance network interfaces to create.
        """
        # pylint: disable=super-init-not-called
        self.availability_policy = availability_policy
        self.default_trusted_profile = default_trusted_profile
        self.keys = keys
        self.metadata_service = metadata_service
        self.name = name
        self.placement_target = placement_target
        self.profile = profile
        self.resource_group = resource_group
        self.total_volume_bandwidth = total_volume_bandwidth
        self.user_data = user_data
        self.volume_attachments = volume_attachments
        self.vpc = vpc
        self.boot_volume_attachment = boot_volume_attachment
        self.catalog_offering = catalog_offering
        self.network_interfaces = network_interfaces
        self.primary_network_interface = primary_network_interface
        self.zone = zone

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceTemplatePrototypeInstanceTemplateByCatalogOffering':
        """Initialize a InstanceTemplatePrototypeInstanceTemplateByCatalogOffering object from a json dictionary."""
        args = {}
        if 'availability_policy' in _dict:
            args['availability_policy'] = InstanceAvailabilityPolicyPrototype.from_dict(_dict.get('availability_policy'))
        if 'default_trusted_profile' in _dict:
            args['default_trusted_profile'] = InstanceDefaultTrustedProfilePrototype.from_dict(_dict.get('default_trusted_profile'))
        if 'keys' in _dict:
            args['keys'] = _dict.get('keys')
        if 'metadata_service' in _dict:
            args['metadata_service'] = InstanceMetadataServicePrototype.from_dict(_dict.get('metadata_service'))
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        if 'placement_target' in _dict:
            args['placement_target'] = _dict.get('placement_target')
        if 'profile' in _dict:
            args['profile'] = _dict.get('profile')
        if 'resource_group' in _dict:
            args['resource_group'] = _dict.get('resource_group')
        if 'total_volume_bandwidth' in _dict:
            args['total_volume_bandwidth'] = _dict.get('total_volume_bandwidth')
        if 'user_data' in _dict:
            args['user_data'] = _dict.get('user_data')
        if 'volume_attachments' in _dict:
            args['volume_attachments'] = [VolumeAttachmentPrototype.from_dict(v) for v 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 'catalog_offering' in _dict:
            args['catalog_offering'] = _dict.get('catalog_offering')
        else:
            raise ValueError('Required property \'catalog_offering\' not present in InstanceTemplatePrototypeInstanceTemplateByCatalogOffering JSON')
        if 'network_interfaces' in _dict:
            args['network_interfaces'] = [NetworkInterfacePrototype.from_dict(v) for v in _dict.get('network_interfaces')]
        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 InstanceTemplatePrototypeInstanceTemplateByCatalogOffering JSON')
        if 'zone' in _dict:
            args['zone'] = _dict.get('zone')
        else:
            raise ValueError('Required property \'zone\' not present in InstanceTemplatePrototypeInstanceTemplateByCatalogOffering JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceTemplatePrototypeInstanceTemplateByCatalogOffering object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'availability_policy') and self.availability_policy is not None:
            if isinstance(self.availability_policy, dict):
                _dict['availability_policy'] = self.availability_policy
            else:
                _dict['availability_policy'] = self.availability_policy.to_dict()
        if hasattr(self, 'default_trusted_profile') and self.default_trusted_profile is not None:
            if isinstance(self.default_trusted_profile, dict):
                _dict['default_trusted_profile'] = self.default_trusted_profile
            else:
                _dict['default_trusted_profile'] = self.default_trusted_profile.to_dict()
        if hasattr(self, 'keys') and self.keys is not None:
            keys_list = []
            for v in self.keys:
                if isinstance(v, dict):
                    keys_list.append(v)
                else:
                    keys_list.append(v.to_dict())
            _dict['keys'] = keys_list
        if hasattr(self, 'metadata_service') and self.metadata_service is not None:
            if isinstance(self.metadata_service, dict):
                _dict['metadata_service'] = self.metadata_service
            else:
                _dict['metadata_service'] = self.metadata_service.to_dict()
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'placement_target') and self.placement_target is not None:
            if isinstance(self.placement_target, dict):
                _dict['placement_target'] = self.placement_target
            else:
                _dict['placement_target'] = self.placement_target.to_dict()
        if hasattr(self, 'profile') and self.profile is not None:
            if isinstance(self.profile, dict):
                _dict['profile'] = self.profile
            else:
                _dict['profile'] = self.profile.to_dict()
        if hasattr(self, 'resource_group') and self.resource_group is not None:
            if isinstance(self.resource_group, dict):
                _dict['resource_group'] = self.resource_group
            else:
                _dict['resource_group'] = self.resource_group.to_dict()
        if hasattr(self, 'total_volume_bandwidth') and self.total_volume_bandwidth is not None:
            _dict['total_volume_bandwidth'] = self.total_volume_bandwidth
        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:
            volume_attachments_list = []
            for v in self.volume_attachments:
                if isinstance(v, dict):
                    volume_attachments_list.append(v)
                else:
                    volume_attachments_list.append(v.to_dict())
            _dict['volume_attachments'] = volume_attachments_list
        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:
            if isinstance(self.boot_volume_attachment, dict):
                _dict['boot_volume_attachment'] = self.boot_volume_attachment
            else:
                _dict['boot_volume_attachment'] = self.boot_volume_attachment.to_dict()
        if hasattr(self, 'catalog_offering') and self.catalog_offering is not None:
            if isinstance(self.catalog_offering, dict):
                _dict['catalog_offering'] = self.catalog_offering
            else:
                _dict['catalog_offering'] = self.catalog_offering.to_dict()
        if hasattr(self, 'network_interfaces') and self.network_interfaces is not None:
            network_interfaces_list = []
            for v in self.network_interfaces:
                if isinstance(v, dict):
                    network_interfaces_list.append(v)
                else:
                    network_interfaces_list.append(v.to_dict())
            _dict['network_interfaces'] = network_interfaces_list
        if hasattr(self, 'primary_network_interface') and self.primary_network_interface is not None:
            if isinstance(self.primary_network_interface, dict):
                _dict['primary_network_interface'] = self.primary_network_interface
            else:
                _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 InstanceTemplatePrototypeInstanceTemplateByCatalogOffering object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceTemplatePrototypeInstanceTemplateByCatalogOffering') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceTemplatePrototypeInstanceTemplateByCatalogOffering') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceTemplatePrototypeInstanceTemplateByImage(InstanceTemplatePrototype):
    """
    Create an instance template that creates instances by using an image.

    :attr InstanceAvailabilityPolicyPrototype availability_policy: (optional) The
          availability policy to use for this virtual server instance.
    :attr InstanceDefaultTrustedProfilePrototype default_trusted_profile: (optional)
          The default trusted profile configuration to use for this virtual server
          instance
          This property's value is used when provisioning the virtual server instance, but
          not subsequently managed. Accordingly, it is reflected as an [instance
          initialization](https://cloud.ibm.com/apidocs/vpc#get-instance-initialization)
          property.
    :attr List[KeyIdentity] keys: (optional) The public SSH keys for the
          administrative user of the virtual server instance. 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.
          For Windows images, the keys of type `rsa` must be specified, and one will be
          selected to encrypt [the administrator
          password](https://cloud.ibm.com/apidocs/vpc#get-instance-initialization). Keys
          are optional for other images, but if no keys are specified, the instance will
          be inaccessible unless the specified image provides another means of access.
          This property's value is used when provisioning the virtual server instance, but
          not subsequently managed. Accordingly, it is reflected as an [instance
          initialization](https://cloud.ibm.com/apidocs/vpc#get-instance-initialization)
          property.
    :attr InstanceMetadataServicePrototype metadata_service: (optional)
    :attr str name: (optional) The name for this instance template. The name must
          not be used by another instance template in the region. If unspecified, the name
          will be a hyphenated list of randomly-selected words.
    :attr InstancePlacementTargetPrototype placement_target: (optional) The
          placement restrictions to use for the virtual server instance.
    :attr InstanceProfileIdentity profile: (optional) The
          [profile](https://cloud.ibm.com/docs/vpc?topic=vpc-profiles) to use for this
          virtual server instance.
          If unspecified, `bx2-2x8` will be used, but this default value is expected to
          change in the future.
    :attr ResourceGroupIdentity resource_group: (optional)
    :attr int total_volume_bandwidth: (optional) The amount of bandwidth (in
          megabits per second) allocated exclusively to instance storage volumes. An
          increase in this value will result in a corresponding decrease to
          `total_network_bandwidth`.
    :attr str user_data: (optional) [User
          data](https://cloud.ibm.com/docs/vpc?topic=vpc-user-data) to make available when
          setting up the virtual server instance.
    :attr List[VolumeAttachmentPrototype] volume_attachments: (optional) The
          additional volume attachments to create for the virtual server instance.
    :attr VPCIdentity vpc: (optional) The VPC this virtual server instance will
          reside in.
          If specified, it must match the VPC for the subnets of the instance network
          interfaces.
    :attr VolumeAttachmentPrototypeInstanceByImageContext boot_volume_attachment:
          (optional) The boot volume attachment to create for the virtual server instance.
    :attr ImageIdentity image: The image to use when provisioning the virtual server
          instance.
    :attr List[NetworkInterfacePrototype] network_interfaces: (optional) The
          additional instance network interfaces to create.
    :attr NetworkInterfacePrototype primary_network_interface: The primary instance
          network interface to create.
    :attr ZoneIdentity zone: The zone this virtual server instance will reside in.
    """

    def __init__(
        self,
        image: 'ImageIdentity',
        primary_network_interface: 'NetworkInterfacePrototype',
        zone: 'ZoneIdentity',
        *,
        availability_policy: 'InstanceAvailabilityPolicyPrototype' = None,
        default_trusted_profile: 'InstanceDefaultTrustedProfilePrototype' = None,
        keys: List['KeyIdentity'] = None,
        metadata_service: 'InstanceMetadataServicePrototype' = None,
        name: str = None,
        placement_target: 'InstancePlacementTargetPrototype' = None,
        profile: 'InstanceProfileIdentity' = None,
        resource_group: 'ResourceGroupIdentity' = None,
        total_volume_bandwidth: int = None,
        user_data: str = None,
        volume_attachments: List['VolumeAttachmentPrototype'] = None,
        vpc: 'VPCIdentity' = None,
        boot_volume_attachment: 'VolumeAttachmentPrototypeInstanceByImageContext' = None,
        network_interfaces: List['NetworkInterfacePrototype'] = None,
    ) -> None:
        """
        Initialize a InstanceTemplatePrototypeInstanceTemplateByImage object.

        :param ImageIdentity image: The image to use when provisioning the virtual
               server instance.
        :param NetworkInterfacePrototype primary_network_interface: The primary
               instance network interface to create.
        :param ZoneIdentity zone: The zone this virtual server instance will reside
               in.
        :param InstanceAvailabilityPolicyPrototype availability_policy: (optional)
               The availability policy to use for this virtual server instance.
        :param InstanceDefaultTrustedProfilePrototype default_trusted_profile:
               (optional) The default trusted profile configuration to use for this
               virtual server instance
               This property's value is used when provisioning the virtual server
               instance, but not subsequently managed. Accordingly, it is reflected as an
               [instance
               initialization](https://cloud.ibm.com/apidocs/vpc#get-instance-initialization)
               property.
        :param List[KeyIdentity] keys: (optional) The public SSH keys for the
               administrative user of the virtual server instance. 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.
               For Windows images, the keys of type `rsa` must be specified, and one will
               be selected to encrypt [the administrator
               password](https://cloud.ibm.com/apidocs/vpc#get-instance-initialization).
               Keys are optional for other images, but if no keys are specified, the
               instance will be inaccessible unless the specified image provides another
               means of access.
               This property's value is used when provisioning the virtual server
               instance, but not subsequently managed. Accordingly, it is reflected as an
               [instance
               initialization](https://cloud.ibm.com/apidocs/vpc#get-instance-initialization)
               property.
        :param InstanceMetadataServicePrototype metadata_service: (optional)
        :param str name: (optional) The name for this instance template. The name
               must not be used by another instance template in the region. If
               unspecified, the name will be a hyphenated list of randomly-selected words.
        :param InstancePlacementTargetPrototype placement_target: (optional) The
               placement restrictions to use for the virtual server instance.
        :param InstanceProfileIdentity profile: (optional) The
               [profile](https://cloud.ibm.com/docs/vpc?topic=vpc-profiles) to use for
               this virtual server instance.
               If unspecified, `bx2-2x8` will be used, but this default value is expected
               to change in the future.
        :param ResourceGroupIdentity resource_group: (optional)
        :param int total_volume_bandwidth: (optional) The amount of bandwidth (in
               megabits per second) allocated exclusively to instance storage volumes. An
               increase in this value will result in a corresponding decrease to
               `total_network_bandwidth`.
        :param str user_data: (optional) [User
               data](https://cloud.ibm.com/docs/vpc?topic=vpc-user-data) to make available
               when setting up the virtual server instance.
        :param List[VolumeAttachmentPrototype] volume_attachments: (optional) The
               additional volume attachments to create for the virtual server instance.
        :param VPCIdentity vpc: (optional) The VPC this virtual server instance
               will reside in.
               If specified, it must match the VPC for the subnets of the instance network
               interfaces.
        :param VolumeAttachmentPrototypeInstanceByImageContext
               boot_volume_attachment: (optional) The boot volume attachment to create for
               the virtual server instance.
        :param List[NetworkInterfacePrototype] network_interfaces: (optional) The
               additional instance network interfaces to create.
        """
        # pylint: disable=super-init-not-called
        self.availability_policy = availability_policy
        self.default_trusted_profile = default_trusted_profile
        self.keys = keys
        self.metadata_service = metadata_service
        self.name = name
        self.placement_target = placement_target
        self.profile = profile
        self.resource_group = resource_group
        self.total_volume_bandwidth = total_volume_bandwidth
        self.user_data = user_data
        self.volume_attachments = volume_attachments
        self.vpc = vpc
        self.boot_volume_attachment = boot_volume_attachment
        self.image = image
        self.network_interfaces = network_interfaces
        self.primary_network_interface = primary_network_interface
        self.zone = zone

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceTemplatePrototypeInstanceTemplateByImage':
        """Initialize a InstanceTemplatePrototypeInstanceTemplateByImage object from a json dictionary."""
        args = {}
        if 'availability_policy' in _dict:
            args['availability_policy'] = InstanceAvailabilityPolicyPrototype.from_dict(_dict.get('availability_policy'))
        if 'default_trusted_profile' in _dict:
            args['default_trusted_profile'] = InstanceDefaultTrustedProfilePrototype.from_dict(_dict.get('default_trusted_profile'))
        if 'keys' in _dict:
            args['keys'] = _dict.get('keys')
        if 'metadata_service' in _dict:
            args['metadata_service'] = InstanceMetadataServicePrototype.from_dict(_dict.get('metadata_service'))
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        if 'placement_target' in _dict:
            args['placement_target'] = _dict.get('placement_target')
        if 'profile' in _dict:
            args['profile'] = _dict.get('profile')
        if 'resource_group' in _dict:
            args['resource_group'] = _dict.get('resource_group')
        if 'total_volume_bandwidth' in _dict:
            args['total_volume_bandwidth'] = _dict.get('total_volume_bandwidth')
        if 'user_data' in _dict:
            args['user_data'] = _dict.get('user_data')
        if 'volume_attachments' in _dict:
            args['volume_attachments'] = [VolumeAttachmentPrototype.from_dict(v) for v 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 InstanceTemplatePrototypeInstanceTemplateByImage JSON')
        if 'network_interfaces' in _dict:
            args['network_interfaces'] = [NetworkInterfacePrototype.from_dict(v) for v in _dict.get('network_interfaces')]
        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 InstanceTemplatePrototypeInstanceTemplateByImage JSON')
        if 'zone' in _dict:
            args['zone'] = _dict.get('zone')
        else:
            raise ValueError('Required property \'zone\' not present in InstanceTemplatePrototypeInstanceTemplateByImage JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceTemplatePrototypeInstanceTemplateByImage object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'availability_policy') and self.availability_policy is not None:
            if isinstance(self.availability_policy, dict):
                _dict['availability_policy'] = self.availability_policy
            else:
                _dict['availability_policy'] = self.availability_policy.to_dict()
        if hasattr(self, 'default_trusted_profile') and self.default_trusted_profile is not None:
            if isinstance(self.default_trusted_profile, dict):
                _dict['default_trusted_profile'] = self.default_trusted_profile
            else:
                _dict['default_trusted_profile'] = self.default_trusted_profile.to_dict()
        if hasattr(self, 'keys') and self.keys is not None:
            keys_list = []
            for v in self.keys:
                if isinstance(v, dict):
                    keys_list.append(v)
                else:
                    keys_list.append(v.to_dict())
            _dict['keys'] = keys_list
        if hasattr(self, 'metadata_service') and self.metadata_service is not None:
            if isinstance(self.metadata_service, dict):
                _dict['metadata_service'] = self.metadata_service
            else:
                _dict['metadata_service'] = self.metadata_service.to_dict()
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'placement_target') and self.placement_target is not None:
            if isinstance(self.placement_target, dict):
                _dict['placement_target'] = self.placement_target
            else:
                _dict['placement_target'] = self.placement_target.to_dict()
        if hasattr(self, 'profile') and self.profile is not None:
            if isinstance(self.profile, dict):
                _dict['profile'] = self.profile
            else:
                _dict['profile'] = self.profile.to_dict()
        if hasattr(self, 'resource_group') and self.resource_group is not None:
            if isinstance(self.resource_group, dict):
                _dict['resource_group'] = self.resource_group
            else:
                _dict['resource_group'] = self.resource_group.to_dict()
        if hasattr(self, 'total_volume_bandwidth') and self.total_volume_bandwidth is not None:
            _dict['total_volume_bandwidth'] = self.total_volume_bandwidth
        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:
            volume_attachments_list = []
            for v in self.volume_attachments:
                if isinstance(v, dict):
                    volume_attachments_list.append(v)
                else:
                    volume_attachments_list.append(v.to_dict())
            _dict['volume_attachments'] = volume_attachments_list
        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:
            if isinstance(self.boot_volume_attachment, dict):
                _dict['boot_volume_attachment'] = self.boot_volume_attachment
            else:
                _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, 'network_interfaces') and self.network_interfaces is not None:
            network_interfaces_list = []
            for v in self.network_interfaces:
                if isinstance(v, dict):
                    network_interfaces_list.append(v)
                else:
                    network_interfaces_list.append(v.to_dict())
            _dict['network_interfaces'] = network_interfaces_list
        if hasattr(self, 'primary_network_interface') and self.primary_network_interface is not None:
            if isinstance(self.primary_network_interface, dict):
                _dict['primary_network_interface'] = self.primary_network_interface
            else:
                _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 InstanceTemplatePrototypeInstanceTemplateByImage object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceTemplatePrototypeInstanceTemplateByImage') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceTemplatePrototypeInstanceTemplateByImage') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceTemplatePrototypeInstanceTemplateBySourceSnapshot(InstanceTemplatePrototype):
    """
    Create an instance template that creates instances by using a snapshot.

    :attr InstanceAvailabilityPolicyPrototype availability_policy: (optional) The
          availability policy to use for this virtual server instance.
    :attr InstanceDefaultTrustedProfilePrototype default_trusted_profile: (optional)
          The default trusted profile configuration to use for this virtual server
          instance
          This property's value is used when provisioning the virtual server instance, but
          not subsequently managed. Accordingly, it is reflected as an [instance
          initialization](https://cloud.ibm.com/apidocs/vpc#get-instance-initialization)
          property.
    :attr List[KeyIdentity] keys: (optional) The public SSH keys for the
          administrative user of the virtual server instance. 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.
          For Windows images, the keys of type `rsa` must be specified, and one will be
          selected to encrypt [the administrator
          password](https://cloud.ibm.com/apidocs/vpc#get-instance-initialization). Keys
          are optional for other images, but if no keys are specified, the instance will
          be inaccessible unless the specified image provides another means of access.
          This property's value is used when provisioning the virtual server instance, but
          not subsequently managed. Accordingly, it is reflected as an [instance
          initialization](https://cloud.ibm.com/apidocs/vpc#get-instance-initialization)
          property.
    :attr InstanceMetadataServicePrototype metadata_service: (optional)
    :attr str name: (optional) The name for this instance template. The name must
          not be used by another instance template in the region. If unspecified, the name
          will be a hyphenated list of randomly-selected words.
    :attr InstancePlacementTargetPrototype placement_target: (optional) The
          placement restrictions to use for the virtual server instance.
    :attr InstanceProfileIdentity profile: (optional) The
          [profile](https://cloud.ibm.com/docs/vpc?topic=vpc-profiles) to use for this
          virtual server instance.
          If unspecified, `bx2-2x8` will be used, but this default value is expected to
          change in the future.
    :attr ResourceGroupIdentity resource_group: (optional)
    :attr int total_volume_bandwidth: (optional) The amount of bandwidth (in
          megabits per second) allocated exclusively to instance storage volumes. An
          increase in this value will result in a corresponding decrease to
          `total_network_bandwidth`.
    :attr str user_data: (optional) [User
          data](https://cloud.ibm.com/docs/vpc?topic=vpc-user-data) to make available when
          setting up the virtual server instance.
    :attr List[VolumeAttachmentPrototype] volume_attachments: (optional) The
          additional volume attachments to create for the virtual server instance.
    :attr VPCIdentity vpc: (optional) The VPC this virtual server instance will
          reside in.
          If specified, it must match the VPC for the subnets of the instance network
          interfaces.
    :attr VolumeAttachmentPrototypeInstanceBySourceSnapshotContext
          boot_volume_attachment: The boot volume attachment to create for the virtual
          server instance.
    :attr List[NetworkInterfacePrototype] network_interfaces: (optional) The
          additional instance network interfaces to create.
    :attr NetworkInterfacePrototype primary_network_interface: The primary instance
          network interface to create.
    :attr ZoneIdentity zone: The zone this virtual server instance will reside in.
    """

    def __init__(
        self,
        boot_volume_attachment: 'VolumeAttachmentPrototypeInstanceBySourceSnapshotContext',
        primary_network_interface: 'NetworkInterfacePrototype',
        zone: 'ZoneIdentity',
        *,
        availability_policy: 'InstanceAvailabilityPolicyPrototype' = None,
        default_trusted_profile: 'InstanceDefaultTrustedProfilePrototype' = None,
        keys: List['KeyIdentity'] = None,
        metadata_service: 'InstanceMetadataServicePrototype' = None,
        name: str = None,
        placement_target: 'InstancePlacementTargetPrototype' = None,
        profile: 'InstanceProfileIdentity' = None,
        resource_group: 'ResourceGroupIdentity' = None,
        total_volume_bandwidth: int = None,
        user_data: str = None,
        volume_attachments: List['VolumeAttachmentPrototype'] = None,
        vpc: 'VPCIdentity' = None,
        network_interfaces: List['NetworkInterfacePrototype'] = None,
    ) -> None:
        """
        Initialize a InstanceTemplatePrototypeInstanceTemplateBySourceSnapshot object.

        :param VolumeAttachmentPrototypeInstanceBySourceSnapshotContext
               boot_volume_attachment: The boot volume attachment to create for the
               virtual server instance.
        :param NetworkInterfacePrototype primary_network_interface: The primary
               instance network interface to create.
        :param ZoneIdentity zone: The zone this virtual server instance will reside
               in.
        :param InstanceAvailabilityPolicyPrototype availability_policy: (optional)
               The availability policy to use for this virtual server instance.
        :param InstanceDefaultTrustedProfilePrototype default_trusted_profile:
               (optional) The default trusted profile configuration to use for this
               virtual server instance
               This property's value is used when provisioning the virtual server
               instance, but not subsequently managed. Accordingly, it is reflected as an
               [instance
               initialization](https://cloud.ibm.com/apidocs/vpc#get-instance-initialization)
               property.
        :param List[KeyIdentity] keys: (optional) The public SSH keys for the
               administrative user of the virtual server instance. 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.
               For Windows images, the keys of type `rsa` must be specified, and one will
               be selected to encrypt [the administrator
               password](https://cloud.ibm.com/apidocs/vpc#get-instance-initialization).
               Keys are optional for other images, but if no keys are specified, the
               instance will be inaccessible unless the specified image provides another
               means of access.
               This property's value is used when provisioning the virtual server
               instance, but not subsequently managed. Accordingly, it is reflected as an
               [instance
               initialization](https://cloud.ibm.com/apidocs/vpc#get-instance-initialization)
               property.
        :param InstanceMetadataServicePrototype metadata_service: (optional)
        :param str name: (optional) The name for this instance template. The name
               must not be used by another instance template in the region. If
               unspecified, the name will be a hyphenated list of randomly-selected words.
        :param InstancePlacementTargetPrototype placement_target: (optional) The
               placement restrictions to use for the virtual server instance.
        :param InstanceProfileIdentity profile: (optional) The
               [profile](https://cloud.ibm.com/docs/vpc?topic=vpc-profiles) to use for
               this virtual server instance.
               If unspecified, `bx2-2x8` will be used, but this default value is expected
               to change in the future.
        :param ResourceGroupIdentity resource_group: (optional)
        :param int total_volume_bandwidth: (optional) The amount of bandwidth (in
               megabits per second) allocated exclusively to instance storage volumes. An
               increase in this value will result in a corresponding decrease to
               `total_network_bandwidth`.
        :param str user_data: (optional) [User
               data](https://cloud.ibm.com/docs/vpc?topic=vpc-user-data) to make available
               when setting up the virtual server instance.
        :param List[VolumeAttachmentPrototype] volume_attachments: (optional) The
               additional volume attachments to create for the virtual server instance.
        :param VPCIdentity vpc: (optional) The VPC this virtual server instance
               will reside in.
               If specified, it must match the VPC for the subnets of the instance network
               interfaces.
        :param List[NetworkInterfacePrototype] network_interfaces: (optional) The
               additional instance network interfaces to create.
        """
        # pylint: disable=super-init-not-called
        self.availability_policy = availability_policy
        self.default_trusted_profile = default_trusted_profile
        self.keys = keys
        self.metadata_service = metadata_service
        self.name = name
        self.placement_target = placement_target
        self.profile = profile
        self.resource_group = resource_group
        self.total_volume_bandwidth = total_volume_bandwidth
        self.user_data = user_data
        self.volume_attachments = volume_attachments
        self.vpc = vpc
        self.boot_volume_attachment = boot_volume_attachment
        self.network_interfaces = network_interfaces
        self.primary_network_interface = primary_network_interface
        self.zone = zone

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceTemplatePrototypeInstanceTemplateBySourceSnapshot':
        """Initialize a InstanceTemplatePrototypeInstanceTemplateBySourceSnapshot object from a json dictionary."""
        args = {}
        if 'availability_policy' in _dict:
            args['availability_policy'] = InstanceAvailabilityPolicyPrototype.from_dict(_dict.get('availability_policy'))
        if 'default_trusted_profile' in _dict:
            args['default_trusted_profile'] = InstanceDefaultTrustedProfilePrototype.from_dict(_dict.get('default_trusted_profile'))
        if 'keys' in _dict:
            args['keys'] = _dict.get('keys')
        if 'metadata_service' in _dict:
            args['metadata_service'] = InstanceMetadataServicePrototype.from_dict(_dict.get('metadata_service'))
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        if 'placement_target' in _dict:
            args['placement_target'] = _dict.get('placement_target')
        if 'profile' in _dict:
            args['profile'] = _dict.get('profile')
        if 'resource_group' in _dict:
            args['resource_group'] = _dict.get('resource_group')
        if 'total_volume_bandwidth' in _dict:
            args['total_volume_bandwidth'] = _dict.get('total_volume_bandwidth')
        if 'user_data' in _dict:
            args['user_data'] = _dict.get('user_data')
        if 'volume_attachments' in _dict:
            args['volume_attachments'] = [VolumeAttachmentPrototype.from_dict(v) for v in _dict.get('volume_attachments')]
        if 'vpc' in _dict:
            args['vpc'] = _dict.get('vpc')
        if 'boot_volume_attachment' in _dict:
            args['boot_volume_attachment'] = VolumeAttachmentPrototypeInstanceBySourceSnapshotContext.from_dict(_dict.get('boot_volume_attachment'))
        else:
            raise ValueError('Required property \'boot_volume_attachment\' not present in InstanceTemplatePrototypeInstanceTemplateBySourceSnapshot JSON')
        if 'network_interfaces' in _dict:
            args['network_interfaces'] = [NetworkInterfacePrototype.from_dict(v) for v in _dict.get('network_interfaces')]
        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 InstanceTemplatePrototypeInstanceTemplateBySourceSnapshot JSON')
        if 'zone' in _dict:
            args['zone'] = _dict.get('zone')
        else:
            raise ValueError('Required property \'zone\' not present in InstanceTemplatePrototypeInstanceTemplateBySourceSnapshot JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceTemplatePrototypeInstanceTemplateBySourceSnapshot object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'availability_policy') and self.availability_policy is not None:
            if isinstance(self.availability_policy, dict):
                _dict['availability_policy'] = self.availability_policy
            else:
                _dict['availability_policy'] = self.availability_policy.to_dict()
        if hasattr(self, 'default_trusted_profile') and self.default_trusted_profile is not None:
            if isinstance(self.default_trusted_profile, dict):
                _dict['default_trusted_profile'] = self.default_trusted_profile
            else:
                _dict['default_trusted_profile'] = self.default_trusted_profile.to_dict()
        if hasattr(self, 'keys') and self.keys is not None:
            keys_list = []
            for v in self.keys:
                if isinstance(v, dict):
                    keys_list.append(v)
                else:
                    keys_list.append(v.to_dict())
            _dict['keys'] = keys_list
        if hasattr(self, 'metadata_service') and self.metadata_service is not None:
            if isinstance(self.metadata_service, dict):
                _dict['metadata_service'] = self.metadata_service
            else:
                _dict['metadata_service'] = self.metadata_service.to_dict()
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'placement_target') and self.placement_target is not None:
            if isinstance(self.placement_target, dict):
                _dict['placement_target'] = self.placement_target
            else:
                _dict['placement_target'] = self.placement_target.to_dict()
        if hasattr(self, 'profile') and self.profile is not None:
            if isinstance(self.profile, dict):
                _dict['profile'] = self.profile
            else:
                _dict['profile'] = self.profile.to_dict()
        if hasattr(self, 'resource_group') and self.resource_group is not None:
            if isinstance(self.resource_group, dict):
                _dict['resource_group'] = self.resource_group
            else:
                _dict['resource_group'] = self.resource_group.to_dict()
        if hasattr(self, 'total_volume_bandwidth') and self.total_volume_bandwidth is not None:
            _dict['total_volume_bandwidth'] = self.total_volume_bandwidth
        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:
            volume_attachments_list = []
            for v in self.volume_attachments:
                if isinstance(v, dict):
                    volume_attachments_list.append(v)
                else:
                    volume_attachments_list.append(v.to_dict())
            _dict['volume_attachments'] = volume_attachments_list
        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:
            if isinstance(self.boot_volume_attachment, dict):
                _dict['boot_volume_attachment'] = self.boot_volume_attachment
            else:
                _dict['boot_volume_attachment'] = self.boot_volume_attachment.to_dict()
        if hasattr(self, 'network_interfaces') and self.network_interfaces is not None:
            network_interfaces_list = []
            for v in self.network_interfaces:
                if isinstance(v, dict):
                    network_interfaces_list.append(v)
                else:
                    network_interfaces_list.append(v.to_dict())
            _dict['network_interfaces'] = network_interfaces_list
        if hasattr(self, 'primary_network_interface') and self.primary_network_interface is not None:
            if isinstance(self.primary_network_interface, dict):
                _dict['primary_network_interface'] = self.primary_network_interface
            else:
                _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 InstanceTemplatePrototypeInstanceTemplateBySourceSnapshot object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceTemplatePrototypeInstanceTemplateBySourceSnapshot') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceTemplatePrototypeInstanceTemplateBySourceSnapshot') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceTemplatePrototypeInstanceTemplateBySourceTemplate(InstanceTemplatePrototype):
    """
    Create an instance template from an existing instance template.

    :attr InstanceAvailabilityPolicyPrototype availability_policy: (optional) The
          availability policy to use for this virtual server instance.
    :attr InstanceDefaultTrustedProfilePrototype default_trusted_profile: (optional)
          The default trusted profile configuration to use for this virtual server
          instance
          This property's value is used when provisioning the virtual server instance, but
          not subsequently managed. Accordingly, it is reflected as an [instance
          initialization](https://cloud.ibm.com/apidocs/vpc#get-instance-initialization)
          property.
    :attr List[KeyIdentity] keys: (optional) The public SSH keys for the
          administrative user of the virtual server instance. 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.
          For Windows images, the keys of type `rsa` must be specified, and one will be
          selected to encrypt [the administrator
          password](https://cloud.ibm.com/apidocs/vpc#get-instance-initialization). Keys
          are optional for other images, but if no keys are specified, the instance will
          be inaccessible unless the specified image provides another means of access.
          This property's value is used when provisioning the virtual server instance, but
          not subsequently managed. Accordingly, it is reflected as an [instance
          initialization](https://cloud.ibm.com/apidocs/vpc#get-instance-initialization)
          property.
    :attr InstanceMetadataServicePrototype metadata_service: (optional)
    :attr str name: (optional) The name for this instance template. The name must
          not be used by another instance template in the region. If unspecified, the name
          will be a hyphenated list of randomly-selected words.
    :attr InstancePlacementTargetPrototype placement_target: (optional) The
          placement restrictions to use for the virtual server instance.
    :attr InstanceProfileIdentity profile: (optional) The
          [profile](https://cloud.ibm.com/docs/vpc?topic=vpc-profiles) to use for this
          virtual server instance.
          If unspecified, `bx2-2x8` will be used, but this default value is expected to
          change in the future.
    :attr ResourceGroupIdentity resource_group: (optional)
    :attr int total_volume_bandwidth: (optional) The amount of bandwidth (in
          megabits per second) allocated exclusively to instance storage volumes. An
          increase in this value will result in a corresponding decrease to
          `total_network_bandwidth`.
    :attr str user_data: (optional) [User
          data](https://cloud.ibm.com/docs/vpc?topic=vpc-user-data) to make available when
          setting up the virtual server instance.
    :attr List[VolumeAttachmentPrototype] volume_attachments: (optional) The
          additional volume attachments to create for the virtual server instance.
    :attr VPCIdentity vpc: (optional) The VPC this virtual server instance will
          reside in.
          If specified, it must match the VPC for the subnets of the instance network
          interfaces.
    :attr VolumeAttachmentPrototypeInstanceByImageContext boot_volume_attachment:
          (optional) The boot volume attachment to create for the virtual server instance.
    :attr InstanceCatalogOfferingPrototype catalog_offering: (optional) The
          [catalog](https://cloud.ibm.com/docs/account?topic=account-restrict-by-user)
          offering version to use when provisioning this virtual server instance.
          If an offering is specified, the latest version of that offering will be used.
          The specified offering or offering version may be in a different account,
          subject to
          IAM policies.
          If specified, `image` must not be specified, and `source_template` must not have
          `image` specified.
    :attr ImageIdentity image: (optional) The image to use when provisioning the
          virtual server instance.
    :attr List[NetworkInterfacePrototype] network_interfaces: (optional) The
          additional instance network interfaces to create.
    :attr NetworkInterfacePrototype primary_network_interface: (optional) The
          primary instance network interface to create.
    :attr InstanceTemplateIdentity source_template: The template to create this
          virtual server instance from.
    :attr ZoneIdentity zone: (optional) The zone this virtual server instance will
          reside in.
    """

    def __init__(
        self,
        source_template: 'InstanceTemplateIdentity',
        *,
        availability_policy: 'InstanceAvailabilityPolicyPrototype' = None,
        default_trusted_profile: 'InstanceDefaultTrustedProfilePrototype' = None,
        keys: List['KeyIdentity'] = None,
        metadata_service: 'InstanceMetadataServicePrototype' = None,
        name: str = None,
        placement_target: 'InstancePlacementTargetPrototype' = None,
        profile: 'InstanceProfileIdentity' = None,
        resource_group: 'ResourceGroupIdentity' = None,
        total_volume_bandwidth: int = None,
        user_data: str = None,
        volume_attachments: List['VolumeAttachmentPrototype'] = None,
        vpc: 'VPCIdentity' = None,
        boot_volume_attachment: 'VolumeAttachmentPrototypeInstanceByImageContext' = None,
        catalog_offering: 'InstanceCatalogOfferingPrototype' = None,
        image: 'ImageIdentity' = None,
        network_interfaces: List['NetworkInterfacePrototype'] = None,
        primary_network_interface: 'NetworkInterfacePrototype' = None,
        zone: 'ZoneIdentity' = None,
    ) -> None:
        """
        Initialize a InstanceTemplatePrototypeInstanceTemplateBySourceTemplate object.

        :param InstanceTemplateIdentity source_template: The template to create
               this virtual server instance from.
        :param InstanceAvailabilityPolicyPrototype availability_policy: (optional)
               The availability policy to use for this virtual server instance.
        :param InstanceDefaultTrustedProfilePrototype default_trusted_profile:
               (optional) The default trusted profile configuration to use for this
               virtual server instance
               This property's value is used when provisioning the virtual server
               instance, but not subsequently managed. Accordingly, it is reflected as an
               [instance
               initialization](https://cloud.ibm.com/apidocs/vpc#get-instance-initialization)
               property.
        :param List[KeyIdentity] keys: (optional) The public SSH keys for the
               administrative user of the virtual server instance. 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.
               For Windows images, the keys of type `rsa` must be specified, and one will
               be selected to encrypt [the administrator
               password](https://cloud.ibm.com/apidocs/vpc#get-instance-initialization).
               Keys are optional for other images, but if no keys are specified, the
               instance will be inaccessible unless the specified image provides another
               means of access.
               This property's value is used when provisioning the virtual server
               instance, but not subsequently managed. Accordingly, it is reflected as an
               [instance
               initialization](https://cloud.ibm.com/apidocs/vpc#get-instance-initialization)
               property.
        :param InstanceMetadataServicePrototype metadata_service: (optional)
        :param str name: (optional) The name for this instance template. The name
               must not be used by another instance template in the region. If
               unspecified, the name will be a hyphenated list of randomly-selected words.
        :param InstancePlacementTargetPrototype placement_target: (optional) The
               placement restrictions to use for the virtual server instance.
        :param InstanceProfileIdentity profile: (optional) The
               [profile](https://cloud.ibm.com/docs/vpc?topic=vpc-profiles) to use for
               this virtual server instance.
               If unspecified, `bx2-2x8` will be used, but this default value is expected
               to change in the future.
        :param ResourceGroupIdentity resource_group: (optional)
        :param int total_volume_bandwidth: (optional) The amount of bandwidth (in
               megabits per second) allocated exclusively to instance storage volumes. An
               increase in this value will result in a corresponding decrease to
               `total_network_bandwidth`.
        :param str user_data: (optional) [User
               data](https://cloud.ibm.com/docs/vpc?topic=vpc-user-data) to make available
               when setting up the virtual server instance.
        :param List[VolumeAttachmentPrototype] volume_attachments: (optional) The
               additional volume attachments to create for the virtual server instance.
        :param VPCIdentity vpc: (optional) The VPC this virtual server instance
               will reside in.
               If specified, it must match the VPC for the subnets of the instance network
               interfaces.
        :param VolumeAttachmentPrototypeInstanceByImageContext
               boot_volume_attachment: (optional) The boot volume attachment to create for
               the virtual server instance.
        :param InstanceCatalogOfferingPrototype catalog_offering: (optional) The
               [catalog](https://cloud.ibm.com/docs/account?topic=account-restrict-by-user)
               offering version to use when provisioning this virtual server instance.
               If an offering is specified, the latest version of that offering will be
               used.
               The specified offering or offering version may be in a different account,
               subject to
               IAM policies.
               If specified, `image` must not be specified, and `source_template` must not
               have
               `image` specified.
        :param ImageIdentity image: (optional) The image to use when provisioning
               the virtual server instance.
        :param List[NetworkInterfacePrototype] network_interfaces: (optional) The
               additional instance network interfaces to create.
        :param NetworkInterfacePrototype primary_network_interface: (optional) The
               primary instance network interface to create.
        :param ZoneIdentity zone: (optional) The zone this virtual server instance
               will reside in.
        """
        # pylint: disable=super-init-not-called
        self.availability_policy = availability_policy
        self.default_trusted_profile = default_trusted_profile
        self.keys = keys
        self.metadata_service = metadata_service
        self.name = name
        self.placement_target = placement_target
        self.profile = profile
        self.resource_group = resource_group
        self.total_volume_bandwidth = total_volume_bandwidth
        self.user_data = user_data
        self.volume_attachments = volume_attachments
        self.vpc = vpc
        self.boot_volume_attachment = boot_volume_attachment
        self.catalog_offering = catalog_offering
        self.image = image
        self.network_interfaces = network_interfaces
        self.primary_network_interface = primary_network_interface
        self.source_template = source_template
        self.zone = zone

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceTemplatePrototypeInstanceTemplateBySourceTemplate':
        """Initialize a InstanceTemplatePrototypeInstanceTemplateBySourceTemplate object from a json dictionary."""
        args = {}
        if 'availability_policy' in _dict:
            args['availability_policy'] = InstanceAvailabilityPolicyPrototype.from_dict(_dict.get('availability_policy'))
        if 'default_trusted_profile' in _dict:
            args['default_trusted_profile'] = InstanceDefaultTrustedProfilePrototype.from_dict(_dict.get('default_trusted_profile'))
        if 'keys' in _dict:
            args['keys'] = _dict.get('keys')
        if 'metadata_service' in _dict:
            args['metadata_service'] = InstanceMetadataServicePrototype.from_dict(_dict.get('metadata_service'))
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        if 'placement_target' in _dict:
            args['placement_target'] = _dict.get('placement_target')
        if 'profile' in _dict:
            args['profile'] = _dict.get('profile')
        if 'resource_group' in _dict:
            args['resource_group'] = _dict.get('resource_group')
        if 'total_volume_bandwidth' in _dict:
            args['total_volume_bandwidth'] = _dict.get('total_volume_bandwidth')
        if 'user_data' in _dict:
            args['user_data'] = _dict.get('user_data')
        if 'volume_attachments' in _dict:
            args['volume_attachments'] = [VolumeAttachmentPrototype.from_dict(v) for v 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 'catalog_offering' in _dict:
            args['catalog_offering'] = _dict.get('catalog_offering')
        if 'image' in _dict:
            args['image'] = _dict.get('image')
        if 'network_interfaces' in _dict:
            args['network_interfaces'] = [NetworkInterfacePrototype.from_dict(v) for v in _dict.get('network_interfaces')]
        if 'primary_network_interface' in _dict:
            args['primary_network_interface'] = NetworkInterfacePrototype.from_dict(_dict.get('primary_network_interface'))
        if 'source_template' in _dict:
            args['source_template'] = _dict.get('source_template')
        else:
            raise ValueError('Required property \'source_template\' not present in InstanceTemplatePrototypeInstanceTemplateBySourceTemplate JSON')
        if 'zone' in _dict:
            args['zone'] = _dict.get('zone')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceTemplatePrototypeInstanceTemplateBySourceTemplate object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'availability_policy') and self.availability_policy is not None:
            if isinstance(self.availability_policy, dict):
                _dict['availability_policy'] = self.availability_policy
            else:
                _dict['availability_policy'] = self.availability_policy.to_dict()
        if hasattr(self, 'default_trusted_profile') and self.default_trusted_profile is not None:
            if isinstance(self.default_trusted_profile, dict):
                _dict['default_trusted_profile'] = self.default_trusted_profile
            else:
                _dict['default_trusted_profile'] = self.default_trusted_profile.to_dict()
        if hasattr(self, 'keys') and self.keys is not None:
            keys_list = []
            for v in self.keys:
                if isinstance(v, dict):
                    keys_list.append(v)
                else:
                    keys_list.append(v.to_dict())
            _dict['keys'] = keys_list
        if hasattr(self, 'metadata_service') and self.metadata_service is not None:
            if isinstance(self.metadata_service, dict):
                _dict['metadata_service'] = self.metadata_service
            else:
                _dict['metadata_service'] = self.metadata_service.to_dict()
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'placement_target') and self.placement_target is not None:
            if isinstance(self.placement_target, dict):
                _dict['placement_target'] = self.placement_target
            else:
                _dict['placement_target'] = self.placement_target.to_dict()
        if hasattr(self, 'profile') and self.profile is not None:
            if isinstance(self.profile, dict):
                _dict['profile'] = self.profile
            else:
                _dict['profile'] = self.profile.to_dict()
        if hasattr(self, 'resource_group') and self.resource_group is not None:
            if isinstance(self.resource_group, dict):
                _dict['resource_group'] = self.resource_group
            else:
                _dict['resource_group'] = self.resource_group.to_dict()
        if hasattr(self, 'total_volume_bandwidth') and self.total_volume_bandwidth is not None:
            _dict['total_volume_bandwidth'] = self.total_volume_bandwidth
        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:
            volume_attachments_list = []
            for v in self.volume_attachments:
                if isinstance(v, dict):
                    volume_attachments_list.append(v)
                else:
                    volume_attachments_list.append(v.to_dict())
            _dict['volume_attachments'] = volume_attachments_list
        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:
            if isinstance(self.boot_volume_attachment, dict):
                _dict['boot_volume_attachment'] = self.boot_volume_attachment
            else:
                _dict['boot_volume_attachment'] = self.boot_volume_attachment.to_dict()
        if hasattr(self, 'catalog_offering') and self.catalog_offering is not None:
            if isinstance(self.catalog_offering, dict):
                _dict['catalog_offering'] = self.catalog_offering
            else:
                _dict['catalog_offering'] = self.catalog_offering.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, 'network_interfaces') and self.network_interfaces is not None:
            network_interfaces_list = []
            for v in self.network_interfaces:
                if isinstance(v, dict):
                    network_interfaces_list.append(v)
                else:
                    network_interfaces_list.append(v.to_dict())
            _dict['network_interfaces'] = network_interfaces_list
        if hasattr(self, 'primary_network_interface') and self.primary_network_interface is not None:
            if isinstance(self.primary_network_interface, dict):
                _dict['primary_network_interface'] = self.primary_network_interface
            else:
                _dict['primary_network_interface'] = self.primary_network_interface.to_dict()
        if hasattr(self, 'source_template') and self.source_template is not None:
            if isinstance(self.source_template, dict):
                _dict['source_template'] = self.source_template
            else:
                _dict['source_template'] = self.source_template.to_dict()
        if hasattr(self, 'zone') and self.zone is not None:
            if isinstance(self.zone, dict):
                _dict['zone'] = self.zone
            else:
                _dict['zone'] = self.zone.to_dict()
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceTemplatePrototypeInstanceTemplateBySourceTemplate object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceTemplatePrototypeInstanceTemplateBySourceTemplate') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceTemplatePrototypeInstanceTemplateBySourceTemplate') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceTemplateInstanceByCatalogOfferingInstanceTemplateContext(InstanceTemplate):
    """
    Create an instance by using a catalog offering.

    :attr InstanceAvailabilityPolicyPrototype availability_policy: (optional) The
          availability policy to use for this virtual server instance.
    :attr datetime created_at: The date and time that the instance template was
          created.
    :attr str crn: The CRN for this instance template.
    :attr InstanceDefaultTrustedProfilePrototype default_trusted_profile: (optional)
          The default trusted profile configuration to use for this virtual server
          instance
          This property's value is used when provisioning the virtual server instance, but
          not subsequently managed. Accordingly, it is reflected as an [instance
          initialization](https://cloud.ibm.com/apidocs/vpc#get-instance-initialization)
          property.
    :attr str href: The URL for this instance template.
    :attr str id: The unique identifier for this instance template.
    :attr List[KeyIdentity] keys: (optional) The public SSH keys for the
          administrative user of the virtual server instance. 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.
          For Windows images, the keys of type `rsa` must be specified, and one will be
          selected to encrypt [the administrator
          password](https://cloud.ibm.com/apidocs/vpc#get-instance-initialization). Keys
          are optional for other images, but if no keys are specified, the instance will
          be inaccessible unless the specified image provides another means of access.
          This property's value is used when provisioning the virtual server instance, but
          not subsequently managed. Accordingly, it is reflected as an [instance
          initialization](https://cloud.ibm.com/apidocs/vpc#get-instance-initialization)
          property.
    :attr InstanceMetadataServicePrototype metadata_service: (optional)
    :attr str name: The name for this instance template. The name is unique across
          all instance templates in the region.
    :attr InstancePlacementTargetPrototype placement_target: (optional) The
          placement restrictions to use for the virtual server instance.
    :attr InstanceProfileIdentity profile: (optional) The
          [profile](https://cloud.ibm.com/docs/vpc?topic=vpc-profiles) to use for this
          virtual server instance.
          If unspecified, `bx2-2x8` will be used, but this default value is expected to
          change in the future.
    :attr ResourceGroupReference resource_group: The resource group for this
          instance template.
    :attr int total_volume_bandwidth: (optional) The amount of bandwidth (in
          megabits per second) allocated exclusively to instance storage volumes. An
          increase in this value will result in a corresponding decrease to
          `total_network_bandwidth`.
    :attr str user_data: (optional) [User
          data](https://cloud.ibm.com/docs/vpc?topic=vpc-user-data) to make available when
          setting up the virtual server instance.
    :attr List[VolumeAttachmentPrototype] volume_attachments: (optional) The
          additional volume attachments to create for the virtual server instance.
    :attr VPCIdentity vpc: (optional) The VPC this virtual server instance will
          reside in.
          If specified, it must match the VPC for the subnets of the instance network
          interfaces.
    :attr VolumeAttachmentPrototypeInstanceByImageContext boot_volume_attachment:
          (optional) The boot volume attachment to create for the virtual server instance.
    :attr InstanceCatalogOfferingPrototype catalog_offering: The
          [catalog](https://cloud.ibm.com/docs/account?topic=account-restrict-by-user)
          offering
          or offering version to use when provisioning this virtual server instance.
          If an offering is specified, the latest version of that offering will be used.
          The specified offering or offering version may be in a different account in the
          same
          [enterprise](https://cloud.ibm.com/docs/account?topic=account-what-is-enterprise),
          subject
          to IAM policies.
    :attr List[NetworkInterfacePrototype] network_interfaces: (optional) The
          additional instance network interfaces to create.
    :attr NetworkInterfacePrototype primary_network_interface: (optional) The
          primary instance network interface to create.
    :attr ZoneIdentity zone: The zone this virtual server instance will reside in.
    """

    def __init__(
        self,
        created_at: datetime,
        crn: str,
        href: str,
        id: str,
        name: str,
        resource_group: 'ResourceGroupReference',
        catalog_offering: 'InstanceCatalogOfferingPrototype',
        zone: 'ZoneIdentity',
        *,
        availability_policy: 'InstanceAvailabilityPolicyPrototype' = None,
        default_trusted_profile: 'InstanceDefaultTrustedProfilePrototype' = None,
        keys: List['KeyIdentity'] = None,
        metadata_service: 'InstanceMetadataServicePrototype' = None,
        placement_target: 'InstancePlacementTargetPrototype' = None,
        profile: 'InstanceProfileIdentity' = None,
        total_volume_bandwidth: int = None,
        user_data: str = None,
        volume_attachments: List['VolumeAttachmentPrototype'] = None,
        vpc: 'VPCIdentity' = None,
        boot_volume_attachment: 'VolumeAttachmentPrototypeInstanceByImageContext' = None,
        network_interfaces: List['NetworkInterfacePrototype'] = None,
        primary_network_interface: 'NetworkInterfacePrototype' = None,
    ) -> None:
        """
        Initialize a InstanceTemplateInstanceByCatalogOfferingInstanceTemplateContext object.

        :param datetime created_at: The date and time that the instance template
               was created.
        :param str crn: The CRN for this instance template.
        :param str href: The URL for this instance template.
        :param str id: The unique identifier for this instance template.
        :param str name: The name for this instance template. The name is unique
               across all instance templates in the region.
        :param ResourceGroupReference resource_group: The resource group for this
               instance template.
        :param InstanceCatalogOfferingPrototype catalog_offering: The
               [catalog](https://cloud.ibm.com/docs/account?topic=account-restrict-by-user)
               offering
               or offering version to use when provisioning this virtual server instance.
               If an offering is specified, the latest version of that offering will be
               used.
               The specified offering or offering version may be in a different account in
               the same
               [enterprise](https://cloud.ibm.com/docs/account?topic=account-what-is-enterprise),
               subject
               to IAM policies.
        :param ZoneIdentity zone: The zone this virtual server instance will reside
               in.
        :param InstanceAvailabilityPolicyPrototype availability_policy: (optional)
               The availability policy to use for this virtual server instance.
        :param InstanceDefaultTrustedProfilePrototype default_trusted_profile:
               (optional) The default trusted profile configuration to use for this
               virtual server instance
               This property's value is used when provisioning the virtual server
               instance, but not subsequently managed. Accordingly, it is reflected as an
               [instance
               initialization](https://cloud.ibm.com/apidocs/vpc#get-instance-initialization)
               property.
        :param List[KeyIdentity] keys: (optional) The public SSH keys for the
               administrative user of the virtual server instance. 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.
               For Windows images, the keys of type `rsa` must be specified, and one will
               be selected to encrypt [the administrator
               password](https://cloud.ibm.com/apidocs/vpc#get-instance-initialization).
               Keys are optional for other images, but if no keys are specified, the
               instance will be inaccessible unless the specified image provides another
               means of access.
               This property's value is used when provisioning the virtual server
               instance, but not subsequently managed. Accordingly, it is reflected as an
               [instance
               initialization](https://cloud.ibm.com/apidocs/vpc#get-instance-initialization)
               property.
        :param InstanceMetadataServicePrototype metadata_service: (optional)
        :param InstancePlacementTargetPrototype placement_target: (optional) The
               placement restrictions to use for the virtual server instance.
        :param InstanceProfileIdentity profile: (optional) The
               [profile](https://cloud.ibm.com/docs/vpc?topic=vpc-profiles) to use for
               this virtual server instance.
               If unspecified, `bx2-2x8` will be used, but this default value is expected
               to change in the future.
        :param int total_volume_bandwidth: (optional) The amount of bandwidth (in
               megabits per second) allocated exclusively to instance storage volumes. An
               increase in this value will result in a corresponding decrease to
               `total_network_bandwidth`.
        :param str user_data: (optional) [User
               data](https://cloud.ibm.com/docs/vpc?topic=vpc-user-data) to make available
               when setting up the virtual server instance.
        :param List[VolumeAttachmentPrototype] volume_attachments: (optional) The
               additional volume attachments to create for the virtual server instance.
        :param VPCIdentity vpc: (optional) The VPC this virtual server instance
               will reside in.
               If specified, it must match the VPC for the subnets of the instance network
               interfaces.
        :param VolumeAttachmentPrototypeInstanceByImageContext
               boot_volume_attachment: (optional) The boot volume attachment to create for
               the virtual server instance.
        :param List[NetworkInterfacePrototype] network_interfaces: (optional) The
               additional instance network interfaces to create.
        :param NetworkInterfacePrototype primary_network_interface: (optional) The
               primary instance network interface to create.
        """
        # pylint: disable=super-init-not-called
        self.availability_policy = availability_policy
        self.created_at = created_at
        self.crn = crn
        self.default_trusted_profile = default_trusted_profile
        self.href = href
        self.id = id
        self.keys = keys
        self.metadata_service = metadata_service
        self.name = name
        self.placement_target = placement_target
        self.profile = profile
        self.resource_group = resource_group
        self.total_volume_bandwidth = total_volume_bandwidth
        self.user_data = user_data
        self.volume_attachments = volume_attachments
        self.vpc = vpc
        self.boot_volume_attachment = boot_volume_attachment
        self.catalog_offering = catalog_offering
        self.network_interfaces = network_interfaces
        self.primary_network_interface = primary_network_interface
        self.zone = zone

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceTemplateInstanceByCatalogOfferingInstanceTemplateContext':
        """Initialize a InstanceTemplateInstanceByCatalogOfferingInstanceTemplateContext object from a json dictionary."""
        args = {}
        if 'availability_policy' in _dict:
            args['availability_policy'] = InstanceAvailabilityPolicyPrototype.from_dict(_dict.get('availability_policy'))
        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 InstanceTemplateInstanceByCatalogOfferingInstanceTemplateContext JSON')
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError('Required property \'crn\' not present in InstanceTemplateInstanceByCatalogOfferingInstanceTemplateContext JSON')
        if 'default_trusted_profile' in _dict:
            args['default_trusted_profile'] = InstanceDefaultTrustedProfilePrototype.from_dict(_dict.get('default_trusted_profile'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in InstanceTemplateInstanceByCatalogOfferingInstanceTemplateContext JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in InstanceTemplateInstanceByCatalogOfferingInstanceTemplateContext JSON')
        if 'keys' in _dict:
            args['keys'] = _dict.get('keys')
        if 'metadata_service' in _dict:
            args['metadata_service'] = InstanceMetadataServicePrototype.from_dict(_dict.get('metadata_service'))
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in InstanceTemplateInstanceByCatalogOfferingInstanceTemplateContext JSON')
        if 'placement_target' in _dict:
            args['placement_target'] = _dict.get('placement_target')
        if 'profile' in _dict:
            args['profile'] = _dict.get('profile')
        if 'resource_group' in _dict:
            args['resource_group'] = ResourceGroupReference.from_dict(_dict.get('resource_group'))
        else:
            raise ValueError('Required property \'resource_group\' not present in InstanceTemplateInstanceByCatalogOfferingInstanceTemplateContext JSON')
        if 'total_volume_bandwidth' in _dict:
            args['total_volume_bandwidth'] = _dict.get('total_volume_bandwidth')
        if 'user_data' in _dict:
            args['user_data'] = _dict.get('user_data')
        if 'volume_attachments' in _dict:
            args['volume_attachments'] = [VolumeAttachmentPrototype.from_dict(v) for v 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 'catalog_offering' in _dict:
            args['catalog_offering'] = _dict.get('catalog_offering')
        else:
            raise ValueError('Required property \'catalog_offering\' not present in InstanceTemplateInstanceByCatalogOfferingInstanceTemplateContext JSON')
        if 'network_interfaces' in _dict:
            args['network_interfaces'] = [NetworkInterfacePrototype.from_dict(v) for v in _dict.get('network_interfaces')]
        if 'primary_network_interface' in _dict:
            args['primary_network_interface'] = NetworkInterfacePrototype.from_dict(_dict.get('primary_network_interface'))
        if 'zone' in _dict:
            args['zone'] = _dict.get('zone')
        else:
            raise ValueError('Required property \'zone\' not present in InstanceTemplateInstanceByCatalogOfferingInstanceTemplateContext JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceTemplateInstanceByCatalogOfferingInstanceTemplateContext object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'availability_policy') and self.availability_policy is not None:
            if isinstance(self.availability_policy, dict):
                _dict['availability_policy'] = self.availability_policy
            else:
                _dict['availability_policy'] = self.availability_policy.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, 'default_trusted_profile') and self.default_trusted_profile is not None:
            if isinstance(self.default_trusted_profile, dict):
                _dict['default_trusted_profile'] = self.default_trusted_profile
            else:
                _dict['default_trusted_profile'] = self.default_trusted_profile.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, 'keys') and self.keys is not None:
            keys_list = []
            for v in self.keys:
                if isinstance(v, dict):
                    keys_list.append(v)
                else:
                    keys_list.append(v.to_dict())
            _dict['keys'] = keys_list
        if hasattr(self, 'metadata_service') and self.metadata_service is not None:
            if isinstance(self.metadata_service, dict):
                _dict['metadata_service'] = self.metadata_service
            else:
                _dict['metadata_service'] = self.metadata_service.to_dict()
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'placement_target') and self.placement_target is not None:
            if isinstance(self.placement_target, dict):
                _dict['placement_target'] = self.placement_target
            else:
                _dict['placement_target'] = self.placement_target.to_dict()
        if hasattr(self, 'profile') and self.profile is not None:
            if isinstance(self.profile, dict):
                _dict['profile'] = self.profile
            else:
                _dict['profile'] = self.profile.to_dict()
        if hasattr(self, 'resource_group') and self.resource_group is not None:
            if isinstance(self.resource_group, dict):
                _dict['resource_group'] = self.resource_group
            else:
                _dict['resource_group'] = self.resource_group.to_dict()
        if hasattr(self, 'total_volume_bandwidth') and self.total_volume_bandwidth is not None:
            _dict['total_volume_bandwidth'] = self.total_volume_bandwidth
        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:
            volume_attachments_list = []
            for v in self.volume_attachments:
                if isinstance(v, dict):
                    volume_attachments_list.append(v)
                else:
                    volume_attachments_list.append(v.to_dict())
            _dict['volume_attachments'] = volume_attachments_list
        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:
            if isinstance(self.boot_volume_attachment, dict):
                _dict['boot_volume_attachment'] = self.boot_volume_attachment
            else:
                _dict['boot_volume_attachment'] = self.boot_volume_attachment.to_dict()
        if hasattr(self, 'catalog_offering') and self.catalog_offering is not None:
            if isinstance(self.catalog_offering, dict):
                _dict['catalog_offering'] = self.catalog_offering
            else:
                _dict['catalog_offering'] = self.catalog_offering.to_dict()
        if hasattr(self, 'network_interfaces') and self.network_interfaces is not None:
            network_interfaces_list = []
            for v in self.network_interfaces:
                if isinstance(v, dict):
                    network_interfaces_list.append(v)
                else:
                    network_interfaces_list.append(v.to_dict())
            _dict['network_interfaces'] = network_interfaces_list
        if hasattr(self, 'primary_network_interface') and self.primary_network_interface is not None:
            if isinstance(self.primary_network_interface, dict):
                _dict['primary_network_interface'] = self.primary_network_interface
            else:
                _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 InstanceTemplateInstanceByCatalogOfferingInstanceTemplateContext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceTemplateInstanceByCatalogOfferingInstanceTemplateContext') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceTemplateInstanceByCatalogOfferingInstanceTemplateContext') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceTemplateInstanceByImageInstanceTemplateContext(InstanceTemplate):
    """
    Create an instance by using an image.

    :attr InstanceAvailabilityPolicyPrototype availability_policy: (optional) The
          availability policy to use for this virtual server instance.
    :attr datetime created_at: The date and time that the instance template was
          created.
    :attr str crn: The CRN for this instance template.
    :attr InstanceDefaultTrustedProfilePrototype default_trusted_profile: (optional)
          The default trusted profile configuration to use for this virtual server
          instance
          This property's value is used when provisioning the virtual server instance, but
          not subsequently managed. Accordingly, it is reflected as an [instance
          initialization](https://cloud.ibm.com/apidocs/vpc#get-instance-initialization)
          property.
    :attr str href: The URL for this instance template.
    :attr str id: The unique identifier for this instance template.
    :attr List[KeyIdentity] keys: (optional) The public SSH keys for the
          administrative user of the virtual server instance. 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.
          For Windows images, the keys of type `rsa` must be specified, and one will be
          selected to encrypt [the administrator
          password](https://cloud.ibm.com/apidocs/vpc#get-instance-initialization). Keys
          are optional for other images, but if no keys are specified, the instance will
          be inaccessible unless the specified image provides another means of access.
          This property's value is used when provisioning the virtual server instance, but
          not subsequently managed. Accordingly, it is reflected as an [instance
          initialization](https://cloud.ibm.com/apidocs/vpc#get-instance-initialization)
          property.
    :attr InstanceMetadataServicePrototype metadata_service: (optional)
    :attr str name: The name for this instance template. The name is unique across
          all instance templates in the region.
    :attr InstancePlacementTargetPrototype placement_target: (optional) The
          placement restrictions to use for the virtual server instance.
    :attr InstanceProfileIdentity profile: (optional) The
          [profile](https://cloud.ibm.com/docs/vpc?topic=vpc-profiles) to use for this
          virtual server instance.
          If unspecified, `bx2-2x8` will be used, but this default value is expected to
          change in the future.
    :attr ResourceGroupReference resource_group: The resource group for this
          instance template.
    :attr int total_volume_bandwidth: (optional) The amount of bandwidth (in
          megabits per second) allocated exclusively to instance storage volumes. An
          increase in this value will result in a corresponding decrease to
          `total_network_bandwidth`.
    :attr str user_data: (optional) [User
          data](https://cloud.ibm.com/docs/vpc?topic=vpc-user-data) to make available when
          setting up the virtual server instance.
    :attr List[VolumeAttachmentPrototype] volume_attachments: (optional) The
          additional volume attachments to create for the virtual server instance.
    :attr VPCIdentity vpc: (optional) The VPC this virtual server instance will
          reside in.
          If specified, it must match the VPC for the subnets of the instance network
          interfaces.
    :attr VolumeAttachmentPrototypeInstanceByImageContext boot_volume_attachment:
          (optional) The boot volume attachment to create for the virtual server instance.
    :attr ImageIdentity image: The image to use when provisioning the virtual server
          instance.
    :attr List[NetworkInterfacePrototype] network_interfaces: (optional) The
          additional instance network interfaces to create.
    :attr NetworkInterfacePrototype primary_network_interface: (optional) The
          primary instance network interface to create.
    :attr ZoneIdentity zone: The zone this virtual server instance will reside in.
    """

    def __init__(
        self,
        created_at: datetime,
        crn: str,
        href: str,
        id: str,
        name: str,
        resource_group: 'ResourceGroupReference',
        image: 'ImageIdentity',
        zone: 'ZoneIdentity',
        *,
        availability_policy: 'InstanceAvailabilityPolicyPrototype' = None,
        default_trusted_profile: 'InstanceDefaultTrustedProfilePrototype' = None,
        keys: List['KeyIdentity'] = None,
        metadata_service: 'InstanceMetadataServicePrototype' = None,
        placement_target: 'InstancePlacementTargetPrototype' = None,
        profile: 'InstanceProfileIdentity' = None,
        total_volume_bandwidth: int = None,
        user_data: str = None,
        volume_attachments: List['VolumeAttachmentPrototype'] = None,
        vpc: 'VPCIdentity' = None,
        boot_volume_attachment: 'VolumeAttachmentPrototypeInstanceByImageContext' = None,
        network_interfaces: List['NetworkInterfacePrototype'] = None,
        primary_network_interface: 'NetworkInterfacePrototype' = None,
    ) -> None:
        """
        Initialize a InstanceTemplateInstanceByImageInstanceTemplateContext object.

        :param datetime created_at: The date and time that the instance template
               was created.
        :param str crn: The CRN for this instance template.
        :param str href: The URL for this instance template.
        :param str id: The unique identifier for this instance template.
        :param str name: The name for this instance template. The name is unique
               across all instance templates in the region.
        :param ResourceGroupReference resource_group: The resource group for this
               instance template.
        :param ImageIdentity image: The image to use when provisioning the virtual
               server instance.
        :param ZoneIdentity zone: The zone this virtual server instance will reside
               in.
        :param InstanceAvailabilityPolicyPrototype availability_policy: (optional)
               The availability policy to use for this virtual server instance.
        :param InstanceDefaultTrustedProfilePrototype default_trusted_profile:
               (optional) The default trusted profile configuration to use for this
               virtual server instance
               This property's value is used when provisioning the virtual server
               instance, but not subsequently managed. Accordingly, it is reflected as an
               [instance
               initialization](https://cloud.ibm.com/apidocs/vpc#get-instance-initialization)
               property.
        :param List[KeyIdentity] keys: (optional) The public SSH keys for the
               administrative user of the virtual server instance. 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.
               For Windows images, the keys of type `rsa` must be specified, and one will
               be selected to encrypt [the administrator
               password](https://cloud.ibm.com/apidocs/vpc#get-instance-initialization).
               Keys are optional for other images, but if no keys are specified, the
               instance will be inaccessible unless the specified image provides another
               means of access.
               This property's value is used when provisioning the virtual server
               instance, but not subsequently managed. Accordingly, it is reflected as an
               [instance
               initialization](https://cloud.ibm.com/apidocs/vpc#get-instance-initialization)
               property.
        :param InstanceMetadataServicePrototype metadata_service: (optional)
        :param InstancePlacementTargetPrototype placement_target: (optional) The
               placement restrictions to use for the virtual server instance.
        :param InstanceProfileIdentity profile: (optional) The
               [profile](https://cloud.ibm.com/docs/vpc?topic=vpc-profiles) to use for
               this virtual server instance.
               If unspecified, `bx2-2x8` will be used, but this default value is expected
               to change in the future.
        :param int total_volume_bandwidth: (optional) The amount of bandwidth (in
               megabits per second) allocated exclusively to instance storage volumes. An
               increase in this value will result in a corresponding decrease to
               `total_network_bandwidth`.
        :param str user_data: (optional) [User
               data](https://cloud.ibm.com/docs/vpc?topic=vpc-user-data) to make available
               when setting up the virtual server instance.
        :param List[VolumeAttachmentPrototype] volume_attachments: (optional) The
               additional volume attachments to create for the virtual server instance.
        :param VPCIdentity vpc: (optional) The VPC this virtual server instance
               will reside in.
               If specified, it must match the VPC for the subnets of the instance network
               interfaces.
        :param VolumeAttachmentPrototypeInstanceByImageContext
               boot_volume_attachment: (optional) The boot volume attachment to create for
               the virtual server instance.
        :param List[NetworkInterfacePrototype] network_interfaces: (optional) The
               additional instance network interfaces to create.
        :param NetworkInterfacePrototype primary_network_interface: (optional) The
               primary instance network interface to create.
        """
        # pylint: disable=super-init-not-called
        self.availability_policy = availability_policy
        self.created_at = created_at
        self.crn = crn
        self.default_trusted_profile = default_trusted_profile
        self.href = href
        self.id = id
        self.keys = keys
        self.metadata_service = metadata_service
        self.name = name
        self.placement_target = placement_target
        self.profile = profile
        self.resource_group = resource_group
        self.total_volume_bandwidth = total_volume_bandwidth
        self.user_data = user_data
        self.volume_attachments = volume_attachments
        self.vpc = vpc
        self.boot_volume_attachment = boot_volume_attachment
        self.image = image
        self.network_interfaces = network_interfaces
        self.primary_network_interface = primary_network_interface
        self.zone = zone

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceTemplateInstanceByImageInstanceTemplateContext':
        """Initialize a InstanceTemplateInstanceByImageInstanceTemplateContext object from a json dictionary."""
        args = {}
        if 'availability_policy' in _dict:
            args['availability_policy'] = InstanceAvailabilityPolicyPrototype.from_dict(_dict.get('availability_policy'))
        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 InstanceTemplateInstanceByImageInstanceTemplateContext JSON')
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError('Required property \'crn\' not present in InstanceTemplateInstanceByImageInstanceTemplateContext JSON')
        if 'default_trusted_profile' in _dict:
            args['default_trusted_profile'] = InstanceDefaultTrustedProfilePrototype.from_dict(_dict.get('default_trusted_profile'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in InstanceTemplateInstanceByImageInstanceTemplateContext JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in InstanceTemplateInstanceByImageInstanceTemplateContext JSON')
        if 'keys' in _dict:
            args['keys'] = _dict.get('keys')
        if 'metadata_service' in _dict:
            args['metadata_service'] = InstanceMetadataServicePrototype.from_dict(_dict.get('metadata_service'))
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in InstanceTemplateInstanceByImageInstanceTemplateContext JSON')
        if 'placement_target' in _dict:
            args['placement_target'] = _dict.get('placement_target')
        if 'profile' in _dict:
            args['profile'] = _dict.get('profile')
        if 'resource_group' in _dict:
            args['resource_group'] = ResourceGroupReference.from_dict(_dict.get('resource_group'))
        else:
            raise ValueError('Required property \'resource_group\' not present in InstanceTemplateInstanceByImageInstanceTemplateContext JSON')
        if 'total_volume_bandwidth' in _dict:
            args['total_volume_bandwidth'] = _dict.get('total_volume_bandwidth')
        if 'user_data' in _dict:
            args['user_data'] = _dict.get('user_data')
        if 'volume_attachments' in _dict:
            args['volume_attachments'] = [VolumeAttachmentPrototype.from_dict(v) for v 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 InstanceTemplateInstanceByImageInstanceTemplateContext JSON')
        if 'network_interfaces' in _dict:
            args['network_interfaces'] = [NetworkInterfacePrototype.from_dict(v) for v in _dict.get('network_interfaces')]
        if 'primary_network_interface' in _dict:
            args['primary_network_interface'] = NetworkInterfacePrototype.from_dict(_dict.get('primary_network_interface'))
        if 'zone' in _dict:
            args['zone'] = _dict.get('zone')
        else:
            raise ValueError('Required property \'zone\' not present in InstanceTemplateInstanceByImageInstanceTemplateContext JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceTemplateInstanceByImageInstanceTemplateContext object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'availability_policy') and self.availability_policy is not None:
            if isinstance(self.availability_policy, dict):
                _dict['availability_policy'] = self.availability_policy
            else:
                _dict['availability_policy'] = self.availability_policy.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, 'default_trusted_profile') and self.default_trusted_profile is not None:
            if isinstance(self.default_trusted_profile, dict):
                _dict['default_trusted_profile'] = self.default_trusted_profile
            else:
                _dict['default_trusted_profile'] = self.default_trusted_profile.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, 'keys') and self.keys is not None:
            keys_list = []
            for v in self.keys:
                if isinstance(v, dict):
                    keys_list.append(v)
                else:
                    keys_list.append(v.to_dict())
            _dict['keys'] = keys_list
        if hasattr(self, 'metadata_service') and self.metadata_service is not None:
            if isinstance(self.metadata_service, dict):
                _dict['metadata_service'] = self.metadata_service
            else:
                _dict['metadata_service'] = self.metadata_service.to_dict()
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'placement_target') and self.placement_target is not None:
            if isinstance(self.placement_target, dict):
                _dict['placement_target'] = self.placement_target
            else:
                _dict['placement_target'] = self.placement_target.to_dict()
        if hasattr(self, 'profile') and self.profile is not None:
            if isinstance(self.profile, dict):
                _dict['profile'] = self.profile
            else:
                _dict['profile'] = self.profile.to_dict()
        if hasattr(self, 'resource_group') and self.resource_group is not None:
            if isinstance(self.resource_group, dict):
                _dict['resource_group'] = self.resource_group
            else:
                _dict['resource_group'] = self.resource_group.to_dict()
        if hasattr(self, 'total_volume_bandwidth') and self.total_volume_bandwidth is not None:
            _dict['total_volume_bandwidth'] = self.total_volume_bandwidth
        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:
            volume_attachments_list = []
            for v in self.volume_attachments:
                if isinstance(v, dict):
                    volume_attachments_list.append(v)
                else:
                    volume_attachments_list.append(v.to_dict())
            _dict['volume_attachments'] = volume_attachments_list
        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:
            if isinstance(self.boot_volume_attachment, dict):
                _dict['boot_volume_attachment'] = self.boot_volume_attachment
            else:
                _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, 'network_interfaces') and self.network_interfaces is not None:
            network_interfaces_list = []
            for v in self.network_interfaces:
                if isinstance(v, dict):
                    network_interfaces_list.append(v)
                else:
                    network_interfaces_list.append(v.to_dict())
            _dict['network_interfaces'] = network_interfaces_list
        if hasattr(self, 'primary_network_interface') and self.primary_network_interface is not None:
            if isinstance(self.primary_network_interface, dict):
                _dict['primary_network_interface'] = self.primary_network_interface
            else:
                _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 InstanceTemplateInstanceByImageInstanceTemplateContext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceTemplateInstanceByImageInstanceTemplateContext') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceTemplateInstanceByImageInstanceTemplateContext') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceTemplateInstanceBySourceSnapshotInstanceTemplateContext(InstanceTemplate):
    """
    Create an instance by using a snapshot.

    :attr InstanceAvailabilityPolicyPrototype availability_policy: (optional) The
          availability policy to use for this virtual server instance.
    :attr datetime created_at: The date and time that the instance template was
          created.
    :attr str crn: The CRN for this instance template.
    :attr InstanceDefaultTrustedProfilePrototype default_trusted_profile: (optional)
          The default trusted profile configuration to use for this virtual server
          instance
          This property's value is used when provisioning the virtual server instance, but
          not subsequently managed. Accordingly, it is reflected as an [instance
          initialization](https://cloud.ibm.com/apidocs/vpc#get-instance-initialization)
          property.
    :attr str href: The URL for this instance template.
    :attr str id: The unique identifier for this instance template.
    :attr List[KeyIdentity] keys: (optional) The public SSH keys for the
          administrative user of the virtual server instance. 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.
          For Windows images, the keys of type `rsa` must be specified, and one will be
          selected to encrypt [the administrator
          password](https://cloud.ibm.com/apidocs/vpc#get-instance-initialization). Keys
          are optional for other images, but if no keys are specified, the instance will
          be inaccessible unless the specified image provides another means of access.
          This property's value is used when provisioning the virtual server instance, but
          not subsequently managed. Accordingly, it is reflected as an [instance
          initialization](https://cloud.ibm.com/apidocs/vpc#get-instance-initialization)
          property.
    :attr InstanceMetadataServicePrototype metadata_service: (optional)
    :attr str name: The name for this instance template. The name is unique across
          all instance templates in the region.
    :attr InstancePlacementTargetPrototype placement_target: (optional) The
          placement restrictions to use for the virtual server instance.
    :attr InstanceProfileIdentity profile: (optional) The
          [profile](https://cloud.ibm.com/docs/vpc?topic=vpc-profiles) to use for this
          virtual server instance.
          If unspecified, `bx2-2x8` will be used, but this default value is expected to
          change in the future.
    :attr ResourceGroupReference resource_group: The resource group for this
          instance template.
    :attr int total_volume_bandwidth: (optional) The amount of bandwidth (in
          megabits per second) allocated exclusively to instance storage volumes. An
          increase in this value will result in a corresponding decrease to
          `total_network_bandwidth`.
    :attr str user_data: (optional) [User
          data](https://cloud.ibm.com/docs/vpc?topic=vpc-user-data) to make available when
          setting up the virtual server instance.
    :attr List[VolumeAttachmentPrototype] volume_attachments: (optional) The
          additional volume attachments to create for the virtual server instance.
    :attr VPCIdentity vpc: (optional) The VPC this virtual server instance will
          reside in.
          If specified, it must match the VPC for the subnets of the instance network
          interfaces.
    :attr VolumeAttachmentPrototypeInstanceBySourceSnapshotContext
          boot_volume_attachment: The boot volume attachment to create for the virtual
          server instance.
    :attr List[NetworkInterfacePrototype] network_interfaces: (optional) The
          additional instance network interfaces to create.
    :attr NetworkInterfacePrototype primary_network_interface: (optional) The
          primary instance network interface to create.
    :attr ZoneIdentity zone: The zone this virtual server instance will reside in.
    """

    def __init__(
        self,
        created_at: datetime,
        crn: str,
        href: str,
        id: str,
        name: str,
        resource_group: 'ResourceGroupReference',
        boot_volume_attachment: 'VolumeAttachmentPrototypeInstanceBySourceSnapshotContext',
        zone: 'ZoneIdentity',
        *,
        availability_policy: 'InstanceAvailabilityPolicyPrototype' = None,
        default_trusted_profile: 'InstanceDefaultTrustedProfilePrototype' = None,
        keys: List['KeyIdentity'] = None,
        metadata_service: 'InstanceMetadataServicePrototype' = None,
        placement_target: 'InstancePlacementTargetPrototype' = None,
        profile: 'InstanceProfileIdentity' = None,
        total_volume_bandwidth: int = None,
        user_data: str = None,
        volume_attachments: List['VolumeAttachmentPrototype'] = None,
        vpc: 'VPCIdentity' = None,
        network_interfaces: List['NetworkInterfacePrototype'] = None,
        primary_network_interface: 'NetworkInterfacePrototype' = None,
    ) -> None:
        """
        Initialize a InstanceTemplateInstanceBySourceSnapshotInstanceTemplateContext object.

        :param datetime created_at: The date and time that the instance template
               was created.
        :param str crn: The CRN for this instance template.
        :param str href: The URL for this instance template.
        :param str id: The unique identifier for this instance template.
        :param str name: The name for this instance template. The name is unique
               across all instance templates in the region.
        :param ResourceGroupReference resource_group: The resource group for this
               instance template.
        :param VolumeAttachmentPrototypeInstanceBySourceSnapshotContext
               boot_volume_attachment: The boot volume attachment to create for the
               virtual server instance.
        :param ZoneIdentity zone: The zone this virtual server instance will reside
               in.
        :param InstanceAvailabilityPolicyPrototype availability_policy: (optional)
               The availability policy to use for this virtual server instance.
        :param InstanceDefaultTrustedProfilePrototype default_trusted_profile:
               (optional) The default trusted profile configuration to use for this
               virtual server instance
               This property's value is used when provisioning the virtual server
               instance, but not subsequently managed. Accordingly, it is reflected as an
               [instance
               initialization](https://cloud.ibm.com/apidocs/vpc#get-instance-initialization)
               property.
        :param List[KeyIdentity] keys: (optional) The public SSH keys for the
               administrative user of the virtual server instance. 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.
               For Windows images, the keys of type `rsa` must be specified, and one will
               be selected to encrypt [the administrator
               password](https://cloud.ibm.com/apidocs/vpc#get-instance-initialization).
               Keys are optional for other images, but if no keys are specified, the
               instance will be inaccessible unless the specified image provides another
               means of access.
               This property's value is used when provisioning the virtual server
               instance, but not subsequently managed. Accordingly, it is reflected as an
               [instance
               initialization](https://cloud.ibm.com/apidocs/vpc#get-instance-initialization)
               property.
        :param InstanceMetadataServicePrototype metadata_service: (optional)
        :param InstancePlacementTargetPrototype placement_target: (optional) The
               placement restrictions to use for the virtual server instance.
        :param InstanceProfileIdentity profile: (optional) The
               [profile](https://cloud.ibm.com/docs/vpc?topic=vpc-profiles) to use for
               this virtual server instance.
               If unspecified, `bx2-2x8` will be used, but this default value is expected
               to change in the future.
        :param int total_volume_bandwidth: (optional) The amount of bandwidth (in
               megabits per second) allocated exclusively to instance storage volumes. An
               increase in this value will result in a corresponding decrease to
               `total_network_bandwidth`.
        :param str user_data: (optional) [User
               data](https://cloud.ibm.com/docs/vpc?topic=vpc-user-data) to make available
               when setting up the virtual server instance.
        :param List[VolumeAttachmentPrototype] volume_attachments: (optional) The
               additional volume attachments to create for the virtual server instance.
        :param VPCIdentity vpc: (optional) The VPC this virtual server instance
               will reside in.
               If specified, it must match the VPC for the subnets of the instance network
               interfaces.
        :param List[NetworkInterfacePrototype] network_interfaces: (optional) The
               additional instance network interfaces to create.
        :param NetworkInterfacePrototype primary_network_interface: (optional) The
               primary instance network interface to create.
        """
        # pylint: disable=super-init-not-called
        self.availability_policy = availability_policy
        self.created_at = created_at
        self.crn = crn
        self.default_trusted_profile = default_trusted_profile
        self.href = href
        self.id = id
        self.keys = keys
        self.metadata_service = metadata_service
        self.name = name
        self.placement_target = placement_target
        self.profile = profile
        self.resource_group = resource_group
        self.total_volume_bandwidth = total_volume_bandwidth
        self.user_data = user_data
        self.volume_attachments = volume_attachments
        self.vpc = vpc
        self.boot_volume_attachment = boot_volume_attachment
        self.network_interfaces = network_interfaces
        self.primary_network_interface = primary_network_interface
        self.zone = zone

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceTemplateInstanceBySourceSnapshotInstanceTemplateContext':
        """Initialize a InstanceTemplateInstanceBySourceSnapshotInstanceTemplateContext object from a json dictionary."""
        args = {}
        if 'availability_policy' in _dict:
            args['availability_policy'] = InstanceAvailabilityPolicyPrototype.from_dict(_dict.get('availability_policy'))
        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 InstanceTemplateInstanceBySourceSnapshotInstanceTemplateContext JSON')
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError('Required property \'crn\' not present in InstanceTemplateInstanceBySourceSnapshotInstanceTemplateContext JSON')
        if 'default_trusted_profile' in _dict:
            args['default_trusted_profile'] = InstanceDefaultTrustedProfilePrototype.from_dict(_dict.get('default_trusted_profile'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in InstanceTemplateInstanceBySourceSnapshotInstanceTemplateContext JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in InstanceTemplateInstanceBySourceSnapshotInstanceTemplateContext JSON')
        if 'keys' in _dict:
            args['keys'] = _dict.get('keys')
        if 'metadata_service' in _dict:
            args['metadata_service'] = InstanceMetadataServicePrototype.from_dict(_dict.get('metadata_service'))
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in InstanceTemplateInstanceBySourceSnapshotInstanceTemplateContext JSON')
        if 'placement_target' in _dict:
            args['placement_target'] = _dict.get('placement_target')
        if 'profile' in _dict:
            args['profile'] = _dict.get('profile')
        if 'resource_group' in _dict:
            args['resource_group'] = ResourceGroupReference.from_dict(_dict.get('resource_group'))
        else:
            raise ValueError('Required property \'resource_group\' not present in InstanceTemplateInstanceBySourceSnapshotInstanceTemplateContext JSON')
        if 'total_volume_bandwidth' in _dict:
            args['total_volume_bandwidth'] = _dict.get('total_volume_bandwidth')
        if 'user_data' in _dict:
            args['user_data'] = _dict.get('user_data')
        if 'volume_attachments' in _dict:
            args['volume_attachments'] = [VolumeAttachmentPrototype.from_dict(v) for v in _dict.get('volume_attachments')]
        if 'vpc' in _dict:
            args['vpc'] = _dict.get('vpc')
        if 'boot_volume_attachment' in _dict:
            args['boot_volume_attachment'] = VolumeAttachmentPrototypeInstanceBySourceSnapshotContext.from_dict(_dict.get('boot_volume_attachment'))
        else:
            raise ValueError('Required property \'boot_volume_attachment\' not present in InstanceTemplateInstanceBySourceSnapshotInstanceTemplateContext JSON')
        if 'network_interfaces' in _dict:
            args['network_interfaces'] = [NetworkInterfacePrototype.from_dict(v) for v in _dict.get('network_interfaces')]
        if 'primary_network_interface' in _dict:
            args['primary_network_interface'] = NetworkInterfacePrototype.from_dict(_dict.get('primary_network_interface'))
        if 'zone' in _dict:
            args['zone'] = _dict.get('zone')
        else:
            raise ValueError('Required property \'zone\' not present in InstanceTemplateInstanceBySourceSnapshotInstanceTemplateContext JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceTemplateInstanceBySourceSnapshotInstanceTemplateContext object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'availability_policy') and self.availability_policy is not None:
            if isinstance(self.availability_policy, dict):
                _dict['availability_policy'] = self.availability_policy
            else:
                _dict['availability_policy'] = self.availability_policy.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, 'default_trusted_profile') and self.default_trusted_profile is not None:
            if isinstance(self.default_trusted_profile, dict):
                _dict['default_trusted_profile'] = self.default_trusted_profile
            else:
                _dict['default_trusted_profile'] = self.default_trusted_profile.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, 'keys') and self.keys is not None:
            keys_list = []
            for v in self.keys:
                if isinstance(v, dict):
                    keys_list.append(v)
                else:
                    keys_list.append(v.to_dict())
            _dict['keys'] = keys_list
        if hasattr(self, 'metadata_service') and self.metadata_service is not None:
            if isinstance(self.metadata_service, dict):
                _dict['metadata_service'] = self.metadata_service
            else:
                _dict['metadata_service'] = self.metadata_service.to_dict()
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'placement_target') and self.placement_target is not None:
            if isinstance(self.placement_target, dict):
                _dict['placement_target'] = self.placement_target
            else:
                _dict['placement_target'] = self.placement_target.to_dict()
        if hasattr(self, 'profile') and self.profile is not None:
            if isinstance(self.profile, dict):
                _dict['profile'] = self.profile
            else:
                _dict['profile'] = self.profile.to_dict()
        if hasattr(self, 'resource_group') and self.resource_group is not None:
            if isinstance(self.resource_group, dict):
                _dict['resource_group'] = self.resource_group
            else:
                _dict['resource_group'] = self.resource_group.to_dict()
        if hasattr(self, 'total_volume_bandwidth') and self.total_volume_bandwidth is not None:
            _dict['total_volume_bandwidth'] = self.total_volume_bandwidth
        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:
            volume_attachments_list = []
            for v in self.volume_attachments:
                if isinstance(v, dict):
                    volume_attachments_list.append(v)
                else:
                    volume_attachments_list.append(v.to_dict())
            _dict['volume_attachments'] = volume_attachments_list
        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:
            if isinstance(self.boot_volume_attachment, dict):
                _dict['boot_volume_attachment'] = self.boot_volume_attachment
            else:
                _dict['boot_volume_attachment'] = self.boot_volume_attachment.to_dict()
        if hasattr(self, 'network_interfaces') and self.network_interfaces is not None:
            network_interfaces_list = []
            for v in self.network_interfaces:
                if isinstance(v, dict):
                    network_interfaces_list.append(v)
                else:
                    network_interfaces_list.append(v.to_dict())
            _dict['network_interfaces'] = network_interfaces_list
        if hasattr(self, 'primary_network_interface') and self.primary_network_interface is not None:
            if isinstance(self.primary_network_interface, dict):
                _dict['primary_network_interface'] = self.primary_network_interface
            else:
                _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 InstanceTemplateInstanceBySourceSnapshotInstanceTemplateContext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceTemplateInstanceBySourceSnapshotInstanceTemplateContext') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceTemplateInstanceBySourceSnapshotInstanceTemplateContext') -> 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 KeyIdentityByFingerprint(KeyIdentity):
    """
    KeyIdentityByFingerprint.

    :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 KeyIdentityByFingerprint 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) -> 'KeyIdentityByFingerprint':
        """Initialize a KeyIdentityByFingerprint object from a json dictionary."""
        args = {}
        if 'fingerprint' in _dict:
            args['fingerprint'] = _dict.get('fingerprint')
        else:
            raise ValueError('Required property \'fingerprint\' not present in KeyIdentityByFingerprint JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a KeyIdentityByFingerprint object from 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 KeyIdentityByFingerprint object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'KeyIdentityByFingerprint') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'KeyIdentityByFingerprint') -> 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 LegacyCloudObjectStorageBucketIdentityCloudObjectStorageBucketIdentityByName(LegacyCloudObjectStorageBucketIdentity):
    """
    LegacyCloudObjectStorageBucketIdentityCloudObjectStorageBucketIdentityByName.

    :attr str name: The globally unique name of this Cloud Object Storage bucket.
    """

    def __init__(
        self,
        name: str,
    ) -> None:
        """
        Initialize a LegacyCloudObjectStorageBucketIdentityCloudObjectStorageBucketIdentityByName object.

        :param str name: The globally unique name of this Cloud Object Storage
               bucket.
        """
        # pylint: disable=super-init-not-called
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LegacyCloudObjectStorageBucketIdentityCloudObjectStorageBucketIdentityByName':
        """Initialize a LegacyCloudObjectStorageBucketIdentityCloudObjectStorageBucketIdentityByName object from a json dictionary."""
        args = {}
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in LegacyCloudObjectStorageBucketIdentityCloudObjectStorageBucketIdentityByName JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LegacyCloudObjectStorageBucketIdentityCloudObjectStorageBucketIdentityByName object from 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 LegacyCloudObjectStorageBucketIdentityCloudObjectStorageBucketIdentityByName object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LegacyCloudObjectStorageBucketIdentityCloudObjectStorageBucketIdentityByName') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LegacyCloudObjectStorageBucketIdentityCloudObjectStorageBucketIdentityByName') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class LoadBalancerIdentityByCRN(LoadBalancerIdentity):
    """
    LoadBalancerIdentityByCRN.

    :attr str crn: The load balancer's CRN.
    """

    def __init__(
        self,
        crn: str,
    ) -> None:
        """
        Initialize a LoadBalancerIdentityByCRN object.

        :param str crn: The load balancer's CRN.
        """
        # pylint: disable=super-init-not-called
        self.crn = crn

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerIdentityByCRN':
        """Initialize a LoadBalancerIdentityByCRN object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError('Required property \'crn\' not present in LoadBalancerIdentityByCRN JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerIdentityByCRN object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancerIdentityByCRN object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerIdentityByCRN') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerIdentityByCRN') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class LoadBalancerIdentityByHref(LoadBalancerIdentity):
    """
    LoadBalancerIdentityByHref.

    :attr str href: The load balancer's canonical URL.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a LoadBalancerIdentityByHref object.

        :param str href: The load balancer's canonical URL.
        """
        # pylint: disable=super-init-not-called
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerIdentityByHref':
        """Initialize a LoadBalancerIdentityByHref object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in LoadBalancerIdentityByHref JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerIdentityByHref object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancerIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerIdentityByHref') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerIdentityByHref') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class LoadBalancerIdentityById(LoadBalancerIdentity):
    """
    LoadBalancerIdentityById.

    :attr str id: The unique identifier for this load balancer.
    """

    def __init__(
        self,
        id: str,
    ) -> None:
        """
        Initialize a LoadBalancerIdentityById object.

        :param str id: The unique identifier for this load balancer.
        """
        # pylint: disable=super-init-not-called
        self.id = id

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerIdentityById':
        """Initialize a LoadBalancerIdentityById object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in LoadBalancerIdentityById JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerIdentityById object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancerIdentityById object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerIdentityById') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerIdentityById') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class LoadBalancerListenerIdentityByHref(LoadBalancerListenerIdentity):
    """
    LoadBalancerListenerIdentityByHref.

    :attr str href: The listener's canonical URL.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a LoadBalancerListenerIdentityByHref object.

        :param str href: The listener's canonical URL.
        """
        # pylint: disable=super-init-not-called
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerListenerIdentityByHref':
        """Initialize a LoadBalancerListenerIdentityByHref object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in LoadBalancerListenerIdentityByHref JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerListenerIdentityByHref object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(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 LoadBalancerListenerIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerListenerIdentityByHref') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerListenerIdentityByHref') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class LoadBalancerListenerIdentityById(LoadBalancerListenerIdentity):
    """
    LoadBalancerListenerIdentityById.

    :attr str id: The unique identifier for this load balancer listener.
    """

    def __init__(
        self,
        id: str,
    ) -> None:
        """
        Initialize a LoadBalancerListenerIdentityById object.

        :param str id: The unique identifier for this load balancer listener.
        """
        # pylint: disable=super-init-not-called
        self.id = id

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerListenerIdentityById':
        """Initialize a LoadBalancerListenerIdentityById object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in LoadBalancerListenerIdentityById JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerListenerIdentityById object from 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 LoadBalancerListenerIdentityById object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerListenerIdentityById') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerListenerIdentityById') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class LoadBalancerListenerPolicyTargetPatchLoadBalancerListenerHTTPSRedirectPatch(LoadBalancerListenerPolicyTargetPatch):
    """
    LoadBalancerListenerPolicyTargetPatchLoadBalancerListenerHTTPSRedirectPatch.

    :attr int http_status_code: (optional) The HTTP status code for this redirect.
    :attr LoadBalancerListenerIdentity listener: (optional) Identifies a load
          balancer listener by a unique property.
    :attr str uri: (optional) The redirect relative target URI.
    """

    def __init__(
        self,
        *,
        http_status_code: int = None,
        listener: 'LoadBalancerListenerIdentity' = None,
        uri: str = None,
    ) -> None:
        """
        Initialize a LoadBalancerListenerPolicyTargetPatchLoadBalancerListenerHTTPSRedirectPatch object.

        :param int http_status_code: (optional) The HTTP status code for this
               redirect.
        :param LoadBalancerListenerIdentity listener: (optional) Identifies a load
               balancer listener by a unique property.
        :param str uri: (optional) The redirect relative target URI.
        """
        # pylint: disable=super-init-not-called
        self.http_status_code = http_status_code
        self.listener = listener
        self.uri = uri

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerListenerPolicyTargetPatchLoadBalancerListenerHTTPSRedirectPatch':
        """Initialize a LoadBalancerListenerPolicyTargetPatchLoadBalancerListenerHTTPSRedirectPatch object from a json dictionary."""
        args = {}
        if 'http_status_code' in _dict:
            args['http_status_code'] = _dict.get('http_status_code')
        if 'listener' in _dict:
            args['listener'] = _dict.get('listener')
        if 'uri' in _dict:
            args['uri'] = _dict.get('uri')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerListenerPolicyTargetPatchLoadBalancerListenerHTTPSRedirectPatch object from 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, 'listener') and self.listener is not None:
            if isinstance(self.listener, dict):
                _dict['listener'] = self.listener
            else:
                _dict['listener'] = self.listener.to_dict()
        if hasattr(self, 'uri') and self.uri is not None:
            _dict['uri'] = self.uri
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancerListenerPolicyTargetPatchLoadBalancerListenerHTTPSRedirectPatch object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerListenerPolicyTargetPatchLoadBalancerListenerHTTPSRedirectPatch') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerListenerPolicyTargetPatchLoadBalancerListenerHTTPSRedirectPatch') -> 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 for this redirect.
    :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 for this
               redirect.
        :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 LoadBalancerListenerPolicyTargetPrototypeLoadBalancerListenerHTTPSRedirectPrototype(LoadBalancerListenerPolicyTargetPrototype):
    """
    LoadBalancerListenerPolicyTargetPrototypeLoadBalancerListenerHTTPSRedirectPrototype.

    :attr int http_status_code: The HTTP status code for this redirect.
    :attr LoadBalancerListenerIdentity listener: Identifies a load balancer listener
          by a unique property.
    :attr str uri: (optional) The redirect relative target URI.
    """

    def __init__(
        self,
        http_status_code: int,
        listener: 'LoadBalancerListenerIdentity',
        *,
        uri: str = None,
    ) -> None:
        """
        Initialize a LoadBalancerListenerPolicyTargetPrototypeLoadBalancerListenerHTTPSRedirectPrototype object.

        :param int http_status_code: The HTTP status code for this redirect.
        :param LoadBalancerListenerIdentity listener: Identifies a load balancer
               listener by a unique property.
        :param str uri: (optional) The redirect relative target URI.
        """
        # pylint: disable=super-init-not-called
        self.http_status_code = http_status_code
        self.listener = listener
        self.uri = uri

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerListenerPolicyTargetPrototypeLoadBalancerListenerHTTPSRedirectPrototype':
        """Initialize a LoadBalancerListenerPolicyTargetPrototypeLoadBalancerListenerHTTPSRedirectPrototype 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 LoadBalancerListenerPolicyTargetPrototypeLoadBalancerListenerHTTPSRedirectPrototype JSON')
        if 'listener' in _dict:
            args['listener'] = _dict.get('listener')
        else:
            raise ValueError('Required property \'listener\' not present in LoadBalancerListenerPolicyTargetPrototypeLoadBalancerListenerHTTPSRedirectPrototype JSON')
        if 'uri' in _dict:
            args['uri'] = _dict.get('uri')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerListenerPolicyTargetPrototypeLoadBalancerListenerHTTPSRedirectPrototype object from 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, 'listener') and self.listener is not None:
            if isinstance(self.listener, dict):
                _dict['listener'] = self.listener
            else:
                _dict['listener'] = self.listener.to_dict()
        if hasattr(self, 'uri') and self.uri is not None:
            _dict['uri'] = self.uri
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancerListenerPolicyTargetPrototypeLoadBalancerListenerHTTPSRedirectPrototype object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerListenerPolicyTargetPrototypeLoadBalancerListenerHTTPSRedirectPrototype') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerListenerPolicyTargetPrototypeLoadBalancerListenerHTTPSRedirectPrototype') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class LoadBalancerListenerPolicyTargetPrototypeLoadBalancerListenerPolicyRedirectURLPrototype(LoadBalancerListenerPolicyTargetPrototype):
    """
    LoadBalancerListenerPolicyTargetPrototypeLoadBalancerListenerPolicyRedirectURLPrototype.

    :attr int http_status_code: The HTTP status code for this redirect.
    :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 for this redirect.
        :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 LoadBalancerListenerPolicyTargetLoadBalancerListenerHTTPSRedirect(LoadBalancerListenerPolicyTarget):
    """
    LoadBalancerListenerPolicyTargetLoadBalancerListenerHTTPSRedirect.

    :attr int http_status_code: The HTTP status code for this redirect.
    :attr LoadBalancerListenerReference listener:
    :attr str uri: (optional) The redirect relative target URI.
    """

    def __init__(
        self,
        http_status_code: int,
        listener: 'LoadBalancerListenerReference',
        *,
        uri: str = None,
    ) -> None:
        """
        Initialize a LoadBalancerListenerPolicyTargetLoadBalancerListenerHTTPSRedirect object.

        :param int http_status_code: The HTTP status code for this redirect.
        :param LoadBalancerListenerReference listener:
        :param str uri: (optional) The redirect relative target URI.
        """
        # pylint: disable=super-init-not-called
        self.http_status_code = http_status_code
        self.listener = listener
        self.uri = uri

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerListenerPolicyTargetLoadBalancerListenerHTTPSRedirect':
        """Initialize a LoadBalancerListenerPolicyTargetLoadBalancerListenerHTTPSRedirect 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 LoadBalancerListenerPolicyTargetLoadBalancerListenerHTTPSRedirect JSON')
        if 'listener' in _dict:
            args['listener'] = LoadBalancerListenerReference.from_dict(_dict.get('listener'))
        else:
            raise ValueError('Required property \'listener\' not present in LoadBalancerListenerPolicyTargetLoadBalancerListenerHTTPSRedirect JSON')
        if 'uri' in _dict:
            args['uri'] = _dict.get('uri')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerListenerPolicyTargetLoadBalancerListenerHTTPSRedirect object from 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, 'listener') and self.listener is not None:
            if isinstance(self.listener, dict):
                _dict['listener'] = self.listener
            else:
                _dict['listener'] = self.listener.to_dict()
        if hasattr(self, 'uri') and self.uri is not None:
            _dict['uri'] = self.uri
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancerListenerPolicyTargetLoadBalancerListenerHTTPSRedirect object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerListenerPolicyTargetLoadBalancerListenerHTTPSRedirect') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerListenerPolicyTargetLoadBalancerListenerHTTPSRedirect') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class LoadBalancerListenerPolicyTargetLoadBalancerListenerPolicyRedirectURL(LoadBalancerListenerPolicyTarget):
    """
    LoadBalancerListenerPolicyTargetLoadBalancerListenerPolicyRedirectURL.

    :attr int http_status_code: The HTTP status code for this redirect.
    :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 for this redirect.
        :param str url: The redirect target URL.
        """
        # pylint: disable=super-init-not-called
        self.http_status_code = http_status_code
        self.url = url

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerListenerPolicyTargetLoadBalancerListenerPolicyRedirectURL':
        """Initialize a LoadBalancerListenerPolicyTargetLoadBalancerListenerPolicyRedirectURL object from a json dictionary."""
        args = {}
        if 'http_status_code' in _dict:
            args['http_status_code'] = _dict.get('http_status_code')
        else:
            raise ValueError('Required property \'http_status_code\' not present in LoadBalancerListenerPolicyTargetLoadBalancerListenerPolicyRedirectURL JSON')
        if 'url' in _dict:
            args['url'] = _dict.get('url')
        else:
            raise ValueError('Required property \'url\' not present in LoadBalancerListenerPolicyTargetLoadBalancerListenerPolicyRedirectURL JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerListenerPolicyTargetLoadBalancerListenerPolicyRedirectURL object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'http_status_code') and self.http_status_code is not None:
            _dict['http_status_code'] = self.http_status_code
        if hasattr(self, 'url') and self.url is not None:
            _dict['url'] = self.url
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancerListenerPolicyTargetLoadBalancerListenerPolicyRedirectURL object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerListenerPolicyTargetLoadBalancerListenerPolicyRedirectURL') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerListenerPolicyTargetLoadBalancerListenerPolicyRedirectURL') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class LoadBalancerListenerPolicyTargetLoadBalancerPoolReference(LoadBalancerListenerPolicyTarget):
    """
    LoadBalancerListenerPolicyTargetLoadBalancerPoolReference.

    :attr LoadBalancerPoolReferenceDeleted deleted: (optional) If present, this
          property indicates the referenced resource has been deleted, and provides
          some supplementary information.
    :attr str href: The pool's canonical URL.
    :attr str id: The unique identifier for this load balancer pool.
    :attr str name: The name for this load balancer pool. The name is unique across
          all pools for the load balancer.
    """

    def __init__(
        self,
        href: str,
        id: str,
        name: str,
        *,
        deleted: 'LoadBalancerPoolReferenceDeleted' = None,
    ) -> None:
        """
        Initialize a LoadBalancerListenerPolicyTargetLoadBalancerPoolReference object.

        :param str href: The pool's canonical URL.
        :param str id: The unique identifier for this load balancer pool.
        :param str name: The name for this load balancer pool. The name is unique
               across all pools for the load balancer.
        :param LoadBalancerPoolReferenceDeleted deleted: (optional) If present,
               this property indicates the referenced resource has been deleted, and
               provides
               some supplementary information.
        """
        # pylint: disable=super-init-not-called
        self.deleted = deleted
        self.href = href
        self.id = id
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerListenerPolicyTargetLoadBalancerPoolReference':
        """Initialize a LoadBalancerListenerPolicyTargetLoadBalancerPoolReference object from a json dictionary."""
        args = {}
        if 'deleted' in _dict:
            args['deleted'] = LoadBalancerPoolReferenceDeleted.from_dict(_dict.get('deleted'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in LoadBalancerListenerPolicyTargetLoadBalancerPoolReference JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in LoadBalancerListenerPolicyTargetLoadBalancerPoolReference JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in LoadBalancerListenerPolicyTargetLoadBalancerPoolReference JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerListenerPolicyTargetLoadBalancerPoolReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'deleted') and self.deleted is not None:
            if isinstance(self.deleted, dict):
                _dict['deleted'] = self.deleted
            else:
                _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancerListenerPolicyTargetLoadBalancerPoolReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerListenerPolicyTargetLoadBalancerPoolReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerListenerPolicyTargetLoadBalancerPoolReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class LoadBalancerPoolIdentityByHref(LoadBalancerPoolIdentity):
    """
    LoadBalancerPoolIdentityByHref.

    :attr str href: The pool's canonical URL.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a LoadBalancerPoolIdentityByHref object.

        :param str href: The pool's canonical URL.
        """
        # pylint: disable=super-init-not-called
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerPoolIdentityByHref':
        """Initialize a LoadBalancerPoolIdentityByHref object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in LoadBalancerPoolIdentityByHref JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerPoolIdentityByHref object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancerPoolIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerPoolIdentityByHref') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerPoolIdentityByHref') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class LoadBalancerPoolIdentityById(LoadBalancerPoolIdentity):
    """
    LoadBalancerPoolIdentityById.

    :attr str id: The unique identifier for this load balancer pool.
    """

    def __init__(
        self,
        id: str,
    ) -> None:
        """
        Initialize a LoadBalancerPoolIdentityById object.

        :param str id: The unique identifier for this load balancer pool.
        """
        # pylint: disable=super-init-not-called
        self.id = id

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerPoolIdentityById':
        """Initialize a LoadBalancerPoolIdentityById object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in LoadBalancerPoolIdentityById JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerPoolIdentityById object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancerPoolIdentityById object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerPoolIdentityById') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerPoolIdentityById') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class LoadBalancerPoolMemberTargetPrototypeIP(LoadBalancerPoolMemberTargetPrototype):
    """
    LoadBalancerPoolMemberTargetPrototypeIP.

    :attr str address: The IP address.
          This property may add support for IPv6 addresses in the future. When processing
          a value in this property, verify that the address is in an expected format. If
          it is not, log an error. Optionally halt processing and surface the error, or
          bypass the resource on which the unexpected IP address format was encountered.
    """

    def __init__(
        self,
        address: str,
    ) -> None:
        """
        Initialize a LoadBalancerPoolMemberTargetPrototypeIP object.

        :param str address: The IP address.
               This property may add support for IPv6 addresses in the future. When
               processing a value in this property, verify that the address is in an
               expected format. If it is not, log an error. Optionally halt processing and
               surface the error, or bypass the resource on which the unexpected IP
               address format was encountered.
        """
        # pylint: disable=super-init-not-called
        self.address = address

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerPoolMemberTargetPrototypeIP':
        """Initialize a LoadBalancerPoolMemberTargetPrototypeIP object from a json dictionary."""
        args = {}
        if 'address' in _dict:
            args['address'] = _dict.get('address')
        else:
            raise ValueError('Required property \'address\' not present in LoadBalancerPoolMemberTargetPrototypeIP JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerPoolMemberTargetPrototypeIP object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'address') and self.address is not None:
            _dict['address'] = self.address
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancerPoolMemberTargetPrototypeIP object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerPoolMemberTargetPrototypeIP') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerPoolMemberTargetPrototypeIP') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class LoadBalancerPoolMemberTargetPrototypeInstanceIdentity(LoadBalancerPoolMemberTargetPrototype):
    """
    Identifies a virtual server instance by a unique property.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a LoadBalancerPoolMemberTargetPrototypeInstanceIdentity object.

        """
        # pylint: disable=super-init-not-called
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['LoadBalancerPoolMemberTargetPrototypeInstanceIdentityInstanceIdentityById', 'LoadBalancerPoolMemberTargetPrototypeInstanceIdentityInstanceIdentityByCRN', 'LoadBalancerPoolMemberTargetPrototypeInstanceIdentityInstanceIdentityByHref'])
        )
        raise Exception(msg)


class LoadBalancerPoolMemberTargetIP(LoadBalancerPoolMemberTarget):
    """
    LoadBalancerPoolMemberTargetIP.

    :attr str address: The IP address.
          This property may add support for IPv6 addresses in the future. When processing
          a value in this property, verify that the address is in an expected format. If
          it is not, log an error. Optionally halt processing and surface the error, or
          bypass the resource on which the unexpected IP address format was encountered.
    """

    def __init__(
        self,
        address: str,
    ) -> None:
        """
        Initialize a LoadBalancerPoolMemberTargetIP object.

        :param str address: The IP address.
               This property may add support for IPv6 addresses in the future. When
               processing a value in this property, verify that the address is in an
               expected format. If it is not, log an error. Optionally halt processing and
               surface the error, or bypass the resource on which the unexpected IP
               address format was encountered.
        """
        # pylint: disable=super-init-not-called
        self.address = address

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerPoolMemberTargetIP':
        """Initialize a LoadBalancerPoolMemberTargetIP object from a json dictionary."""
        args = {}
        if 'address' in _dict:
            args['address'] = _dict.get('address')
        else:
            raise ValueError('Required property \'address\' not present in LoadBalancerPoolMemberTargetIP JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerPoolMemberTargetIP object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'address') and self.address is not None:
            _dict['address'] = self.address
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancerPoolMemberTargetIP object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerPoolMemberTargetIP') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerPoolMemberTargetIP') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class LoadBalancerPoolMemberTargetInstanceReference(LoadBalancerPoolMemberTarget):
    """
    LoadBalancerPoolMemberTargetInstanceReference.

    :attr str crn: The CRN for this virtual server instance.
    :attr InstanceReferenceDeleted deleted: (optional) If present, this property
          indicates the referenced resource has been deleted, and provides
          some supplementary information.
    :attr str href: The URL for this virtual server instance.
    :attr str id: The unique identifier for this virtual server instance.
    :attr str name: The name for this virtual server instance. The name is unique
          across all virtual server instances in the region.
    """

    def __init__(
        self,
        crn: str,
        href: str,
        id: str,
        name: str,
        *,
        deleted: 'InstanceReferenceDeleted' = None,
    ) -> None:
        """
        Initialize a LoadBalancerPoolMemberTargetInstanceReference object.

        :param str crn: The CRN for this virtual server instance.
        :param str href: The URL for this virtual server instance.
        :param str id: The unique identifier for this virtual server instance.
        :param str name: The name for this virtual server instance. The name is
               unique across all virtual server instances in the region.
        :param InstanceReferenceDeleted deleted: (optional) If present, this
               property indicates the referenced resource has been deleted, and provides
               some supplementary information.
        """
        # pylint: disable=super-init-not-called
        self.crn = crn
        self.deleted = deleted
        self.href = href
        self.id = id
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerPoolMemberTargetInstanceReference':
        """Initialize a LoadBalancerPoolMemberTargetInstanceReference object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError('Required property \'crn\' not present in LoadBalancerPoolMemberTargetInstanceReference JSON')
        if 'deleted' in _dict:
            args['deleted'] = InstanceReferenceDeleted.from_dict(_dict.get('deleted'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in LoadBalancerPoolMemberTargetInstanceReference JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in LoadBalancerPoolMemberTargetInstanceReference JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in LoadBalancerPoolMemberTargetInstanceReference JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerPoolMemberTargetInstanceReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'deleted') and self.deleted is not None:
            if isinstance(self.deleted, dict):
                _dict['deleted'] = self.deleted
            else:
                _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancerPoolMemberTargetInstanceReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerPoolMemberTargetInstanceReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerPoolMemberTargetInstanceReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class LoadBalancerProfileIdentityByHref(LoadBalancerProfileIdentity):
    """
    LoadBalancerProfileIdentityByHref.

    :attr str href: The URL for this load balancer profile.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a LoadBalancerProfileIdentityByHref object.

        :param str href: The URL for this load balancer profile.
        """
        # pylint: disable=super-init-not-called
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerProfileIdentityByHref':
        """Initialize a LoadBalancerProfileIdentityByHref object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in LoadBalancerProfileIdentityByHref JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerProfileIdentityByHref object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancerProfileIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerProfileIdentityByHref') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerProfileIdentityByHref') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class LoadBalancerProfileIdentityByName(LoadBalancerProfileIdentity):
    """
    LoadBalancerProfileIdentityByName.

    :attr str name: The globally unique name for this load balancer profile.
    """

    def __init__(
        self,
        name: str,
    ) -> None:
        """
        Initialize a LoadBalancerProfileIdentityByName object.

        :param str name: The globally unique name for this load balancer profile.
        """
        # pylint: disable=super-init-not-called
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerProfileIdentityByName':
        """Initialize a LoadBalancerProfileIdentityByName object from a json dictionary."""
        args = {}
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in LoadBalancerProfileIdentityByName JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerProfileIdentityByName object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancerProfileIdentityByName object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerProfileIdentityByName') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerProfileIdentityByName') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class LoadBalancerProfileInstanceGroupsSupportedDependent(LoadBalancerProfileInstanceGroupsSupported):
    """
    The instance groups support for a load balancer with this profile depends on its
    configuration.

    :attr str type: The type for this profile field.
    """

    def __init__(
        self,
        type: str,
    ) -> None:
        """
        Initialize a LoadBalancerProfileInstanceGroupsSupportedDependent 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) -> 'LoadBalancerProfileInstanceGroupsSupportedDependent':
        """Initialize a LoadBalancerProfileInstanceGroupsSupportedDependent object from a json dictionary."""
        args = {}
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in LoadBalancerProfileInstanceGroupsSupportedDependent JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerProfileInstanceGroupsSupportedDependent object from 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 LoadBalancerProfileInstanceGroupsSupportedDependent object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerProfileInstanceGroupsSupportedDependent') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerProfileInstanceGroupsSupportedDependent') -> 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 LoadBalancerProfileInstanceGroupsSupportedFixed(LoadBalancerProfileInstanceGroupsSupported):
    """
    The instance groups support for a load balancer with this profile.

    :attr str type: The type for this profile field.
    :attr bool value: The value for this profile field.
    """

    def __init__(
        self,
        type: str,
        value: bool,
    ) -> None:
        """
        Initialize a LoadBalancerProfileInstanceGroupsSupportedFixed object.

        :param str type: The type for this profile field.
        :param bool value: The value for this profile field.
        """
        # pylint: disable=super-init-not-called
        self.type = type
        self.value = value

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerProfileInstanceGroupsSupportedFixed':
        """Initialize a LoadBalancerProfileInstanceGroupsSupportedFixed object from a json dictionary."""
        args = {}
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in LoadBalancerProfileInstanceGroupsSupportedFixed JSON')
        if 'value' in _dict:
            args['value'] = _dict.get('value')
        else:
            raise ValueError('Required property \'value\' not present in LoadBalancerProfileInstanceGroupsSupportedFixed JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerProfileInstanceGroupsSupportedFixed object from 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 LoadBalancerProfileInstanceGroupsSupportedFixed object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerProfileInstanceGroupsSupportedFixed') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerProfileInstanceGroupsSupportedFixed') -> 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 LoadBalancerProfileRouteModeSupportedDependent(LoadBalancerProfileRouteModeSupported):
    """
    The route mode support for a load balancer with this profile depends on its
    configuration.

    :attr str type: The type for this profile field.
    """

    def __init__(
        self,
        type: str,
    ) -> None:
        """
        Initialize a LoadBalancerProfileRouteModeSupportedDependent 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) -> 'LoadBalancerProfileRouteModeSupportedDependent':
        """Initialize a LoadBalancerProfileRouteModeSupportedDependent object from a json dictionary."""
        args = {}
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in LoadBalancerProfileRouteModeSupportedDependent JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerProfileRouteModeSupportedDependent object from 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 LoadBalancerProfileRouteModeSupportedDependent object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerProfileRouteModeSupportedDependent') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerProfileRouteModeSupportedDependent') -> 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 LoadBalancerProfileRouteModeSupportedFixed(LoadBalancerProfileRouteModeSupported):
    """
    The route mode support for a load balancer with this profile.

    :attr str type: The type for this profile field.
    :attr bool value: The value for this profile field.
    """

    def __init__(
        self,
        type: str,
        value: bool,
    ) -> None:
        """
        Initialize a LoadBalancerProfileRouteModeSupportedFixed object.

        :param str type: The type for this profile field.
        :param bool value: The value for this profile field.
        """
        # pylint: disable=super-init-not-called
        self.type = type
        self.value = value

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerProfileRouteModeSupportedFixed':
        """Initialize a LoadBalancerProfileRouteModeSupportedFixed object from a json dictionary."""
        args = {}
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in LoadBalancerProfileRouteModeSupportedFixed JSON')
        if 'value' in _dict:
            args['value'] = _dict.get('value')
        else:
            raise ValueError('Required property \'value\' not present in LoadBalancerProfileRouteModeSupportedFixed JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerProfileRouteModeSupportedFixed object from 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 LoadBalancerProfileRouteModeSupportedFixed object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerProfileRouteModeSupportedFixed') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerProfileRouteModeSupportedFixed') -> 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 LoadBalancerProfileSecurityGroupsSupportedDependent(LoadBalancerProfileSecurityGroupsSupported):
    """
    The security group support for a load balancer with this profile depends on its
    configuration.

    :attr str type: The type for this profile field.
    """

    def __init__(
        self,
        type: str,
    ) -> None:
        """
        Initialize a LoadBalancerProfileSecurityGroupsSupportedDependent object.

        :param str type: The type for this profile field.
        """
        # pylint: disable=super-init-not-called
        self.type = type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerProfileSecurityGroupsSupportedDependent':
        """Initialize a LoadBalancerProfileSecurityGroupsSupportedDependent object from a json dictionary."""
        args = {}
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in LoadBalancerProfileSecurityGroupsSupportedDependent JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerProfileSecurityGroupsSupportedDependent object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'type') and self.type is not None:
            _dict['type'] = self.type
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancerProfileSecurityGroupsSupportedDependent object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerProfileSecurityGroupsSupportedDependent') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerProfileSecurityGroupsSupportedDependent') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class TypeEnum(str, Enum):
        """
        The type for this profile field.
        """

        DEPENDENT = 'dependent'



class LoadBalancerProfileSecurityGroupsSupportedFixed(LoadBalancerProfileSecurityGroupsSupported):
    """
    The security group support for a load balancer with this profile.

    :attr str type: The type for this profile field.
    :attr bool value: The value for this profile field.
    """

    def __init__(
        self,
        type: str,
        value: bool,
    ) -> None:
        """
        Initialize a LoadBalancerProfileSecurityGroupsSupportedFixed object.

        :param str type: The type for this profile field.
        :param bool value: The value for this profile field.
        """
        # pylint: disable=super-init-not-called
        self.type = type
        self.value = value

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerProfileSecurityGroupsSupportedFixed':
        """Initialize a LoadBalancerProfileSecurityGroupsSupportedFixed object from a json dictionary."""
        args = {}
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in LoadBalancerProfileSecurityGroupsSupportedFixed JSON')
        if 'value' in _dict:
            args['value'] = _dict.get('value')
        else:
            raise ValueError('Required property \'value\' not present in LoadBalancerProfileSecurityGroupsSupportedFixed JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerProfileSecurityGroupsSupportedFixed object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'type') and self.type is not None:
            _dict['type'] = self.type
        if hasattr(self, 'value') and self.value is not None:
            _dict['value'] = self.value
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancerProfileSecurityGroupsSupportedFixed object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerProfileSecurityGroupsSupportedFixed') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerProfileSecurityGroupsSupportedFixed') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class TypeEnum(str, Enum):
        """
        The type for this profile field.
        """

        FIXED = 'fixed'



class LoadBalancerProfileUDPSupportedDependent(LoadBalancerProfileUDPSupported):
    """
    The UDP support for a load balancer with this profile depends on its configuration.

    :attr str type: The type for this profile field.
    """

    def __init__(
        self,
        type: str,
    ) -> None:
        """
        Initialize a LoadBalancerProfileUDPSupportedDependent 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) -> 'LoadBalancerProfileUDPSupportedDependent':
        """Initialize a LoadBalancerProfileUDPSupportedDependent object from a json dictionary."""
        args = {}
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in LoadBalancerProfileUDPSupportedDependent JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerProfileUDPSupportedDependent object from 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 LoadBalancerProfileUDPSupportedDependent object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerProfileUDPSupportedDependent') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerProfileUDPSupportedDependent') -> 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 LoadBalancerProfileUDPSupportedFixed(LoadBalancerProfileUDPSupported):
    """
    The UDP support for a load balancer with this profile.

    :attr str type: The type for this profile field.
    :attr bool value: The value for this profile field.
    """

    def __init__(
        self,
        type: str,
        value: bool,
    ) -> None:
        """
        Initialize a LoadBalancerProfileUDPSupportedFixed object.

        :param str type: The type for this profile field.
        :param bool value: The value for this profile field.
        """
        # pylint: disable=super-init-not-called
        self.type = type
        self.value = value

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerProfileUDPSupportedFixed':
        """Initialize a LoadBalancerProfileUDPSupportedFixed object from a json dictionary."""
        args = {}
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in LoadBalancerProfileUDPSupportedFixed JSON')
        if 'value' in _dict:
            args['value'] = _dict.get('value')
        else:
            raise ValueError('Required property \'value\' not present in LoadBalancerProfileUDPSupportedFixed JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerProfileUDPSupportedFixed object from 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 LoadBalancerProfileUDPSupportedFixed object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerProfileUDPSupportedFixed') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerProfileUDPSupportedFixed') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class TypeEnum(str, Enum):
        """
        The type for this profile field.
        """

        FIXED = 'fixed'



class NetworkACLIdentityByCRN(NetworkACLIdentity):
    """
    NetworkACLIdentityByCRN.

    :attr str crn: The CRN for this network ACL.
    """

    def __init__(
        self,
        crn: str,
    ) -> None:
        """
        Initialize a NetworkACLIdentityByCRN object.

        :param str crn: The CRN for this network ACL.
        """
        # pylint: disable=super-init-not-called
        self.crn = crn

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'NetworkACLIdentityByCRN':
        """Initialize a NetworkACLIdentityByCRN object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError('Required property \'crn\' not present in NetworkACLIdentityByCRN JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a NetworkACLIdentityByCRN object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this NetworkACLIdentityByCRN object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'NetworkACLIdentityByCRN') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'NetworkACLIdentityByCRN') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class NetworkACLIdentityByHref(NetworkACLIdentity):
    """
    NetworkACLIdentityByHref.

    :attr str href: The URL for this network ACL.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a NetworkACLIdentityByHref object.

        :param str href: The URL for this network ACL.
        """
        # pylint: disable=super-init-not-called
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'NetworkACLIdentityByHref':
        """Initialize a NetworkACLIdentityByHref object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in NetworkACLIdentityByHref JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a NetworkACLIdentityByHref object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this NetworkACLIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'NetworkACLIdentityByHref') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'NetworkACLIdentityByHref') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class NetworkACLIdentityById(NetworkACLIdentity):
    """
    NetworkACLIdentityById.

    :attr str id: The unique identifier for this network ACL.
    """

    def __init__(
        self,
        id: str,
    ) -> None:
        """
        Initialize a NetworkACLIdentityById object.

        :param str id: The unique identifier for this network ACL.
        """
        # pylint: disable=super-init-not-called
        self.id = id

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'NetworkACLIdentityById':
        """Initialize a NetworkACLIdentityById object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in NetworkACLIdentityById JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a NetworkACLIdentityById object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this NetworkACLIdentityById object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'NetworkACLIdentityById') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'NetworkACLIdentityById') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class NetworkACLPrototypeNetworkACLByRules(NetworkACLPrototype):
    """
    NetworkACLPrototypeNetworkACLByRules.

    :attr str name: (optional) The name for this network ACL. The name must not be
          used by another network ACL for the VPC. If unspecified, the name will be a
          hyphenated list of randomly-selected words.
    :attr ResourceGroupIdentity resource_group: (optional)
    :attr VPCIdentity vpc: The VPC this network ACL will reside in.
    :attr List[NetworkACLRulePrototypeNetworkACLContext] rules: (optional) The
          prototype objects for rules to create along with this network ACL. If
          unspecified, no rules will be created, resulting in all traffic being denied.
    """

    def __init__(
        self,
        vpc: 'VPCIdentity',
        *,
        name: str = None,
        resource_group: 'ResourceGroupIdentity' = None,
        rules: List['NetworkACLRulePrototypeNetworkACLContext'] = None,
    ) -> None:
        """
        Initialize a NetworkACLPrototypeNetworkACLByRules object.

        :param VPCIdentity vpc: The VPC this network ACL will reside in.
        :param str name: (optional) The name for this network ACL. The name must
               not be used by another network ACL for the VPC. If unspecified, the name
               will be a hyphenated list of randomly-selected words.
        :param ResourceGroupIdentity resource_group: (optional)
        :param List[NetworkACLRulePrototypeNetworkACLContext] rules: (optional) The
               prototype objects for rules to create along with this network ACL. If
               unspecified, no rules will be created, resulting in all traffic being
               denied.
        """
        # pylint: disable=super-init-not-called
        self.name = name
        self.resource_group = resource_group
        self.vpc = vpc
        self.rules = rules

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'NetworkACLPrototypeNetworkACLByRules':
        """Initialize a NetworkACLPrototypeNetworkACLByRules object from a json dictionary."""
        args = {}
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        if 'resource_group' in _dict:
            args['resource_group'] = _dict.get('resource_group')
        if 'vpc' in _dict:
            args['vpc'] = _dict.get('vpc')
        else:
            raise ValueError('Required property \'vpc\' not present in NetworkACLPrototypeNetworkACLByRules JSON')
        if 'rules' in _dict:
            args['rules'] = [NetworkACLRulePrototypeNetworkACLContext.from_dict(v) for v in _dict.get('rules')]
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a NetworkACLPrototypeNetworkACLByRules object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'resource_group') and self.resource_group is not None:
            if isinstance(self.resource_group, dict):
                _dict['resource_group'] = self.resource_group
            else:
                _dict['resource_group'] = self.resource_group.to_dict()
        if hasattr(self, 'vpc') and self.vpc is not None:
            if isinstance(self.vpc, dict):
                _dict['vpc'] = self.vpc
            else:
                _dict['vpc'] = self.vpc.to_dict()
        if hasattr(self, 'rules') and self.rules is not None:
            rules_list = []
            for v in self.rules:
                if isinstance(v, dict):
                    rules_list.append(v)
                else:
                    rules_list.append(v.to_dict())
            _dict['rules'] = rules_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 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 name for this network ACL. The name must not be
          used by another network ACL for the VPC. If unspecified, the name will be a
          hyphenated list of randomly-selected words.
    :attr ResourceGroupIdentity resource_group: (optional)
    :attr VPCIdentity vpc: The VPC this network ACL will reside in.
    :attr NetworkACLIdentity source_network_acl: Network ACL to copy rules from.
    """

    def __init__(
        self,
        vpc: 'VPCIdentity',
        source_network_acl: 'NetworkACLIdentity',
        *,
        name: str = None,
        resource_group: 'ResourceGroupIdentity' = None,
    ) -> None:
        """
        Initialize a NetworkACLPrototypeNetworkACLBySourceNetworkACL object.

        :param VPCIdentity vpc: The VPC this network ACL will reside in.
        :param NetworkACLIdentity source_network_acl: Network ACL to copy rules
               from.
        :param str name: (optional) The name for this network ACL. The name must
               not be used by another network ACL for the VPC. If unspecified, the name
               will be a hyphenated list of randomly-selected words.
        :param ResourceGroupIdentity resource_group: (optional)
        """
        # pylint: disable=super-init-not-called
        self.name = name
        self.resource_group = resource_group
        self.vpc = vpc
        self.source_network_acl = source_network_acl

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'NetworkACLPrototypeNetworkACLBySourceNetworkACL':
        """Initialize a NetworkACLPrototypeNetworkACLBySourceNetworkACL object from a json dictionary."""
        args = {}
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        if 'resource_group' in _dict:
            args['resource_group'] = _dict.get('resource_group')
        if 'vpc' in _dict:
            args['vpc'] = _dict.get('vpc')
        else:
            raise ValueError('Required property \'vpc\' not present in NetworkACLPrototypeNetworkACLBySourceNetworkACL JSON')
        if 'source_network_acl' in _dict:
            args['source_network_acl'] = _dict.get('source_network_acl')
        else:
            raise ValueError('Required property \'source_network_acl\' not present in NetworkACLPrototypeNetworkACLBySourceNetworkACL JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a NetworkACLPrototypeNetworkACLBySourceNetworkACL object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'resource_group') and self.resource_group is not None:
            if isinstance(self.resource_group, dict):
                _dict['resource_group'] = self.resource_group
            else:
                _dict['resource_group'] = self.resource_group.to_dict()
        if hasattr(self, 'vpc') and self.vpc is not None:
            if isinstance(self.vpc, dict):
                _dict['vpc'] = self.vpc
            else:
                _dict['vpc'] = self.vpc.to_dict()
        if hasattr(self, 'source_network_acl') and self.source_network_acl is not None:
            if isinstance(self.source_network_acl, dict):
                _dict['source_network_acl'] = self.source_network_acl
            else:
                _dict['source_network_acl'] = self.source_network_acl.to_dict()
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this NetworkACLPrototypeNetworkACLBySourceNetworkACL object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'NetworkACLPrototypeNetworkACLBySourceNetworkACL') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'NetworkACLPrototypeNetworkACLBySourceNetworkACL') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class NetworkACLRuleBeforePatchNetworkACLRuleIdentityByHref(NetworkACLRuleBeforePatch):
    """
    NetworkACLRuleBeforePatchNetworkACLRuleIdentityByHref.

    :attr str href: The URL for this network ACL rule.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a NetworkACLRuleBeforePatchNetworkACLRuleIdentityByHref object.

        :param str href: The URL for this network ACL rule.
        """
        # pylint: disable=super-init-not-called
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'NetworkACLRuleBeforePatchNetworkACLRuleIdentityByHref':
        """Initialize a NetworkACLRuleBeforePatchNetworkACLRuleIdentityByHref object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in NetworkACLRuleBeforePatchNetworkACLRuleIdentityByHref JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a NetworkACLRuleBeforePatchNetworkACLRuleIdentityByHref object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this NetworkACLRuleBeforePatchNetworkACLRuleIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'NetworkACLRuleBeforePatchNetworkACLRuleIdentityByHref') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'NetworkACLRuleBeforePatchNetworkACLRuleIdentityByHref') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class NetworkACLRuleBeforePatchNetworkACLRuleIdentityById(NetworkACLRuleBeforePatch):
    """
    NetworkACLRuleBeforePatchNetworkACLRuleIdentityById.

    :attr str id: The unique identifier for this network ACL rule.
    """

    def __init__(
        self,
        id: str,
    ) -> None:
        """
        Initialize a NetworkACLRuleBeforePatchNetworkACLRuleIdentityById object.

        :param str id: The unique identifier for this network ACL rule.
        """
        # pylint: disable=super-init-not-called
        self.id = id

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'NetworkACLRuleBeforePatchNetworkACLRuleIdentityById':
        """Initialize a NetworkACLRuleBeforePatchNetworkACLRuleIdentityById object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in NetworkACLRuleBeforePatchNetworkACLRuleIdentityById JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a NetworkACLRuleBeforePatchNetworkACLRuleIdentityById object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this NetworkACLRuleBeforePatchNetworkACLRuleIdentityById object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'NetworkACLRuleBeforePatchNetworkACLRuleIdentityById') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'NetworkACLRuleBeforePatchNetworkACLRuleIdentityById') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class NetworkACLRuleBeforePrototypeNetworkACLRuleIdentityByHref(NetworkACLRuleBeforePrototype):
    """
    NetworkACLRuleBeforePrototypeNetworkACLRuleIdentityByHref.

    :attr str href: The URL for this network ACL rule.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a NetworkACLRuleBeforePrototypeNetworkACLRuleIdentityByHref object.

        :param str href: The URL for this network ACL rule.
        """
        # pylint: disable=super-init-not-called
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'NetworkACLRuleBeforePrototypeNetworkACLRuleIdentityByHref':
        """Initialize a NetworkACLRuleBeforePrototypeNetworkACLRuleIdentityByHref object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in NetworkACLRuleBeforePrototypeNetworkACLRuleIdentityByHref JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a NetworkACLRuleBeforePrototypeNetworkACLRuleIdentityByHref object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this NetworkACLRuleBeforePrototypeNetworkACLRuleIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'NetworkACLRuleBeforePrototypeNetworkACLRuleIdentityByHref') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'NetworkACLRuleBeforePrototypeNetworkACLRuleIdentityByHref') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class NetworkACLRuleBeforePrototypeNetworkACLRuleIdentityById(NetworkACLRuleBeforePrototype):
    """
    NetworkACLRuleBeforePrototypeNetworkACLRuleIdentityById.

    :attr str id: The unique identifier for this network ACL rule.
    """

    def __init__(
        self,
        id: str,
    ) -> None:
        """
        Initialize a NetworkACLRuleBeforePrototypeNetworkACLRuleIdentityById object.

        :param str id: The unique identifier for this network ACL rule.
        """
        # pylint: disable=super-init-not-called
        self.id = id

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'NetworkACLRuleBeforePrototypeNetworkACLRuleIdentityById':
        """Initialize a NetworkACLRuleBeforePrototypeNetworkACLRuleIdentityById object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in NetworkACLRuleBeforePrototypeNetworkACLRuleIdentityById JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a NetworkACLRuleBeforePrototypeNetworkACLRuleIdentityById object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this NetworkACLRuleBeforePrototypeNetworkACLRuleIdentityById object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'NetworkACLRuleBeforePrototypeNetworkACLRuleIdentityById') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'NetworkACLRuleBeforePrototypeNetworkACLRuleIdentityById') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class NetworkACLRuleItemNetworkACLRuleProtocolAll(NetworkACLRuleItem):
    """
    NetworkACLRuleItemNetworkACLRuleProtocolAll.

    :attr str action: The action to perform for a packet matching the rule.
    :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 IP address or CIDR block to match. The
          CIDR block `0.0.0.0/0` matches all destination addresses.
    :attr str direction: The direction of traffic to match.
    :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 name for this network ACL rule. The name is unique across
          all rules for the network ACL.
    :attr str source: The source IP address or CIDR block to match. The CIDR block
          `0.0.0.0/0` matches all source 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: The action to perform for a packet matching the rule.
        :param datetime created_at: The date and time that the rule was created.
        :param str destination: The destination IP address or CIDR block to match.
               The CIDR block `0.0.0.0/0` matches all destination addresses.
        :param str direction: The direction of traffic to match.
        :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 name for this network ACL rule. The name is unique
               across all rules for the network ACL.
        :param str source: The source IP address or CIDR block to match. The CIDR
               block `0.0.0.0/0` matches all source 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:
            if isinstance(self.before, dict):
                _dict['before'] = self.before
            else:
                _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):
        """
        The action to perform for a packet matching the rule.
        """

        ALLOW = 'allow'
        DENY = 'deny'


    class DirectionEnum(str, Enum):
        """
        The direction of traffic to match.
        """

        INBOUND = 'inbound'
        OUTBOUND = 'outbound'


    class IpVersionEnum(str, Enum):
        """
        The IP version for this rule.
        """

        IPV4 = 'ipv4'


    class ProtocolEnum(str, Enum):
        """
        The protocol to enforce.
        """

        ALL = 'all'



class NetworkACLRuleItemNetworkACLRuleProtocolICMP(NetworkACLRuleItem):
    """
    NetworkACLRuleItemNetworkACLRuleProtocolICMP.

    :attr str action: The action to perform for a packet matching the rule.
    :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 IP address or CIDR block to match. The
          CIDR block `0.0.0.0/0` matches all destination addresses.
    :attr str direction: The direction of traffic to match.
    :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 name for this network ACL rule. The name is unique across
          all rules for the network ACL.
    :attr str source: The source IP address or CIDR block to match. The CIDR block
          `0.0.0.0/0` matches all source addresses.
    :attr int code: (optional) The ICMP traffic code to match.
          If absent, all codes are matched.
    :attr str protocol: The protocol to enforce.
    :attr int type: (optional) The ICMP traffic type to match.
          If absent, all types are matched.
    """

    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: The action to perform for a packet matching the rule.
        :param datetime created_at: The date and time that the rule was created.
        :param str destination: The destination IP address or CIDR block to match.
               The CIDR block `0.0.0.0/0` matches all destination addresses.
        :param str direction: The direction of traffic to match.
        :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 name for this network ACL rule. The name is unique
               across all rules for the network ACL.
        :param str source: The source IP address or CIDR block to match. The CIDR
               block `0.0.0.0/0` matches all source 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 match.
               If absent, all codes are matched.
        :param int type: (optional) The ICMP traffic type to match.
               If absent, all types are matched.
        """
        # 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:
            if isinstance(self.before, dict):
                _dict['before'] = self.before
            else:
                _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):
        """
        The action to perform for a packet matching the rule.
        """

        ALLOW = 'allow'
        DENY = 'deny'


    class DirectionEnum(str, Enum):
        """
        The direction of traffic to match.
        """

        INBOUND = 'inbound'
        OUTBOUND = 'outbound'


    class IpVersionEnum(str, Enum):
        """
        The IP version for this rule.
        """

        IPV4 = 'ipv4'


    class ProtocolEnum(str, Enum):
        """
        The protocol to enforce.
        """

        ICMP = 'icmp'



class NetworkACLRuleItemNetworkACLRuleProtocolTCPUDP(NetworkACLRuleItem):
    """
    NetworkACLRuleItemNetworkACLRuleProtocolTCPUDP.

    :attr str action: The action to perform for a packet matching the rule.
    :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 IP address or CIDR block to match. The
          CIDR block `0.0.0.0/0` matches all destination addresses.
    :attr str direction: The direction of traffic to match.
    :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 name for this network ACL rule. The name is unique across
          all rules for the network ACL.
    :attr str source: The source IP address or CIDR block to match. The CIDR block
          `0.0.0.0/0` matches all source addresses.
    :attr int destination_port_max: The inclusive upper bound of TCP/UDP destination
          port range.
    :attr int destination_port_min: The inclusive lower bound of TCP/UDP destination
          port range.
    :attr str protocol: The protocol to enforce.
    :attr int source_port_max: The inclusive upper bound of TCP/UDP source port
          range.
    :attr int source_port_min: 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,
        destination_port_max: int,
        destination_port_min: int,
        protocol: str,
        source_port_max: int,
        source_port_min: int,
        *,
        before: 'NetworkACLRuleReference' = None,
    ) -> None:
        """
        Initialize a NetworkACLRuleItemNetworkACLRuleProtocolTCPUDP object.

        :param str action: The action to perform for a packet matching the rule.
        :param datetime created_at: The date and time that the rule was created.
        :param str destination: The destination IP address or CIDR block to match.
               The CIDR block `0.0.0.0/0` matches all destination addresses.
        :param str direction: The direction of traffic to match.
        :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 name for this network ACL rule. The name is unique
               across all rules for the network ACL.
        :param str source: The source IP address or CIDR block to match. The CIDR
               block `0.0.0.0/0` matches all source addresses.
        :param int destination_port_max: The inclusive upper bound of TCP/UDP
               destination port range.
        :param int destination_port_min: The inclusive lower bound of TCP/UDP
               destination port range.
        :param str protocol: The protocol to enforce.
        :param int source_port_max: The inclusive upper bound of TCP/UDP source
               port range.
        :param int source_port_min: The inclusive lower bound of TCP/UDP source
               port range.
        :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.destination_port_max = destination_port_max
        self.destination_port_min = destination_port_min
        self.protocol = protocol
        self.source_port_max = source_port_max
        self.source_port_min = source_port_min

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'NetworkACLRuleItemNetworkACLRuleProtocolTCPUDP':
        """Initialize a NetworkACLRuleItemNetworkACLRuleProtocolTCPUDP object from a json dictionary."""
        args = {}
        if 'action' in _dict:
            args['action'] = _dict.get('action')
        else:
            raise ValueError('Required property \'action\' not present in NetworkACLRuleItemNetworkACLRuleProtocolTCPUDP JSON')
        if 'before' in _dict:
            args['before'] = NetworkACLRuleReference.from_dict(_dict.get('before'))
        if 'created_at' in _dict:
            args['created_at'] = string_to_datetime(_dict.get('created_at'))
        else:
            raise ValueError('Required property \'created_at\' not present in NetworkACLRuleItemNetworkACLRuleProtocolTCPUDP JSON')
        if 'destination' in _dict:
            args['destination'] = _dict.get('destination')
        else:
            raise ValueError('Required property \'destination\' not present in NetworkACLRuleItemNetworkACLRuleProtocolTCPUDP JSON')
        if 'direction' in _dict:
            args['direction'] = _dict.get('direction')
        else:
            raise ValueError('Required property \'direction\' not present in NetworkACLRuleItemNetworkACLRuleProtocolTCPUDP JSON')
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in NetworkACLRuleItemNetworkACLRuleProtocolTCPUDP JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in NetworkACLRuleItemNetworkACLRuleProtocolTCPUDP JSON')
        if 'ip_version' in _dict:
            args['ip_version'] = _dict.get('ip_version')
        else:
            raise ValueError('Required property \'ip_version\' not present in NetworkACLRuleItemNetworkACLRuleProtocolTCPUDP JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in NetworkACLRuleItemNetworkACLRuleProtocolTCPUDP JSON')
        if 'source' in _dict:
            args['source'] = _dict.get('source')
        else:
            raise ValueError('Required property \'source\' not present in NetworkACLRuleItemNetworkACLRuleProtocolTCPUDP JSON')
        if 'destination_port_max' in _dict:
            args['destination_port_max'] = _dict.get('destination_port_max')
        else:
            raise ValueError('Required property \'destination_port_max\' not present in NetworkACLRuleItemNetworkACLRuleProtocolTCPUDP JSON')
        if 'destination_port_min' in _dict:
            args['destination_port_min'] = _dict.get('destination_port_min')
        else:
            raise ValueError('Required property \'destination_port_min\' not present in NetworkACLRuleItemNetworkACLRuleProtocolTCPUDP JSON')
        if 'protocol' in _dict:
            args['protocol'] = _dict.get('protocol')
        else:
            raise ValueError('Required property \'protocol\' not present in NetworkACLRuleItemNetworkACLRuleProtocolTCPUDP JSON')
        if 'source_port_max' in _dict:
            args['source_port_max'] = _dict.get('source_port_max')
        else:
            raise ValueError('Required property \'source_port_max\' not present in NetworkACLRuleItemNetworkACLRuleProtocolTCPUDP JSON')
        if 'source_port_min' in _dict:
            args['source_port_min'] = _dict.get('source_port_min')
        else:
            raise ValueError('Required property \'source_port_min\' not present in NetworkACLRuleItemNetworkACLRuleProtocolTCPUDP JSON')
        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:
            if isinstance(self.before, dict):
                _dict['before'] = self.before
            else:
                _dict['before'] = self.before.to_dict()
        if hasattr(self, 'created_at') and self.created_at is not None:
            _dict['created_at'] = datetime_to_string(self.created_at)
        if hasattr(self, 'destination') and self.destination is not None:
            _dict['destination'] = self.destination
        if hasattr(self, 'direction') and self.direction is not None:
            _dict['direction'] = self.direction
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'ip_version') and self.ip_version is not None:
            _dict['ip_version'] = self.ip_version
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'source') and self.source is not None:
            _dict['source'] = self.source
        if hasattr(self, 'destination_port_max') and self.destination_port_max is not None:
            _dict['destination_port_max'] = self.destination_port_max
        if hasattr(self, 'destination_port_min') and self.destination_port_min is not None:
            _dict['destination_port_min'] = self.destination_port_min
        if hasattr(self, 'protocol') and self.protocol is not None:
            _dict['protocol'] = self.protocol
        if hasattr(self, 'source_port_max') and self.source_port_max is not None:
            _dict['source_port_max'] = self.source_port_max
        if hasattr(self, 'source_port_min') and self.source_port_min is not None:
            _dict['source_port_min'] = self.source_port_min
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this NetworkACLRuleItemNetworkACLRuleProtocolTCPUDP object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'NetworkACLRuleItemNetworkACLRuleProtocolTCPUDP') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'NetworkACLRuleItemNetworkACLRuleProtocolTCPUDP') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ActionEnum(str, Enum):
        """
        The action to perform for a packet matching the rule.
        """

        ALLOW = 'allow'
        DENY = 'deny'


    class DirectionEnum(str, Enum):
        """
        The direction of traffic to match.
        """

        INBOUND = 'inbound'
        OUTBOUND = 'outbound'


    class IpVersionEnum(str, Enum):
        """
        The IP version for this rule.
        """

        IPV4 = 'ipv4'


    class ProtocolEnum(str, Enum):
        """
        The protocol to enforce.
        """

        TCP = 'tcp'
        UDP = 'udp'



class NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolAllPrototype(NetworkACLRulePrototypeNetworkACLContext):
    """
    NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolAllPrototype.

    :attr str action: The action to perform for a packet matching the rule.
    :attr str destination: The destination IP address or CIDR block to match. The
          CIDR block `0.0.0.0/0` matches all destination addresses.
    :attr str direction: The direction of traffic to match.
    :attr str ip_version: (optional) The IP version for this rule.
    :attr str name: (optional) The name for this network ACL rule. The name must not
          be used by another rule for the network ACL. If unspecified, the name will be a
          hyphenated list of randomly-selected words.
    :attr str source: The source IP address or CIDR block to match. The CIDR block
          `0.0.0.0/0` matches all source addresses.
    :attr str protocol: The protocol to enforce.
    """

    def __init__(
        self,
        action: str,
        destination: str,
        direction: str,
        source: str,
        protocol: str,
        *,
        ip_version: str = None,
        name: str = None,
    ) -> None:
        """
        Initialize a NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolAllPrototype object.

        :param str action: The action to perform for a packet matching the rule.
        :param str destination: The destination IP address or CIDR block to match.
               The CIDR block `0.0.0.0/0` matches all destination addresses.
        :param str direction: The direction of traffic to match.
        :param str source: The source IP address or CIDR block to match. The CIDR
               block `0.0.0.0/0` matches all source addresses.
        :param str protocol: The protocol to enforce.
        :param str ip_version: (optional) The IP version for this rule.
        :param str name: (optional) The name for this network ACL rule. The name
               must not be used by another rule for the network ACL. 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.ip_version = ip_version
        self.name = name
        self.source = source
        self.protocol = protocol

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolAllPrototype':
        """Initialize a NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolAllPrototype object from a json dictionary."""
        args = {}
        if 'action' in _dict:
            args['action'] = _dict.get('action')
        else:
            raise ValueError('Required property \'action\' not present in NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolAllPrototype JSON')
        if 'destination' in _dict:
            args['destination'] = _dict.get('destination')
        else:
            raise ValueError('Required property \'destination\' not present in NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolAllPrototype JSON')
        if 'direction' in _dict:
            args['direction'] = _dict.get('direction')
        else:
            raise ValueError('Required property \'direction\' not present in NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolAllPrototype JSON')
        if 'ip_version' in _dict:
            args['ip_version'] = _dict.get('ip_version')
        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 NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolAllPrototype JSON')
        if 'protocol' in _dict:
            args['protocol'] = _dict.get('protocol')
        else:
            raise ValueError('Required property \'protocol\' not present in NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolAllPrototype JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolAllPrototype object from 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, '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 NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolAllPrototype object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolAllPrototype') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolAllPrototype') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ActionEnum(str, Enum):
        """
        The action to perform for a packet matching the rule.
        """

        ALLOW = 'allow'
        DENY = 'deny'


    class DirectionEnum(str, Enum):
        """
        The direction of traffic to match.
        """

        INBOUND = 'inbound'
        OUTBOUND = 'outbound'


    class IpVersionEnum(str, Enum):
        """
        The IP version for this rule.
        """

        IPV4 = 'ipv4'


    class ProtocolEnum(str, Enum):
        """
        The protocol to enforce.
        """

        ALL = 'all'



class NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolICMPPrototype(NetworkACLRulePrototypeNetworkACLContext):
    """
    NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolICMPPrototype.

    :attr str action: The action to perform for a packet matching the rule.
    :attr str destination: The destination IP address or CIDR block to match. The
          CIDR block `0.0.0.0/0` matches all destination addresses.
    :attr str direction: The direction of traffic to match.
    :attr str ip_version: (optional) The IP version for this rule.
    :attr str name: (optional) The name for this network ACL rule. The name must not
          be used by another rule for the network ACL. If unspecified, the name will be a
          hyphenated list of randomly-selected words.
    :attr str source: The source IP address or CIDR block to match. The CIDR block
          `0.0.0.0/0` matches all source addresses.
    :attr int code: (optional) The ICMP traffic code to match.
          If specified, `type` must also be specified.  If unspecified, all codes are
          matched.
    :attr str protocol: The protocol to enforce.
    :attr int type: (optional) The ICMP traffic type to match.
          If unspecified, all types are matched.
    """

    def __init__(
        self,
        action: str,
        destination: str,
        direction: str,
        source: str,
        protocol: str,
        *,
        ip_version: str = None,
        name: str = None,
        code: int = None,
        type: int = None,
    ) -> None:
        """
        Initialize a NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolICMPPrototype object.

        :param str action: The action to perform for a packet matching the rule.
        :param str destination: The destination IP address or CIDR block to match.
               The CIDR block `0.0.0.0/0` matches all destination addresses.
        :param str direction: The direction of traffic to match.
        :param str source: The source IP address or CIDR block to match. The CIDR
               block `0.0.0.0/0` matches all source addresses.
        :param str protocol: The protocol to enforce.
        :param str ip_version: (optional) The IP version for this rule.
        :param str name: (optional) The name for this network ACL rule. The name
               must not be used by another rule for the network ACL. If unspecified, the
               name will be a hyphenated list of randomly-selected words.
        :param int code: (optional) The ICMP traffic code to match.
               If specified, `type` must also be specified.  If unspecified, all codes are
               matched.
        :param int type: (optional) The ICMP traffic type to match.
               If unspecified, all types are matched.
        """
        # pylint: disable=super-init-not-called
        self.action = action
        self.destination = destination
        self.direction = direction
        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) -> 'NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolICMPPrototype':
        """Initialize a NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolICMPPrototype object from a json dictionary."""
        args = {}
        if 'action' in _dict:
            args['action'] = _dict.get('action')
        else:
            raise ValueError('Required property \'action\' not present in NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolICMPPrototype JSON')
        if 'destination' in _dict:
            args['destination'] = _dict.get('destination')
        else:
            raise ValueError('Required property \'destination\' not present in NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolICMPPrototype JSON')
        if 'direction' in _dict:
            args['direction'] = _dict.get('direction')
        else:
            raise ValueError('Required property \'direction\' not present in NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolICMPPrototype JSON')
        if 'ip_version' in _dict:
            args['ip_version'] = _dict.get('ip_version')
        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 NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolICMPPrototype 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 NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolICMPPrototype JSON')
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolICMPPrototype object from 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, '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 NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolICMPPrototype object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolICMPPrototype') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolICMPPrototype') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ActionEnum(str, Enum):
        """
        The action to perform for a packet matching the rule.
        """

        ALLOW = 'allow'
        DENY = 'deny'


    class DirectionEnum(str, Enum):
        """
        The direction of traffic to match.
        """

        INBOUND = 'inbound'
        OUTBOUND = 'outbound'


    class IpVersionEnum(str, Enum):
        """
        The IP version for this rule.
        """

        IPV4 = 'ipv4'


    class ProtocolEnum(str, Enum):
        """
        The protocol to enforce.
        """

        ICMP = 'icmp'



class NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolTCPUDPPrototype(NetworkACLRulePrototypeNetworkACLContext):
    """
    NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolTCPUDPPrototype.

    :attr str action: The action to perform for a packet matching the rule.
    :attr str destination: The destination IP address or CIDR block to match. The
          CIDR block `0.0.0.0/0` matches all destination addresses.
    :attr str direction: The direction of traffic to match.
    :attr str ip_version: (optional) The IP version for this rule.
    :attr str name: (optional) The name for this network ACL rule. The name must not
          be used by another rule for the network ACL. If unspecified, the name will be a
          hyphenated list of randomly-selected words.
    :attr str source: The source IP address or CIDR block to match. The CIDR block
          `0.0.0.0/0` matches all source addresses.
    :attr int destination_port_max: (optional) The inclusive upper bound of TCP/UDP
          destination port range.
    :attr int destination_port_min: (optional) The inclusive lower bound of TCP/UDP
          destination port range.
    :attr str protocol: The protocol to enforce.
    :attr int source_port_max: (optional) The inclusive upper bound of TCP/UDP
          source port range.
    :attr int source_port_min: (optional) The inclusive lower bound of TCP/UDP
          source port range.
    """

    def __init__(
        self,
        action: str,
        destination: str,
        direction: str,
        source: str,
        protocol: str,
        *,
        ip_version: str = None,
        name: str = None,
        destination_port_max: int = None,
        destination_port_min: int = None,
        source_port_max: int = None,
        source_port_min: int = None,
    ) -> None:
        """
        Initialize a NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolTCPUDPPrototype object.

        :param str action: The action to perform for a packet matching the rule.
        :param str destination: The destination IP address or CIDR block to match.
               The CIDR block `0.0.0.0/0` matches all destination addresses.
        :param str direction: The direction of traffic to match.
        :param str source: The source IP address or CIDR block to match. The CIDR
               block `0.0.0.0/0` matches all source addresses.
        :param str protocol: The protocol to enforce.
        :param str ip_version: (optional) The IP version for this rule.
        :param str name: (optional) The name for this network ACL rule. The name
               must not be used by another rule for the network ACL. If unspecified, the
               name will be a hyphenated list of randomly-selected words.
        :param int destination_port_max: (optional) The inclusive upper bound of
               TCP/UDP destination port range.
        :param int destination_port_min: (optional) The inclusive lower bound of
               TCP/UDP destination port range.
        :param int source_port_max: (optional) The inclusive upper bound of TCP/UDP
               source port range.
        :param int source_port_min: (optional) The inclusive lower bound of TCP/UDP
               source port range.
        """
        # pylint: disable=super-init-not-called
        self.action = action
        self.destination = destination
        self.direction = direction
        self.ip_version = ip_version
        self.name = name
        self.source = source
        self.destination_port_max = destination_port_max
        self.destination_port_min = destination_port_min
        self.protocol = protocol
        self.source_port_max = source_port_max
        self.source_port_min = source_port_min

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolTCPUDPPrototype':
        """Initialize a NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolTCPUDPPrototype object from a json dictionary."""
        args = {}
        if 'action' in _dict:
            args['action'] = _dict.get('action')
        else:
            raise ValueError('Required property \'action\' not present in NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolTCPUDPPrototype JSON')
        if 'destination' in _dict:
            args['destination'] = _dict.get('destination')
        else:
            raise ValueError('Required property \'destination\' not present in NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolTCPUDPPrototype JSON')
        if 'direction' in _dict:
            args['direction'] = _dict.get('direction')
        else:
            raise ValueError('Required property \'direction\' not present in NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolTCPUDPPrototype JSON')
        if 'ip_version' in _dict:
            args['ip_version'] = _dict.get('ip_version')
        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 NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolTCPUDPPrototype JSON')
        if 'destination_port_max' in _dict:
            args['destination_port_max'] = _dict.get('destination_port_max')
        if 'destination_port_min' in _dict:
            args['destination_port_min'] = _dict.get('destination_port_min')
        if 'protocol' in _dict:
            args['protocol'] = _dict.get('protocol')
        else:
            raise ValueError('Required property \'protocol\' not present in NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolTCPUDPPrototype 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 NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolTCPUDPPrototype object from 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, 'ip_version') and self.ip_version is not None:
            _dict['ip_version'] = self.ip_version
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'source') and self.source is not None:
            _dict['source'] = self.source
        if hasattr(self, 'destination_port_max') and self.destination_port_max is not None:
            _dict['destination_port_max'] = self.destination_port_max
        if hasattr(self, 'destination_port_min') and self.destination_port_min is not None:
            _dict['destination_port_min'] = self.destination_port_min
        if hasattr(self, 'protocol') and self.protocol is not None:
            _dict['protocol'] = self.protocol
        if hasattr(self, 'source_port_max') and self.source_port_max is not None:
            _dict['source_port_max'] = self.source_port_max
        if hasattr(self, 'source_port_min') and self.source_port_min is not None:
            _dict['source_port_min'] = self.source_port_min
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolTCPUDPPrototype object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolTCPUDPPrototype') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolTCPUDPPrototype') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ActionEnum(str, Enum):
        """
        The action to perform for a packet matching the rule.
        """

        ALLOW = 'allow'
        DENY = 'deny'


    class DirectionEnum(str, Enum):
        """
        The direction of traffic to match.
        """

        INBOUND = 'inbound'
        OUTBOUND = 'outbound'


    class IpVersionEnum(str, Enum):
        """
        The IP version for this rule.
        """

        IPV4 = 'ipv4'


    class ProtocolEnum(str, Enum):
        """
        The protocol to enforce.
        """

        TCP = 'tcp'
        UDP = 'udp'



class NetworkACLRulePrototypeNetworkACLRuleProtocolAllPrototype(NetworkACLRulePrototype):
    """
    NetworkACLRulePrototypeNetworkACLRuleProtocolAllPrototype.

    :attr str action: The action to perform for a packet matching the rule.
    :attr NetworkACLRuleBeforePrototype before: (optional)
    :attr str destination: The destination IP address or CIDR block to match. The
          CIDR block `0.0.0.0/0` matches all destination addresses.
    :attr str direction: The direction of traffic to match.
    :attr str ip_version: (optional) The IP version for this rule.
    :attr str name: (optional) The name for this network ACL rule. The name must not
          be used by another rule for the network ACL. If unspecified, the name will be a
          hyphenated list of randomly-selected words.
    :attr str source: The source IP address or CIDR block to match. The CIDR block
          `0.0.0.0/0` matches all source addresses.
    :attr str protocol: The protocol to enforce.
    """

    def __init__(
        self,
        action: str,
        destination: str,
        direction: str,
        source: str,
        protocol: str,
        *,
        before: 'NetworkACLRuleBeforePrototype' = None,
        ip_version: str = None,
        name: str = None,
    ) -> None:
        """
        Initialize a NetworkACLRulePrototypeNetworkACLRuleProtocolAllPrototype object.

        :param str action: The action to perform for a packet matching the rule.
        :param str destination: The destination IP address or CIDR block to match.
               The CIDR block `0.0.0.0/0` matches all destination addresses.
        :param str direction: The direction of traffic to match.
        :param str source: The source IP address or CIDR block to match. The CIDR
               block `0.0.0.0/0` matches all source addresses.
        :param str protocol: The protocol to enforce.
        :param NetworkACLRuleBeforePrototype before: (optional)
        :param str ip_version: (optional) The IP version for this rule.
        :param str name: (optional) The name for this network ACL rule. The name
               must not be used by another rule for the network ACL. 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.ip_version = ip_version
        self.name = name
        self.source = source
        self.protocol = protocol

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'NetworkACLRulePrototypeNetworkACLRuleProtocolAllPrototype':
        """Initialize a NetworkACLRulePrototypeNetworkACLRuleProtocolAllPrototype object from a json dictionary."""
        args = {}
        if 'action' in _dict:
            args['action'] = _dict.get('action')
        else:
            raise ValueError('Required property \'action\' not present in NetworkACLRulePrototypeNetworkACLRuleProtocolAllPrototype 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 NetworkACLRulePrototypeNetworkACLRuleProtocolAllPrototype JSON')
        if 'direction' in _dict:
            args['direction'] = _dict.get('direction')
        else:
            raise ValueError('Required property \'direction\' not present in NetworkACLRulePrototypeNetworkACLRuleProtocolAllPrototype JSON')
        if 'ip_version' in _dict:
            args['ip_version'] = _dict.get('ip_version')
        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 NetworkACLRulePrototypeNetworkACLRuleProtocolAllPrototype JSON')
        if 'protocol' in _dict:
            args['protocol'] = _dict.get('protocol')
        else:
            raise ValueError('Required property \'protocol\' not present in NetworkACLRulePrototypeNetworkACLRuleProtocolAllPrototype JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a NetworkACLRulePrototypeNetworkACLRuleProtocolAllPrototype object from 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, '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 NetworkACLRulePrototypeNetworkACLRuleProtocolAllPrototype object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'NetworkACLRulePrototypeNetworkACLRuleProtocolAllPrototype') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'NetworkACLRulePrototypeNetworkACLRuleProtocolAllPrototype') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ActionEnum(str, Enum):
        """
        The action to perform for a packet matching the rule.
        """

        ALLOW = 'allow'
        DENY = 'deny'


    class DirectionEnum(str, Enum):
        """
        The direction of traffic to match.
        """

        INBOUND = 'inbound'
        OUTBOUND = 'outbound'


    class IpVersionEnum(str, Enum):
        """
        The IP version for this rule.
        """

        IPV4 = 'ipv4'


    class ProtocolEnum(str, Enum):
        """
        The protocol to enforce.
        """

        ALL = 'all'



class NetworkACLRulePrototypeNetworkACLRuleProtocolICMPPrototype(NetworkACLRulePrototype):
    """
    NetworkACLRulePrototypeNetworkACLRuleProtocolICMPPrototype.

    :attr str action: The action to perform for a packet matching the rule.
    :attr NetworkACLRuleBeforePrototype before: (optional)
    :attr str destination: The destination IP address or CIDR block to match. The
          CIDR block `0.0.0.0/0` matches all destination addresses.
    :attr str direction: The direction of traffic to match.
    :attr str ip_version: (optional) The IP version for this rule.
    :attr str name: (optional) The name for this network ACL rule. The name must not
          be used by another rule for the network ACL. If unspecified, the name will be a
          hyphenated list of randomly-selected words.
    :attr str source: The source IP address or CIDR block to match. The CIDR block
          `0.0.0.0/0` matches all source addresses.
    :attr int code: (optional) The ICMP traffic code to match.
          If specified, `type` must also be specified.  If unspecified, all codes are
          matched.
    :attr str protocol: The protocol to enforce.
    :attr int type: (optional) The ICMP traffic type to match.
          If unspecified, all types are matched.
    """

    def __init__(
        self,
        action: str,
        destination: str,
        direction: str,
        source: str,
        protocol: str,
        *,
        before: 'NetworkACLRuleBeforePrototype' = None,
        ip_version: str = None,
        name: str = None,
        code: int = None,
        type: int = None,
    ) -> None:
        """
        Initialize a NetworkACLRulePrototypeNetworkACLRuleProtocolICMPPrototype object.

        :param str action: The action to perform for a packet matching the rule.
        :param str destination: The destination IP address or CIDR block to match.
               The CIDR block `0.0.0.0/0` matches all destination addresses.
        :param str direction: The direction of traffic to match.
        :param str source: The source IP address or CIDR block to match. The CIDR
               block `0.0.0.0/0` matches all source addresses.
        :param str protocol: The protocol to enforce.
        :param NetworkACLRuleBeforePrototype before: (optional)
        :param str ip_version: (optional) The IP version for this rule.
        :param str name: (optional) The name for this network ACL rule. The name
               must not be used by another rule for the network ACL. If unspecified, the
               name will be a hyphenated list of randomly-selected words.
        :param int code: (optional) The ICMP traffic code to match.
               If specified, `type` must also be specified.  If unspecified, all codes are
               matched.
        :param int type: (optional) The ICMP traffic type to match.
               If unspecified, all types are matched.
        """
        # pylint: disable=super-init-not-called
        self.action = action
        self.before = before
        self.destination = destination
        self.direction = direction
        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) -> 'NetworkACLRulePrototypeNetworkACLRuleProtocolICMPPrototype':
        """Initialize a NetworkACLRulePrototypeNetworkACLRuleProtocolICMPPrototype object from a json dictionary."""
        args = {}
        if 'action' in _dict:
            args['action'] = _dict.get('action')
        else:
            raise ValueError('Required property \'action\' not present in NetworkACLRulePrototypeNetworkACLRuleProtocolICMPPrototype 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 NetworkACLRulePrototypeNetworkACLRuleProtocolICMPPrototype JSON')
        if 'direction' in _dict:
            args['direction'] = _dict.get('direction')
        else:
            raise ValueError('Required property \'direction\' not present in NetworkACLRulePrototypeNetworkACLRuleProtocolICMPPrototype JSON')
        if 'ip_version' in _dict:
            args['ip_version'] = _dict.get('ip_version')
        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 NetworkACLRulePrototypeNetworkACLRuleProtocolICMPPrototype 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 NetworkACLRulePrototypeNetworkACLRuleProtocolICMPPrototype JSON')
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a NetworkACLRulePrototypeNetworkACLRuleProtocolICMPPrototype object from 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, '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 NetworkACLRulePrototypeNetworkACLRuleProtocolICMPPrototype object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'NetworkACLRulePrototypeNetworkACLRuleProtocolICMPPrototype') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'NetworkACLRulePrototypeNetworkACLRuleProtocolICMPPrototype') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ActionEnum(str, Enum):
        """
        The action to perform for a packet matching the rule.
        """

        ALLOW = 'allow'
        DENY = 'deny'


    class DirectionEnum(str, Enum):
        """
        The direction of traffic to match.
        """

        INBOUND = 'inbound'
        OUTBOUND = 'outbound'


    class IpVersionEnum(str, Enum):
        """
        The IP version for this rule.
        """

        IPV4 = 'ipv4'


    class ProtocolEnum(str, Enum):
        """
        The protocol to enforce.
        """

        ICMP = 'icmp'



class NetworkACLRulePrototypeNetworkACLRuleProtocolTCPUDPPrototype(NetworkACLRulePrototype):
    """
    NetworkACLRulePrototypeNetworkACLRuleProtocolTCPUDPPrototype.

    :attr str action: The action to perform for a packet matching the rule.
    :attr NetworkACLRuleBeforePrototype before: (optional)
    :attr str destination: The destination IP address or CIDR block to match. The
          CIDR block `0.0.0.0/0` matches all destination addresses.
    :attr str direction: The direction of traffic to match.
    :attr str ip_version: (optional) The IP version for this rule.
    :attr str name: (optional) The name for this network ACL rule. The name must not
          be used by another rule for the network ACL. If unspecified, the name will be a
          hyphenated list of randomly-selected words.
    :attr str source: The source IP address or CIDR block to match. The CIDR block
          `0.0.0.0/0` matches all source addresses.
    :attr int destination_port_max: (optional) The inclusive upper bound of TCP/UDP
          destination port range.
    :attr int destination_port_min: (optional) The inclusive lower bound of TCP/UDP
          destination port range.
    :attr str protocol: The protocol to enforce.
    :attr int source_port_max: (optional) The inclusive upper bound of TCP/UDP
          source port range.
    :attr int source_port_min: (optional) The inclusive lower bound of TCP/UDP
          source port range.
    """

    def __init__(
        self,
        action: str,
        destination: str,
        direction: str,
        source: str,
        protocol: str,
        *,
        before: 'NetworkACLRuleBeforePrototype' = None,
        ip_version: str = None,
        name: str = None,
        destination_port_max: int = None,
        destination_port_min: int = None,
        source_port_max: int = None,
        source_port_min: int = None,
    ) -> None:
        """
        Initialize a NetworkACLRulePrototypeNetworkACLRuleProtocolTCPUDPPrototype object.

        :param str action: The action to perform for a packet matching the rule.
        :param str destination: The destination IP address or CIDR block to match.
               The CIDR block `0.0.0.0/0` matches all destination addresses.
        :param str direction: The direction of traffic to match.
        :param str source: The source IP address or CIDR block to match. The CIDR
               block `0.0.0.0/0` matches all source addresses.
        :param str protocol: The protocol to enforce.
        :param NetworkACLRuleBeforePrototype before: (optional)
        :param str ip_version: (optional) The IP version for this rule.
        :param str name: (optional) The name for this network ACL rule. The name
               must not be used by another rule for the network ACL. If unspecified, the
               name will be a hyphenated list of randomly-selected words.
        :param int destination_port_max: (optional) The inclusive upper bound of
               TCP/UDP destination port range.
        :param int destination_port_min: (optional) The inclusive lower bound of
               TCP/UDP destination port range.
        :param int source_port_max: (optional) The inclusive upper bound of TCP/UDP
               source port range.
        :param int source_port_min: (optional) The inclusive lower bound of TCP/UDP
               source port range.
        """
        # pylint: disable=super-init-not-called
        self.action = action
        self.before = before
        self.destination = destination
        self.direction = direction
        self.ip_version = ip_version
        self.name = name
        self.source = source
        self.destination_port_max = destination_port_max
        self.destination_port_min = destination_port_min
        self.protocol = protocol
        self.source_port_max = source_port_max
        self.source_port_min = source_port_min

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'NetworkACLRulePrototypeNetworkACLRuleProtocolTCPUDPPrototype':
        """Initialize a NetworkACLRulePrototypeNetworkACLRuleProtocolTCPUDPPrototype object from a json dictionary."""
        args = {}
        if 'action' in _dict:
            args['action'] = _dict.get('action')
        else:
            raise ValueError('Required property \'action\' not present in NetworkACLRulePrototypeNetworkACLRuleProtocolTCPUDPPrototype 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 NetworkACLRulePrototypeNetworkACLRuleProtocolTCPUDPPrototype JSON')
        if 'direction' in _dict:
            args['direction'] = _dict.get('direction')
        else:
            raise ValueError('Required property \'direction\' not present in NetworkACLRulePrototypeNetworkACLRuleProtocolTCPUDPPrototype JSON')
        if 'ip_version' in _dict:
            args['ip_version'] = _dict.get('ip_version')
        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 NetworkACLRulePrototypeNetworkACLRuleProtocolTCPUDPPrototype JSON')
        if 'destination_port_max' in _dict:
            args['destination_port_max'] = _dict.get('destination_port_max')
        if 'destination_port_min' in _dict:
            args['destination_port_min'] = _dict.get('destination_port_min')
        if 'protocol' in _dict:
            args['protocol'] = _dict.get('protocol')
        else:
            raise ValueError('Required property \'protocol\' not present in NetworkACLRulePrototypeNetworkACLRuleProtocolTCPUDPPrototype 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 NetworkACLRulePrototypeNetworkACLRuleProtocolTCPUDPPrototype object from 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, 'ip_version') and self.ip_version is not None:
            _dict['ip_version'] = self.ip_version
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'source') and self.source is not None:
            _dict['source'] = self.source
        if hasattr(self, 'destination_port_max') and self.destination_port_max is not None:
            _dict['destination_port_max'] = self.destination_port_max
        if hasattr(self, 'destination_port_min') and self.destination_port_min is not None:
            _dict['destination_port_min'] = self.destination_port_min
        if hasattr(self, 'protocol') and self.protocol is not None:
            _dict['protocol'] = self.protocol
        if hasattr(self, 'source_port_max') and self.source_port_max is not None:
            _dict['source_port_max'] = self.source_port_max
        if hasattr(self, 'source_port_min') and self.source_port_min is not None:
            _dict['source_port_min'] = self.source_port_min
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this NetworkACLRulePrototypeNetworkACLRuleProtocolTCPUDPPrototype object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'NetworkACLRulePrototypeNetworkACLRuleProtocolTCPUDPPrototype') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'NetworkACLRulePrototypeNetworkACLRuleProtocolTCPUDPPrototype') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ActionEnum(str, Enum):
        """
        The action to perform for a packet matching the rule.
        """

        ALLOW = 'allow'
        DENY = 'deny'


    class DirectionEnum(str, Enum):
        """
        The direction of traffic to match.
        """

        INBOUND = 'inbound'
        OUTBOUND = 'outbound'


    class IpVersionEnum(str, Enum):
        """
        The IP version for this rule.
        """

        IPV4 = 'ipv4'


    class ProtocolEnum(str, Enum):
        """
        The protocol to enforce.
        """

        TCP = 'tcp'
        UDP = 'udp'



class NetworkACLRuleNetworkACLRuleProtocolAll(NetworkACLRule):
    """
    NetworkACLRuleNetworkACLRuleProtocolAll.

    :attr str action: The action to perform for a packet matching the rule.
    :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 IP address or CIDR block to match. The
          CIDR block `0.0.0.0/0` matches all destination addresses.
    :attr str direction: The direction of traffic to match.
    :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 name for this network ACL rule. The name is unique across
          all rules for the network ACL.
    :attr str source: The source IP address or CIDR block to match. The CIDR block
          `0.0.0.0/0` matches all source 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: The action to perform for a packet matching the rule.
        :param datetime created_at: The date and time that the rule was created.
        :param str destination: The destination IP address or CIDR block to match.
               The CIDR block `0.0.0.0/0` matches all destination addresses.
        :param str direction: The direction of traffic to match.
        :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 name for this network ACL rule. The name is unique
               across all rules for the network ACL.
        :param str source: The source IP address or CIDR block to match. The CIDR
               block `0.0.0.0/0` matches all source 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:
            if isinstance(self.before, dict):
                _dict['before'] = self.before
            else:
                _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):
        """
        The action to perform for a packet matching the rule.
        """

        ALLOW = 'allow'
        DENY = 'deny'


    class DirectionEnum(str, Enum):
        """
        The direction of traffic to match.
        """

        INBOUND = 'inbound'
        OUTBOUND = 'outbound'


    class IpVersionEnum(str, Enum):
        """
        The IP version for this rule.
        """

        IPV4 = 'ipv4'


    class ProtocolEnum(str, Enum):
        """
        The protocol to enforce.
        """

        ALL = 'all'



class NetworkACLRuleNetworkACLRuleProtocolICMP(NetworkACLRule):
    """
    NetworkACLRuleNetworkACLRuleProtocolICMP.

    :attr str action: The action to perform for a packet matching the rule.
    :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 IP address or CIDR block to match. The
          CIDR block `0.0.0.0/0` matches all destination addresses.
    :attr str direction: The direction of traffic to match.
    :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 name for this network ACL rule. The name is unique across
          all rules for the network ACL.
    :attr str source: The source IP address or CIDR block to match. The CIDR block
          `0.0.0.0/0` matches all source addresses.
    :attr int code: (optional) The ICMP traffic code to match.
          If absent, all codes are matched.
    :attr str protocol: The protocol to enforce.
    :attr int type: (optional) The ICMP traffic type to match.
          If absent, all types are matched.
    """

    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: The action to perform for a packet matching the rule.
        :param datetime created_at: The date and time that the rule was created.
        :param str destination: The destination IP address or CIDR block to match.
               The CIDR block `0.0.0.0/0` matches all destination addresses.
        :param str direction: The direction of traffic to match.
        :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 name for this network ACL rule. The name is unique
               across all rules for the network ACL.
        :param str source: The source IP address or CIDR block to match. The CIDR
               block `0.0.0.0/0` matches all source 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 match.
               If absent, all codes are matched.
        :param int type: (optional) The ICMP traffic type to match.
               If absent, all types are matched.
        """
        # 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:
            if isinstance(self.before, dict):
                _dict['before'] = self.before
            else:
                _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):
        """
        The action to perform for a packet matching the rule.
        """

        ALLOW = 'allow'
        DENY = 'deny'


    class DirectionEnum(str, Enum):
        """
        The direction of traffic to match.
        """

        INBOUND = 'inbound'
        OUTBOUND = 'outbound'


    class IpVersionEnum(str, Enum):
        """
        The IP version for this rule.
        """

        IPV4 = 'ipv4'


    class ProtocolEnum(str, Enum):
        """
        The protocol to enforce.
        """

        ICMP = 'icmp'



class NetworkACLRuleNetworkACLRuleProtocolTCPUDP(NetworkACLRule):
    """
    NetworkACLRuleNetworkACLRuleProtocolTCPUDP.

    :attr str action: The action to perform for a packet matching the rule.
    :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 IP address or CIDR block to match. The
          CIDR block `0.0.0.0/0` matches all destination addresses.
    :attr str direction: The direction of traffic to match.
    :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 name for this network ACL rule. The name is unique across
          all rules for the network ACL.
    :attr str source: The source IP address or CIDR block to match. The CIDR block
          `0.0.0.0/0` matches all source addresses.
    :attr int destination_port_max: The inclusive upper bound of TCP/UDP destination
          port range.
    :attr int destination_port_min: The inclusive lower bound of TCP/UDP destination
          port range.
    :attr str protocol: The protocol to enforce.
    :attr int source_port_max: The inclusive upper bound of TCP/UDP source port
          range.
    :attr int source_port_min: 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,
        destination_port_max: int,
        destination_port_min: int,
        protocol: str,
        source_port_max: int,
        source_port_min: int,
        *,
        before: 'NetworkACLRuleReference' = None,
    ) -> None:
        """
        Initialize a NetworkACLRuleNetworkACLRuleProtocolTCPUDP object.

        :param str action: The action to perform for a packet matching the rule.
        :param datetime created_at: The date and time that the rule was created.
        :param str destination: The destination IP address or CIDR block to match.
               The CIDR block `0.0.0.0/0` matches all destination addresses.
        :param str direction: The direction of traffic to match.
        :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 name for this network ACL rule. The name is unique
               across all rules for the network ACL.
        :param str source: The source IP address or CIDR block to match. The CIDR
               block `0.0.0.0/0` matches all source addresses.
        :param int destination_port_max: The inclusive upper bound of TCP/UDP
               destination port range.
        :param int destination_port_min: The inclusive lower bound of TCP/UDP
               destination port range.
        :param str protocol: The protocol to enforce.
        :param int source_port_max: The inclusive upper bound of TCP/UDP source
               port range.
        :param int source_port_min: The inclusive lower bound of TCP/UDP source
               port range.
        :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.destination_port_max = destination_port_max
        self.destination_port_min = destination_port_min
        self.protocol = protocol
        self.source_port_max = source_port_max
        self.source_port_min = source_port_min

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'NetworkACLRuleNetworkACLRuleProtocolTCPUDP':
        """Initialize a NetworkACLRuleNetworkACLRuleProtocolTCPUDP object from a json dictionary."""
        args = {}
        if 'action' in _dict:
            args['action'] = _dict.get('action')
        else:
            raise ValueError('Required property \'action\' not present in NetworkACLRuleNetworkACLRuleProtocolTCPUDP JSON')
        if 'before' in _dict:
            args['before'] = NetworkACLRuleReference.from_dict(_dict.get('before'))
        if 'created_at' in _dict:
            args['created_at'] = string_to_datetime(_dict.get('created_at'))
        else:
            raise ValueError('Required property \'created_at\' not present in NetworkACLRuleNetworkACLRuleProtocolTCPUDP JSON')
        if 'destination' in _dict:
            args['destination'] = _dict.get('destination')
        else:
            raise ValueError('Required property \'destination\' not present in NetworkACLRuleNetworkACLRuleProtocolTCPUDP JSON')
        if 'direction' in _dict:
            args['direction'] = _dict.get('direction')
        else:
            raise ValueError('Required property \'direction\' not present in NetworkACLRuleNetworkACLRuleProtocolTCPUDP JSON')
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in NetworkACLRuleNetworkACLRuleProtocolTCPUDP JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in NetworkACLRuleNetworkACLRuleProtocolTCPUDP JSON')
        if 'ip_version' in _dict:
            args['ip_version'] = _dict.get('ip_version')
        else:
            raise ValueError('Required property \'ip_version\' not present in NetworkACLRuleNetworkACLRuleProtocolTCPUDP JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in NetworkACLRuleNetworkACLRuleProtocolTCPUDP JSON')
        if 'source' in _dict:
            args['source'] = _dict.get('source')
        else:
            raise ValueError('Required property \'source\' not present in NetworkACLRuleNetworkACLRuleProtocolTCPUDP JSON')
        if 'destination_port_max' in _dict:
            args['destination_port_max'] = _dict.get('destination_port_max')
        else:
            raise ValueError('Required property \'destination_port_max\' not present in NetworkACLRuleNetworkACLRuleProtocolTCPUDP JSON')
        if 'destination_port_min' in _dict:
            args['destination_port_min'] = _dict.get('destination_port_min')
        else:
            raise ValueError('Required property \'destination_port_min\' not present in NetworkACLRuleNetworkACLRuleProtocolTCPUDP JSON')
        if 'protocol' in _dict:
            args['protocol'] = _dict.get('protocol')
        else:
            raise ValueError('Required property \'protocol\' not present in NetworkACLRuleNetworkACLRuleProtocolTCPUDP JSON')
        if 'source_port_max' in _dict:
            args['source_port_max'] = _dict.get('source_port_max')
        else:
            raise ValueError('Required property \'source_port_max\' not present in NetworkACLRuleNetworkACLRuleProtocolTCPUDP JSON')
        if 'source_port_min' in _dict:
            args['source_port_min'] = _dict.get('source_port_min')
        else:
            raise ValueError('Required property \'source_port_min\' not present in NetworkACLRuleNetworkACLRuleProtocolTCPUDP JSON')
        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:
            if isinstance(self.before, dict):
                _dict['before'] = self.before
            else:
                _dict['before'] = self.before.to_dict()
        if hasattr(self, 'created_at') and self.created_at is not None:
            _dict['created_at'] = datetime_to_string(self.created_at)
        if hasattr(self, 'destination') and self.destination is not None:
            _dict['destination'] = self.destination
        if hasattr(self, 'direction') and self.direction is not None:
            _dict['direction'] = self.direction
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'ip_version') and self.ip_version is not None:
            _dict['ip_version'] = self.ip_version
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'source') and self.source is not None:
            _dict['source'] = self.source
        if hasattr(self, 'destination_port_max') and self.destination_port_max is not None:
            _dict['destination_port_max'] = self.destination_port_max
        if hasattr(self, 'destination_port_min') and self.destination_port_min is not None:
            _dict['destination_port_min'] = self.destination_port_min
        if hasattr(self, 'protocol') and self.protocol is not None:
            _dict['protocol'] = self.protocol
        if hasattr(self, 'source_port_max') and self.source_port_max is not None:
            _dict['source_port_max'] = self.source_port_max
        if hasattr(self, 'source_port_min') and self.source_port_min is not None:
            _dict['source_port_min'] = self.source_port_min
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this NetworkACLRuleNetworkACLRuleProtocolTCPUDP object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'NetworkACLRuleNetworkACLRuleProtocolTCPUDP') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'NetworkACLRuleNetworkACLRuleProtocolTCPUDP') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ActionEnum(str, Enum):
        """
        The action to perform for a packet matching the rule.
        """

        ALLOW = 'allow'
        DENY = 'deny'


    class DirectionEnum(str, Enum):
        """
        The direction of traffic to match.
        """

        INBOUND = 'inbound'
        OUTBOUND = 'outbound'


    class IpVersionEnum(str, Enum):
        """
        The IP version for this rule.
        """

        IPV4 = 'ipv4'


    class ProtocolEnum(str, Enum):
        """
        The protocol to enforce.
        """

        TCP = 'tcp'
        UDP = 'udp'



class NetworkInterfaceIPPrototypeReservedIPIdentity(NetworkInterfaceIPPrototype):
    """
    Identifies a reserved IP by a unique property.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a NetworkInterfaceIPPrototypeReservedIPIdentity object.

        """
        # pylint: disable=super-init-not-called
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['NetworkInterfaceIPPrototypeReservedIPIdentityById', 'NetworkInterfaceIPPrototypeReservedIPIdentityByHref'])
        )
        raise Exception(msg)


class NetworkInterfaceIPPrototypeReservedIPPrototypeNetworkInterfaceContext(NetworkInterfaceIPPrototype):
    """
    NetworkInterfaceIPPrototypeReservedIPPrototypeNetworkInterfaceContext.

    :attr str address: (optional) The IP address to reserve, which must not already
          be reserved on the subnet.
          If unspecified, an available address on the subnet will automatically be
          selected.
    :attr bool auto_delete: (optional) Indicates whether this reserved IP member
          will be automatically deleted when either
          `target` is deleted, or the reserved IP is unbound.
    :attr str name: (optional) The name for this reserved IP. The name must not be
          used by another reserved IP in the subnet. Names starting with `ibm-` are
          reserved for provider-owned resources, and are not allowed. If unspecified, the
          name will be a hyphenated list of randomly-selected words.
    """

    def __init__(
        self,
        *,
        address: str = None,
        auto_delete: bool = None,
        name: str = None,
    ) -> None:
        """
        Initialize a NetworkInterfaceIPPrototypeReservedIPPrototypeNetworkInterfaceContext object.

        :param str address: (optional) The IP address to reserve, which must not
               already be reserved on the subnet.
               If unspecified, an available address on the subnet will automatically be
               selected.
        :param bool auto_delete: (optional) Indicates whether this reserved IP
               member will be automatically deleted when either
               `target` is deleted, or the reserved IP is unbound.
        :param str name: (optional) The name for this reserved IP. The name must
               not be used by another reserved IP in the subnet. Names starting with
               `ibm-` are reserved for provider-owned resources, and are not allowed. If
               unspecified, the name will be a hyphenated list of randomly-selected words.
        """
        # pylint: disable=super-init-not-called
        self.address = address
        self.auto_delete = auto_delete
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'NetworkInterfaceIPPrototypeReservedIPPrototypeNetworkInterfaceContext':
        """Initialize a NetworkInterfaceIPPrototypeReservedIPPrototypeNetworkInterfaceContext object from a json dictionary."""
        args = {}
        if 'address' in _dict:
            args['address'] = _dict.get('address')
        if 'auto_delete' in _dict:
            args['auto_delete'] = _dict.get('auto_delete')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a NetworkInterfaceIPPrototypeReservedIPPrototypeNetworkInterfaceContext object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'address') and self.address is not None:
            _dict['address'] = self.address
        if hasattr(self, 'auto_delete') and self.auto_delete is not None:
            _dict['auto_delete'] = self.auto_delete
        if hasattr(self, '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 NetworkInterfaceIPPrototypeReservedIPPrototypeNetworkInterfaceContext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'NetworkInterfaceIPPrototypeReservedIPPrototypeNetworkInterfaceContext') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'NetworkInterfaceIPPrototypeReservedIPPrototypeNetworkInterfaceContext') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


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 name for this floating IP. The name must not be
          used by another floating IP in the region. 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) will be
          used.
    """

    def __init__(
        self,
        *,
        name: str = None,
        resource_group: 'ResourceGroupIdentity' = None,
    ) -> None:
        """
        Initialize a PublicGatewayFloatingIPPrototypeFloatingIPPrototypeTargetContext object.

        :param str name: (optional) The name for this floating IP. The name must
               not be used by another floating IP in the region. 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) will be
               used.
        """
        # pylint: disable=super-init-not-called
        self.name = name
        self.resource_group = resource_group

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'PublicGatewayFloatingIPPrototypeFloatingIPPrototypeTargetContext':
        """Initialize a PublicGatewayFloatingIPPrototypeFloatingIPPrototypeTargetContext object from a json dictionary."""
        args = {}
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        if 'resource_group' in _dict:
            args['resource_group'] = _dict.get('resource_group')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a PublicGatewayFloatingIPPrototypeFloatingIPPrototypeTargetContext object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'resource_group') and self.resource_group is not None:
            if isinstance(self.resource_group, dict):
                _dict['resource_group'] = self.resource_group
            else:
                _dict['resource_group'] = self.resource_group.to_dict()
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this PublicGatewayFloatingIPPrototypeFloatingIPPrototypeTargetContext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'PublicGatewayFloatingIPPrototypeFloatingIPPrototypeTargetContext') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'PublicGatewayFloatingIPPrototypeFloatingIPPrototypeTargetContext') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class PublicGatewayIdentityPublicGatewayIdentityByCRN(PublicGatewayIdentity):
    """
    PublicGatewayIdentityPublicGatewayIdentityByCRN.

    :attr str crn: The CRN for this public gateway.
    """

    def __init__(
        self,
        crn: str,
    ) -> None:
        """
        Initialize a PublicGatewayIdentityPublicGatewayIdentityByCRN 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) -> 'PublicGatewayIdentityPublicGatewayIdentityByCRN':
        """Initialize a PublicGatewayIdentityPublicGatewayIdentityByCRN object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError('Required property \'crn\' not present in PublicGatewayIdentityPublicGatewayIdentityByCRN JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a PublicGatewayIdentityPublicGatewayIdentityByCRN object from 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 PublicGatewayIdentityPublicGatewayIdentityByCRN object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'PublicGatewayIdentityPublicGatewayIdentityByCRN') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'PublicGatewayIdentityPublicGatewayIdentityByCRN') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class PublicGatewayIdentityPublicGatewayIdentityByHref(PublicGatewayIdentity):
    """
    PublicGatewayIdentityPublicGatewayIdentityByHref.

    :attr str href: The URL for this public gateway.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a PublicGatewayIdentityPublicGatewayIdentityByHref 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) -> 'PublicGatewayIdentityPublicGatewayIdentityByHref':
        """Initialize a PublicGatewayIdentityPublicGatewayIdentityByHref object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in PublicGatewayIdentityPublicGatewayIdentityByHref JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a PublicGatewayIdentityPublicGatewayIdentityByHref object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(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 PublicGatewayIdentityPublicGatewayIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'PublicGatewayIdentityPublicGatewayIdentityByHref') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'PublicGatewayIdentityPublicGatewayIdentityByHref') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class PublicGatewayIdentityPublicGatewayIdentityById(PublicGatewayIdentity):
    """
    PublicGatewayIdentityPublicGatewayIdentityById.

    :attr str id: The unique identifier for this public gateway.
    """

    def __init__(
        self,
        id: str,
    ) -> None:
        """
        Initialize a PublicGatewayIdentityPublicGatewayIdentityById 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) -> 'PublicGatewayIdentityPublicGatewayIdentityById':
        """Initialize a PublicGatewayIdentityPublicGatewayIdentityById object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in PublicGatewayIdentityPublicGatewayIdentityById JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a PublicGatewayIdentityPublicGatewayIdentityById object from 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 PublicGatewayIdentityPublicGatewayIdentityById object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'PublicGatewayIdentityPublicGatewayIdentityById') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'PublicGatewayIdentityPublicGatewayIdentityById') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class RegionIdentityByHref(RegionIdentity):
    """
    RegionIdentityByHref.

    :attr str href: The URL for this region.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a RegionIdentityByHref object.

        :param str href: The URL for this region.
        """
        # pylint: disable=super-init-not-called
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'RegionIdentityByHref':
        """Initialize a RegionIdentityByHref object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in RegionIdentityByHref JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a RegionIdentityByHref object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(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 RegionIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'RegionIdentityByHref') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'RegionIdentityByHref') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class RegionIdentityByName(RegionIdentity):
    """
    RegionIdentityByName.

    :attr str name: The globally unique name for this region.
    """

    def __init__(
        self,
        name: str,
    ) -> None:
        """
        Initialize a RegionIdentityByName object.

        :param str name: The globally unique name for this region.
        """
        # pylint: disable=super-init-not-called
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'RegionIdentityByName':
        """Initialize a RegionIdentityByName object from a json dictionary."""
        args = {}
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in RegionIdentityByName JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a RegionIdentityByName object from 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 RegionIdentityByName object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'RegionIdentityByName') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'RegionIdentityByName') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class ReservedIPTargetPrototypeEndpointGatewayIdentity(ReservedIPTargetPrototype):
    """
    ReservedIPTargetPrototypeEndpointGatewayIdentity.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a ReservedIPTargetPrototypeEndpointGatewayIdentity object.

        """
        # pylint: disable=super-init-not-called
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['ReservedIPTargetPrototypeEndpointGatewayIdentityEndpointGatewayIdentityById', 'ReservedIPTargetPrototypeEndpointGatewayIdentityEndpointGatewayIdentityByCRN', 'ReservedIPTargetPrototypeEndpointGatewayIdentityEndpointGatewayIdentityByHref'])
        )
        raise Exception(msg)


class ReservedIPTargetBareMetalServerNetworkInterfaceReferenceTargetContext(ReservedIPTarget):
    """
    ReservedIPTargetBareMetalServerNetworkInterfaceReferenceTargetContext.

    :attr BareMetalServerNetworkInterfaceReferenceTargetContextDeleted deleted:
          (optional) If present, this property indicates the referenced resource has been
          deleted, and provides
          some supplementary information.
    :attr str href: The URL for this bare metal server network interface.
    :attr str id: The unique identifier for this bare metal server network
          interface.
    :attr str name: The name for this bare metal server network interface.
    :attr str resource_type: The resource type.
    """

    def __init__(
        self,
        href: str,
        id: str,
        name: str,
        resource_type: str,
        *,
        deleted: 'BareMetalServerNetworkInterfaceReferenceTargetContextDeleted' = None,
    ) -> None:
        """
        Initialize a ReservedIPTargetBareMetalServerNetworkInterfaceReferenceTargetContext object.

        :param str href: The URL for this bare metal server network interface.
        :param str id: The unique identifier for this bare metal server network
               interface.
        :param str name: The name for this bare metal server network interface.
        :param str resource_type: The resource type.
        :param BareMetalServerNetworkInterfaceReferenceTargetContextDeleted
               deleted: (optional) If present, this property indicates the referenced
               resource has been deleted, and provides
               some supplementary information.
        """
        # pylint: disable=super-init-not-called
        self.deleted = deleted
        self.href = href
        self.id = id
        self.name = name
        self.resource_type = resource_type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ReservedIPTargetBareMetalServerNetworkInterfaceReferenceTargetContext':
        """Initialize a ReservedIPTargetBareMetalServerNetworkInterfaceReferenceTargetContext object from a json dictionary."""
        args = {}
        if 'deleted' in _dict:
            args['deleted'] = BareMetalServerNetworkInterfaceReferenceTargetContextDeleted.from_dict(_dict.get('deleted'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in ReservedIPTargetBareMetalServerNetworkInterfaceReferenceTargetContext JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in ReservedIPTargetBareMetalServerNetworkInterfaceReferenceTargetContext JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in ReservedIPTargetBareMetalServerNetworkInterfaceReferenceTargetContext JSON')
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError('Required property \'resource_type\' not present in ReservedIPTargetBareMetalServerNetworkInterfaceReferenceTargetContext JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ReservedIPTargetBareMetalServerNetworkInterfaceReferenceTargetContext object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'deleted') and self.deleted is not None:
            if isinstance(self.deleted, dict):
                _dict['deleted'] = self.deleted
            else:
                _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'resource_type') and self.resource_type is not None:
            _dict['resource_type'] = self.resource_type
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this ReservedIPTargetBareMetalServerNetworkInterfaceReferenceTargetContext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ReservedIPTargetBareMetalServerNetworkInterfaceReferenceTargetContext') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ReservedIPTargetBareMetalServerNetworkInterfaceReferenceTargetContext') -> 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 ReservedIPTargetEndpointGatewayReference(ReservedIPTarget):
    """
    ReservedIPTargetEndpointGatewayReference.

    :attr str crn: The CRN for this endpoint gateway.
    :attr EndpointGatewayReferenceDeleted deleted: (optional) If present, this
          property indicates the referenced resource has been deleted, and provides
          some supplementary information.
    :attr str href: The URL for this endpoint gateway.
    :attr str id: The unique identifier for this endpoint gateway.
    :attr str name: The name for this endpoint gateway. The name is unique across
          all endpoint gateways in the VPC.
    :attr str resource_type: The resource type.
    """

    def __init__(
        self,
        crn: str,
        href: str,
        id: str,
        name: str,
        resource_type: str,
        *,
        deleted: 'EndpointGatewayReferenceDeleted' = None,
    ) -> None:
        """
        Initialize a ReservedIPTargetEndpointGatewayReference object.

        :param str crn: The CRN for this endpoint gateway.
        :param str href: The URL for this endpoint gateway.
        :param str id: The unique identifier for this endpoint gateway.
        :param str name: The name for this endpoint gateway. The name is unique
               across all endpoint gateways in the VPC.
        :param str resource_type: The resource type.
        :param EndpointGatewayReferenceDeleted deleted: (optional) If present, this
               property indicates the referenced resource has been deleted, and provides
               some supplementary information.
        """
        # pylint: disable=super-init-not-called
        self.crn = crn
        self.deleted = deleted
        self.href = href
        self.id = id
        self.name = name
        self.resource_type = resource_type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ReservedIPTargetEndpointGatewayReference':
        """Initialize a ReservedIPTargetEndpointGatewayReference object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError('Required property \'crn\' not present in ReservedIPTargetEndpointGatewayReference JSON')
        if 'deleted' in _dict:
            args['deleted'] = EndpointGatewayReferenceDeleted.from_dict(_dict.get('deleted'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in ReservedIPTargetEndpointGatewayReference JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in ReservedIPTargetEndpointGatewayReference JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in ReservedIPTargetEndpointGatewayReference JSON')
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError('Required property \'resource_type\' not present in ReservedIPTargetEndpointGatewayReference JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ReservedIPTargetEndpointGatewayReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'deleted') and self.deleted is not None:
            if isinstance(self.deleted, dict):
                _dict['deleted'] = self.deleted
            else:
                _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'resource_type') and self.resource_type is not None:
            _dict['resource_type'] = self.resource_type
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this ReservedIPTargetEndpointGatewayReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ReservedIPTargetEndpointGatewayReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ReservedIPTargetEndpointGatewayReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        ENDPOINT_GATEWAY = 'endpoint_gateway'



class ReservedIPTargetGenericResourceReference(ReservedIPTarget):
    """
    Identifying information for a resource that is not native to the VPC API.

    :attr str crn: The CRN for the resource.
    :attr GenericResourceReferenceDeleted deleted: (optional) If present, this
          property indicates the referenced resource has been deleted, and provides
          some supplementary information.
    :attr str resource_type: The resource type.
    """

    def __init__(
        self,
        crn: str,
        resource_type: str,
        *,
        deleted: 'GenericResourceReferenceDeleted' = None,
    ) -> None:
        """
        Initialize a ReservedIPTargetGenericResourceReference object.

        :param str crn: The CRN for the resource.
        :param str resource_type: The resource type.
        :param GenericResourceReferenceDeleted deleted: (optional) If present, this
               property indicates the referenced resource has been deleted, and provides
               some supplementary information.
        """
        # pylint: disable=super-init-not-called
        self.crn = crn
        self.deleted = deleted
        self.resource_type = resource_type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ReservedIPTargetGenericResourceReference':
        """Initialize a ReservedIPTargetGenericResourceReference object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError('Required property \'crn\' not present in ReservedIPTargetGenericResourceReference JSON')
        if 'deleted' in _dict:
            args['deleted'] = GenericResourceReferenceDeleted.from_dict(_dict.get('deleted'))
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError('Required property \'resource_type\' not present in ReservedIPTargetGenericResourceReference JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ReservedIPTargetGenericResourceReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'deleted') and self.deleted is not None:
            if isinstance(self.deleted, dict):
                _dict['deleted'] = self.deleted
            else:
                _dict['deleted'] = self.deleted.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 ReservedIPTargetGenericResourceReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ReservedIPTargetGenericResourceReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ReservedIPTargetGenericResourceReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        CLOUD_RESOURCE = 'cloud_resource'



class ReservedIPTargetLoadBalancerReference(ReservedIPTarget):
    """
    ReservedIPTargetLoadBalancerReference.

    :attr str crn: The load balancer's CRN.
    :attr LoadBalancerReferenceDeleted deleted: (optional) If present, this property
          indicates the referenced resource has been deleted, and provides
          some supplementary information.
    :attr str href: The load balancer's canonical URL.
    :attr str id: The unique identifier for this load balancer.
    :attr str name: The name for this load balancer. The name is unique across all
          load balancers in the VPC.
    :attr str resource_type: The resource type.
    """

    def __init__(
        self,
        crn: str,
        href: str,
        id: str,
        name: str,
        resource_type: str,
        *,
        deleted: 'LoadBalancerReferenceDeleted' = None,
    ) -> None:
        """
        Initialize a ReservedIPTargetLoadBalancerReference object.

        :param str crn: The load balancer's CRN.
        :param str href: The load balancer's canonical URL.
        :param str id: The unique identifier for this load balancer.
        :param str name: The name for this load balancer. The name is unique across
               all load balancers in the VPC.
        :param str resource_type: The resource type.
        :param LoadBalancerReferenceDeleted deleted: (optional) If present, this
               property indicates the referenced resource has been deleted, and provides
               some supplementary information.
        """
        # pylint: disable=super-init-not-called
        self.crn = crn
        self.deleted = deleted
        self.href = href
        self.id = id
        self.name = name
        self.resource_type = resource_type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ReservedIPTargetLoadBalancerReference':
        """Initialize a ReservedIPTargetLoadBalancerReference object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError('Required property \'crn\' not present in ReservedIPTargetLoadBalancerReference JSON')
        if 'deleted' in _dict:
            args['deleted'] = LoadBalancerReferenceDeleted.from_dict(_dict.get('deleted'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in ReservedIPTargetLoadBalancerReference JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in ReservedIPTargetLoadBalancerReference JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in ReservedIPTargetLoadBalancerReference JSON')
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError('Required property \'resource_type\' not present in ReservedIPTargetLoadBalancerReference JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ReservedIPTargetLoadBalancerReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'deleted') and self.deleted is not None:
            if isinstance(self.deleted, dict):
                _dict['deleted'] = self.deleted
            else:
                _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'resource_type') and self.resource_type is not None:
            _dict['resource_type'] = self.resource_type
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this ReservedIPTargetLoadBalancerReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ReservedIPTargetLoadBalancerReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ReservedIPTargetLoadBalancerReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        LOAD_BALANCER = 'load_balancer'



class ReservedIPTargetNetworkInterfaceReferenceTargetContext(ReservedIPTarget):
    """
    ReservedIPTargetNetworkInterfaceReferenceTargetContext.

    :attr NetworkInterfaceReferenceTargetContextDeleted deleted: (optional) If
          present, this property indicates the referenced resource has been deleted, and
          provides
          some supplementary information.
    :attr str href: The URL for this instance network interface.
    :attr str id: The unique identifier for this instance network interface.
    :attr str name: The name for this instance network interface.
    :attr str resource_type: The resource type.
    """

    def __init__(
        self,
        href: str,
        id: str,
        name: str,
        resource_type: str,
        *,
        deleted: 'NetworkInterfaceReferenceTargetContextDeleted' = None,
    ) -> None:
        """
        Initialize a ReservedIPTargetNetworkInterfaceReferenceTargetContext object.

        :param str href: The URL for this instance network interface.
        :param str id: The unique identifier for this instance network interface.
        :param str name: The name for this instance network interface.
        :param str resource_type: The resource type.
        :param NetworkInterfaceReferenceTargetContextDeleted deleted: (optional) If
               present, this property indicates the referenced resource has been deleted,
               and provides
               some supplementary information.
        """
        # pylint: disable=super-init-not-called
        self.deleted = deleted
        self.href = href
        self.id = id
        self.name = name
        self.resource_type = resource_type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ReservedIPTargetNetworkInterfaceReferenceTargetContext':
        """Initialize a ReservedIPTargetNetworkInterfaceReferenceTargetContext object from a json dictionary."""
        args = {}
        if 'deleted' in _dict:
            args['deleted'] = NetworkInterfaceReferenceTargetContextDeleted.from_dict(_dict.get('deleted'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in ReservedIPTargetNetworkInterfaceReferenceTargetContext JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in ReservedIPTargetNetworkInterfaceReferenceTargetContext JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in ReservedIPTargetNetworkInterfaceReferenceTargetContext JSON')
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError('Required property \'resource_type\' not present in ReservedIPTargetNetworkInterfaceReferenceTargetContext JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ReservedIPTargetNetworkInterfaceReferenceTargetContext object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'deleted') and self.deleted is not None:
            if isinstance(self.deleted, dict):
                _dict['deleted'] = self.deleted
            else:
                _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'resource_type') and self.resource_type is not None:
            _dict['resource_type'] = self.resource_type
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this ReservedIPTargetNetworkInterfaceReferenceTargetContext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ReservedIPTargetNetworkInterfaceReferenceTargetContext') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ReservedIPTargetNetworkInterfaceReferenceTargetContext') -> 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 ReservedIPTargetVPNGatewayReference(ReservedIPTarget):
    """
    ReservedIPTargetVPNGatewayReference.

    :attr str crn: The VPN gateway's CRN.
    :attr VPNGatewayReferenceDeleted deleted: (optional) If present, this property
          indicates the referenced resource has been deleted, and provides
          some supplementary information.
    :attr str href: The VPN gateway's canonical URL.
    :attr str id: The unique identifier for this VPN gateway.
    :attr str name: The name for this VPN gateway. The name is unique across all VPN
          gateways in the VPC.
    :attr str resource_type: The resource type.
    """

    def __init__(
        self,
        crn: str,
        href: str,
        id: str,
        name: str,
        resource_type: str,
        *,
        deleted: 'VPNGatewayReferenceDeleted' = None,
    ) -> None:
        """
        Initialize a ReservedIPTargetVPNGatewayReference object.

        :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 str name: The name for this VPN gateway. The name is unique across
               all VPN gateways in the VPC.
        :param str resource_type: The resource type.
        :param VPNGatewayReferenceDeleted deleted: (optional) If present, this
               property indicates the referenced resource has been deleted, and provides
               some supplementary information.
        """
        # pylint: disable=super-init-not-called
        self.crn = crn
        self.deleted = deleted
        self.href = href
        self.id = id
        self.name = name
        self.resource_type = resource_type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ReservedIPTargetVPNGatewayReference':
        """Initialize a ReservedIPTargetVPNGatewayReference object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError('Required property \'crn\' not present in ReservedIPTargetVPNGatewayReference JSON')
        if 'deleted' in _dict:
            args['deleted'] = VPNGatewayReferenceDeleted.from_dict(_dict.get('deleted'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in ReservedIPTargetVPNGatewayReference JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in ReservedIPTargetVPNGatewayReference JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in ReservedIPTargetVPNGatewayReference JSON')
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError('Required property \'resource_type\' not present in ReservedIPTargetVPNGatewayReference JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ReservedIPTargetVPNGatewayReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'deleted') and self.deleted is not None:
            if isinstance(self.deleted, dict):
                _dict['deleted'] = self.deleted
            else:
                _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'resource_type') and self.resource_type is not None:
            _dict['resource_type'] = self.resource_type
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this ReservedIPTargetVPNGatewayReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ReservedIPTargetVPNGatewayReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ReservedIPTargetVPNGatewayReference') -> 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 ReservedIPTargetVPNServerReference(ReservedIPTarget):
    """
    ReservedIPTargetVPNServerReference.

    :attr str crn: The CRN for this VPN server.
    :attr VPNServerReferenceDeleted deleted: (optional) If present, this property
          indicates the referenced resource has been deleted, and provides
          some supplementary information.
    :attr str href: The URL for this VPN server.
    :attr str id: The unique identifier for this VPN server.
    :attr str name: The name for this VPN server. The name is unique across all VPN
          servers in the VPC.
    :attr str resource_type: The resource type.
    """

    def __init__(
        self,
        crn: str,
        href: str,
        id: str,
        name: str,
        resource_type: str,
        *,
        deleted: 'VPNServerReferenceDeleted' = None,
    ) -> None:
        """
        Initialize a ReservedIPTargetVPNServerReference object.

        :param str crn: The CRN for this VPN server.
        :param str href: The URL for this VPN server.
        :param str id: The unique identifier for this VPN server.
        :param str name: The name for this VPN server. The name is unique across
               all VPN servers in the VPC.
        :param str resource_type: The resource type.
        :param VPNServerReferenceDeleted deleted: (optional) If present, this
               property indicates the referenced resource has been deleted, and provides
               some supplementary information.
        """
        # pylint: disable=super-init-not-called
        self.crn = crn
        self.deleted = deleted
        self.href = href
        self.id = id
        self.name = name
        self.resource_type = resource_type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ReservedIPTargetVPNServerReference':
        """Initialize a ReservedIPTargetVPNServerReference object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError('Required property \'crn\' not present in ReservedIPTargetVPNServerReference JSON')
        if 'deleted' in _dict:
            args['deleted'] = VPNServerReferenceDeleted.from_dict(_dict.get('deleted'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in ReservedIPTargetVPNServerReference JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in ReservedIPTargetVPNServerReference JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in ReservedIPTargetVPNServerReference JSON')
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError('Required property \'resource_type\' not present in ReservedIPTargetVPNServerReference JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ReservedIPTargetVPNServerReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'deleted') and self.deleted is not None:
            if isinstance(self.deleted, dict):
                _dict['deleted'] = self.deleted
            else:
                _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'resource_type') and self.resource_type is not None:
            _dict['resource_type'] = self.resource_type
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this ReservedIPTargetVPNServerReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ReservedIPTargetVPNServerReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ReservedIPTargetVPNServerReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        VPN_SERVER = 'vpn_server'



class ReservedIPTargetVirtualNetworkInterfaceReferenceReservedIPTargetContext(ReservedIPTarget):
    """
    ReservedIPTargetVirtualNetworkInterfaceReferenceReservedIPTargetContext.

    :attr str crn: The CRN for this virtual network interface.
    :attr str href: The URL for this virtual network interface.
    :attr str id: The unique identifier for this virtual network interface.
    :attr str name: The name for this virtual network interface. The name is unique
          across all virtual network interfaces in the VPC.
    :attr str resource_type: The resource type.
    """

    def __init__(
        self,
        crn: str,
        href: str,
        id: str,
        name: str,
        resource_type: str,
    ) -> None:
        """
        Initialize a ReservedIPTargetVirtualNetworkInterfaceReferenceReservedIPTargetContext object.

        :param str crn: The CRN for this virtual network interface.
        :param str href: The URL for this virtual network interface.
        :param str id: The unique identifier for this virtual network interface.
        :param str name: The name for this virtual network interface. The name is
               unique across all virtual network interfaces in the VPC.
        :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) -> 'ReservedIPTargetVirtualNetworkInterfaceReferenceReservedIPTargetContext':
        """Initialize a ReservedIPTargetVirtualNetworkInterfaceReferenceReservedIPTargetContext object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError('Required property \'crn\' not present in ReservedIPTargetVirtualNetworkInterfaceReferenceReservedIPTargetContext JSON')
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in ReservedIPTargetVirtualNetworkInterfaceReferenceReservedIPTargetContext JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in ReservedIPTargetVirtualNetworkInterfaceReferenceReservedIPTargetContext JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in ReservedIPTargetVirtualNetworkInterfaceReferenceReservedIPTargetContext JSON')
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError('Required property \'resource_type\' not present in ReservedIPTargetVirtualNetworkInterfaceReferenceReservedIPTargetContext JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ReservedIPTargetVirtualNetworkInterfaceReferenceReservedIPTargetContext object from 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 ReservedIPTargetVirtualNetworkInterfaceReferenceReservedIPTargetContext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ReservedIPTargetVirtualNetworkInterfaceReferenceReservedIPTargetContext') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ReservedIPTargetVirtualNetworkInterfaceReferenceReservedIPTargetContext') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        VIRTUAL_NETWORK_INTERFACE = 'virtual_network_interface'



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 RouteCreatorVPNGatewayReference(RouteCreator):
    """
    RouteCreatorVPNGatewayReference.

    :attr str crn: The VPN gateway's CRN.
    :attr VPNGatewayReferenceDeleted deleted: (optional) If present, this property
          indicates the referenced resource has been deleted, and provides
          some supplementary information.
    :attr str href: The VPN gateway's canonical URL.
    :attr str id: The unique identifier for this VPN gateway.
    :attr str name: The name for this VPN gateway. The name is unique across all VPN
          gateways in the VPC.
    :attr str resource_type: The resource type.
    """

    def __init__(
        self,
        crn: str,
        href: str,
        id: str,
        name: str,
        resource_type: str,
        *,
        deleted: 'VPNGatewayReferenceDeleted' = None,
    ) -> None:
        """
        Initialize a RouteCreatorVPNGatewayReference object.

        :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 str name: The name for this VPN gateway. The name is unique across
               all VPN gateways in the VPC.
        :param str resource_type: The resource type.
        :param VPNGatewayReferenceDeleted deleted: (optional) If present, this
               property indicates the referenced resource has been deleted, and provides
               some supplementary information.
        """
        # pylint: disable=super-init-not-called
        self.crn = crn
        self.deleted = deleted
        self.href = href
        self.id = id
        self.name = name
        self.resource_type = resource_type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'RouteCreatorVPNGatewayReference':
        """Initialize a RouteCreatorVPNGatewayReference object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError('Required property \'crn\' not present in RouteCreatorVPNGatewayReference JSON')
        if 'deleted' in _dict:
            args['deleted'] = VPNGatewayReferenceDeleted.from_dict(_dict.get('deleted'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in RouteCreatorVPNGatewayReference JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in RouteCreatorVPNGatewayReference JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in RouteCreatorVPNGatewayReference JSON')
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError('Required property \'resource_type\' not present in RouteCreatorVPNGatewayReference JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a RouteCreatorVPNGatewayReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'deleted') and self.deleted is not None:
            if isinstance(self.deleted, dict):
                _dict['deleted'] = self.deleted
            else:
                _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'resource_type') and self.resource_type is not None:
            _dict['resource_type'] = self.resource_type
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this RouteCreatorVPNGatewayReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'RouteCreatorVPNGatewayReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'RouteCreatorVPNGatewayReference') -> 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 RouteCreatorVPNServerReference(RouteCreator):
    """
    RouteCreatorVPNServerReference.

    :attr str crn: The CRN for this VPN server.
    :attr VPNServerReferenceDeleted deleted: (optional) If present, this property
          indicates the referenced resource has been deleted, and provides
          some supplementary information.
    :attr str href: The URL for this VPN server.
    :attr str id: The unique identifier for this VPN server.
    :attr str name: The name for this VPN server. The name is unique across all VPN
          servers in the VPC.
    :attr str resource_type: The resource type.
    """

    def __init__(
        self,
        crn: str,
        href: str,
        id: str,
        name: str,
        resource_type: str,
        *,
        deleted: 'VPNServerReferenceDeleted' = None,
    ) -> None:
        """
        Initialize a RouteCreatorVPNServerReference object.

        :param str crn: The CRN for this VPN server.
        :param str href: The URL for this VPN server.
        :param str id: The unique identifier for this VPN server.
        :param str name: The name for this VPN server. The name is unique across
               all VPN servers in the VPC.
        :param str resource_type: The resource type.
        :param VPNServerReferenceDeleted deleted: (optional) If present, this
               property indicates the referenced resource has been deleted, and provides
               some supplementary information.
        """
        # pylint: disable=super-init-not-called
        self.crn = crn
        self.deleted = deleted
        self.href = href
        self.id = id
        self.name = name
        self.resource_type = resource_type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'RouteCreatorVPNServerReference':
        """Initialize a RouteCreatorVPNServerReference object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError('Required property \'crn\' not present in RouteCreatorVPNServerReference JSON')
        if 'deleted' in _dict:
            args['deleted'] = VPNServerReferenceDeleted.from_dict(_dict.get('deleted'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in RouteCreatorVPNServerReference JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in RouteCreatorVPNServerReference JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in RouteCreatorVPNServerReference JSON')
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError('Required property \'resource_type\' not present in RouteCreatorVPNServerReference JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a RouteCreatorVPNServerReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'deleted') and self.deleted is not None:
            if isinstance(self.deleted, dict):
                _dict['deleted'] = self.deleted
            else:
                _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'resource_type') and self.resource_type is not None:
            _dict['resource_type'] = self.resource_type
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this RouteCreatorVPNServerReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'RouteCreatorVPNServerReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'RouteCreatorVPNServerReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        VPN_SERVER = 'vpn_server'



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 RouteNextHopPatchRouteNextHopIP(RouteNextHopPatch):
    """
    RouteNextHopPatchRouteNextHopIP.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a RouteNextHopPatchRouteNextHopIP object.

        """
        # pylint: disable=super-init-not-called
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['RouteNextHopPatchRouteNextHopIPRouteNextHopIPSentinelIP', 'RouteNextHopPatchRouteNextHopIPRouteNextHopIPUnicastIP'])
        )
        raise Exception(msg)


class RouteNextHopPatchVPNGatewayConnectionIdentity(RouteNextHopPatch):
    """
    Identifies a VPN gateway connection by a unique property.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a RouteNextHopPatchVPNGatewayConnectionIdentity object.

        """
        # pylint: disable=super-init-not-called
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['RouteNextHopPatchVPNGatewayConnectionIdentityVPNGatewayConnectionIdentityById', 'RouteNextHopPatchVPNGatewayConnectionIdentityVPNGatewayConnectionIdentityByHref'])
        )
        raise Exception(msg)


class RouteNextHopVPNGatewayConnectionReference(RouteNextHop):
    """
    RouteNextHopVPNGatewayConnectionReference.

    :attr VPNGatewayConnectionReferenceDeleted deleted: (optional) If present, this
          property indicates the referenced resource has been deleted, and provides
          some supplementary information.
    :attr str href: The VPN connection's canonical URL.
    :attr str id: The unique identifier for this VPN gateway connection.
    :attr str name: The name for this VPN gateway connection. The name is unique
          across all connections for the VPN gateway.
    :attr str resource_type: The resource type.
    """

    def __init__(
        self,
        href: str,
        id: str,
        name: str,
        resource_type: str,
        *,
        deleted: 'VPNGatewayConnectionReferenceDeleted' = None,
    ) -> None:
        """
        Initialize a RouteNextHopVPNGatewayConnectionReference object.

        :param str href: The VPN connection's canonical URL.
        :param str id: The unique identifier for this VPN gateway connection.
        :param str name: The name for this VPN gateway connection. The name is
               unique across all connections for the VPN gateway.
        :param str resource_type: The resource type.
        :param VPNGatewayConnectionReferenceDeleted deleted: (optional) If present,
               this property indicates the referenced resource has been deleted, and
               provides
               some supplementary information.
        """
        # pylint: disable=super-init-not-called
        self.deleted = deleted
        self.href = href
        self.id = id
        self.name = name
        self.resource_type = resource_type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'RouteNextHopVPNGatewayConnectionReference':
        """Initialize a RouteNextHopVPNGatewayConnectionReference object from a json dictionary."""
        args = {}
        if 'deleted' in _dict:
            args['deleted'] = VPNGatewayConnectionReferenceDeleted.from_dict(_dict.get('deleted'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in RouteNextHopVPNGatewayConnectionReference JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in RouteNextHopVPNGatewayConnectionReference JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in RouteNextHopVPNGatewayConnectionReference JSON')
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError('Required property \'resource_type\' not present in RouteNextHopVPNGatewayConnectionReference JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a RouteNextHopVPNGatewayConnectionReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'deleted') and self.deleted is not None:
            if isinstance(self.deleted, dict):
                _dict['deleted'] = self.deleted
            else:
                _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'resource_type') and self.resource_type is not None:
            _dict['resource_type'] = self.resource_type
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this RouteNextHopVPNGatewayConnectionReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'RouteNextHopVPNGatewayConnectionReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'RouteNextHopVPNGatewayConnectionReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        VPN_GATEWAY_CONNECTION = 'vpn_gateway_connection'



class RoutePrototypeNextHopRouteNextHopPrototypeRouteNextHopIP(RoutePrototypeNextHop):
    """
    RoutePrototypeNextHopRouteNextHopPrototypeRouteNextHopIP.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a RoutePrototypeNextHopRouteNextHopPrototypeRouteNextHopIP object.

        """
        # pylint: disable=super-init-not-called
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['RoutePrototypeNextHopRouteNextHopPrototypeRouteNextHopIPRouteNextHopPrototypeRouteNextHopIPRouteNextHopIPSentinelIP', 'RoutePrototypeNextHopRouteNextHopPrototypeRouteNextHopIPRouteNextHopPrototypeRouteNextHopIPRouteNextHopIPUnicastIP'])
        )
        raise Exception(msg)


class RoutePrototypeNextHopRouteNextHopPrototypeVPNGatewayConnectionIdentity(RoutePrototypeNextHop):
    """
    Identifies a VPN gateway connection by a unique property.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a RoutePrototypeNextHopRouteNextHopPrototypeVPNGatewayConnectionIdentity object.

        """
        # pylint: disable=super-init-not-called
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['RoutePrototypeNextHopRouteNextHopPrototypeVPNGatewayConnectionIdentityRouteNextHopPrototypeVPNGatewayConnectionIdentityVPNGatewayConnectionIdentityById', 'RoutePrototypeNextHopRouteNextHopPrototypeVPNGatewayConnectionIdentityRouteNextHopPrototypeVPNGatewayConnectionIdentityVPNGatewayConnectionIdentityByHref'])
        )
        raise Exception(msg)


class RoutingTableIdentityByHref(RoutingTableIdentity):
    """
    RoutingTableIdentityByHref.

    :attr str href: The URL for this routing table.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a RoutingTableIdentityByHref object.

        :param str href: The URL for this routing table.
        """
        # pylint: disable=super-init-not-called
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'RoutingTableIdentityByHref':
        """Initialize a RoutingTableIdentityByHref object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in RoutingTableIdentityByHref JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a RoutingTableIdentityByHref object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this RoutingTableIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'RoutingTableIdentityByHref') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'RoutingTableIdentityByHref') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class RoutingTableIdentityById(RoutingTableIdentity):
    """
    RoutingTableIdentityById.

    :attr str id: The unique identifier for this routing table.
    """

    def __init__(
        self,
        id: str,
    ) -> None:
        """
        Initialize a RoutingTableIdentityById object.

        :param str id: The unique identifier for this routing table.
        """
        # pylint: disable=super-init-not-called
        self.id = id

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'RoutingTableIdentityById':
        """Initialize a RoutingTableIdentityById object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in RoutingTableIdentityById JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a RoutingTableIdentityById object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this RoutingTableIdentityById object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'RoutingTableIdentityById') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'RoutingTableIdentityById') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class SecurityGroupIdentityByCRN(SecurityGroupIdentity):
    """
    SecurityGroupIdentityByCRN.

    :attr str crn: The security group's CRN.
    """

    def __init__(
        self,
        crn: str,
    ) -> None:
        """
        Initialize a SecurityGroupIdentityByCRN object.

        :param str crn: The security group's CRN.
        """
        # pylint: disable=super-init-not-called
        self.crn = crn

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'SecurityGroupIdentityByCRN':
        """Initialize a SecurityGroupIdentityByCRN object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError('Required property \'crn\' not present in SecurityGroupIdentityByCRN JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SecurityGroupIdentityByCRN object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this SecurityGroupIdentityByCRN object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'SecurityGroupIdentityByCRN') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'SecurityGroupIdentityByCRN') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class SecurityGroupIdentityByHref(SecurityGroupIdentity):
    """
    SecurityGroupIdentityByHref.

    :attr str href: The security group's canonical URL.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a SecurityGroupIdentityByHref object.

        :param str href: The security group's canonical URL.
        """
        # pylint: disable=super-init-not-called
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'SecurityGroupIdentityByHref':
        """Initialize a SecurityGroupIdentityByHref object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in SecurityGroupIdentityByHref JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SecurityGroupIdentityByHref object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this SecurityGroupIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'SecurityGroupIdentityByHref') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'SecurityGroupIdentityByHref') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class SecurityGroupIdentityById(SecurityGroupIdentity):
    """
    SecurityGroupIdentityById.

    :attr str id: The unique identifier for this security group.
    """

    def __init__(
        self,
        id: str,
    ) -> None:
        """
        Initialize a SecurityGroupIdentityById object.

        :param str id: The unique identifier for this security group.
        """
        # pylint: disable=super-init-not-called
        self.id = id

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'SecurityGroupIdentityById':
        """Initialize a SecurityGroupIdentityById object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in SecurityGroupIdentityById JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SecurityGroupIdentityById object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this SecurityGroupIdentityById object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'SecurityGroupIdentityById') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'SecurityGroupIdentityById') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class SecurityGroupRulePrototypeSecurityGroupRuleProtocolAll(SecurityGroupRulePrototype):
    """
    A rule allowing traffic for all supported protocols.

    :attr str direction: The direction of traffic to enforce.
    :attr str ip_version: (optional) The IP version to enforce. The format of
          `remote.address` or `remote.cidr_block` must match this property, 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: The protocol to enforce.
    :attr SecurityGroupRuleRemotePrototype remote: (optional) The remote 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 within the VPC.
          If unspecified, a CIDR block of `0.0.0.0/0` will be used to allow traffic from
          any source
          (or to any destination, for outbound rules).
    """

    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.
        :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 property, 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) The remote 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 within the VPC.
               If unspecified, a CIDR block of `0.0.0.0/0` will be used to allow traffic
               from any source
               (or to any destination, for outbound rules).
        """
        # pylint: disable=super-init-not-called
        self.direction = direction
        self.ip_version = ip_version
        self.protocol = protocol
        self.remote = remote

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'SecurityGroupRulePrototypeSecurityGroupRuleProtocolAll':
        """Initialize a SecurityGroupRulePrototypeSecurityGroupRuleProtocolAll object from a json dictionary."""
        args = {}
        if 'direction' in _dict:
            args['direction'] = _dict.get('direction')
        else:
            raise ValueError('Required property \'direction\' not present in SecurityGroupRulePrototypeSecurityGroupRuleProtocolAll JSON')
        if 'ip_version' in _dict:
            args['ip_version'] = _dict.get('ip_version')
        if 'protocol' in _dict:
            args['protocol'] = _dict.get('protocol')
        else:
            raise ValueError('Required property \'protocol\' not present in SecurityGroupRulePrototypeSecurityGroupRuleProtocolAll JSON')
        if 'remote' in _dict:
            args['remote'] = _dict.get('remote')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SecurityGroupRulePrototypeSecurityGroupRuleProtocolAll object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'direction') and self.direction is not None:
            _dict['direction'] = self.direction
        if hasattr(self, 'ip_version') and self.ip_version is not None:
            _dict['ip_version'] = self.ip_version
        if hasattr(self, 'protocol') and self.protocol is not None:
            _dict['protocol'] = self.protocol
        if hasattr(self, 'remote') and self.remote is not None:
            if isinstance(self.remote, dict):
                _dict['remote'] = self.remote
            else:
                _dict['remote'] = self.remote.to_dict()
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this SecurityGroupRulePrototypeSecurityGroupRuleProtocolAll object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'SecurityGroupRulePrototypeSecurityGroupRuleProtocolAll') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'SecurityGroupRulePrototypeSecurityGroupRuleProtocolAll') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class DirectionEnum(str, Enum):
        """
        The direction of traffic to enforce.
        """

        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 property, 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):
    """
    A rule specifying the ICMP traffic to allow.

    :attr int code: (optional) The ICMP traffic code to allow.
          If specified, `type` must also be specified.  If unspecified, all codes are
          allowed.
    :attr str direction: The direction of traffic to enforce.
    :attr str ip_version: (optional) The IP version to enforce. The format of
          `remote.address` or `remote.cidr_block` must match this property, 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: The protocol to enforce.
    :attr SecurityGroupRuleRemotePrototype remote: (optional) The remote 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 within the VPC.
          If unspecified, a CIDR block of `0.0.0.0/0` will be used to allow traffic from
          any source
          (or to any destination, for outbound rules).
    :attr int type: (optional) The ICMP traffic type to allow.
          If unspecified, all types are allowed.
    """

    def __init__(
        self,
        direction: str,
        protocol: str,
        *,
        code: int = None,
        ip_version: str = None,
        remote: 'SecurityGroupRuleRemotePrototype' = None,
        type: int = None,
    ) -> None:
        """
        Initialize a SecurityGroupRulePrototypeSecurityGroupRuleProtocolICMP object.

        :param str direction: The direction of traffic to enforce.
        :param str protocol: The protocol to enforce.
        :param int code: (optional) The ICMP traffic code to allow.
               If specified, `type` must also be specified.  If unspecified, all codes are
               allowed.
        :param str ip_version: (optional) The IP version to enforce. The format of
               `remote.address` or `remote.cidr_block` must match this property, 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) The remote 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 within the VPC.
               If unspecified, a CIDR block of `0.0.0.0/0` will be used to allow traffic
               from any source
               (or to any destination, for outbound rules).
        :param int type: (optional) The ICMP traffic type to allow.
               If unspecified, all types are allowed.
        """
        # pylint: disable=super-init-not-called
        self.code = code
        self.direction = direction
        self.ip_version = ip_version
        self.protocol = protocol
        self.remote = remote
        self.type = type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'SecurityGroupRulePrototypeSecurityGroupRuleProtocolICMP':
        """Initialize a SecurityGroupRulePrototypeSecurityGroupRuleProtocolICMP object from a json dictionary."""
        args = {}
        if 'code' in _dict:
            args['code'] = _dict.get('code')
        if 'direction' in _dict:
            args['direction'] = _dict.get('direction')
        else:
            raise ValueError('Required property \'direction\' not present in SecurityGroupRulePrototypeSecurityGroupRuleProtocolICMP JSON')
        if 'ip_version' in _dict:
            args['ip_version'] = _dict.get('ip_version')
        if 'protocol' in _dict:
            args['protocol'] = _dict.get('protocol')
        else:
            raise ValueError('Required property \'protocol\' not present in SecurityGroupRulePrototypeSecurityGroupRuleProtocolICMP JSON')
        if 'remote' in _dict:
            args['remote'] = _dict.get('remote')
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a 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, 'code') and self.code is not None:
            _dict['code'] = self.code
        if hasattr(self, 'direction') and self.direction is not None:
            _dict['direction'] = self.direction
        if hasattr(self, 'ip_version') and self.ip_version is not None:
            _dict['ip_version'] = self.ip_version
        if hasattr(self, 'protocol') and self.protocol is not None:
            _dict['protocol'] = self.protocol
        if hasattr(self, 'remote') and self.remote is not None:
            if isinstance(self.remote, dict):
                _dict['remote'] = self.remote
            else:
                _dict['remote'] = self.remote.to_dict()
        if hasattr(self, '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.
        """

        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 property, 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):
    """
    A rule specifying the TCP or UDP traffic to allow.
    Either both `port_min` and `port_max` will be present, or neither. When neither is
    present, all destination ports are allowed for the protocol. When both have the same
    value, that single destination port is allowed.

    :attr str direction: The direction of traffic to enforce.
    :attr str ip_version: (optional) The IP version to enforce. The format of
          `remote.address` or `remote.cidr_block` must match this property, if they are
          used. Alternatively, if `remote` references a security group, then this rule
          only applies to IP addresses (network interfaces) in that group matching this IP
          version.
    :attr int port_max: (optional) The inclusive upper bound of TCP/UDP destination
          port range.
          If specified, `port_min` must also be specified, and must not be larger. If
          unspecified,
          `port_min` must also be unspecified, allowing traffic on all destination ports.
    :attr int port_min: (optional) The inclusive lower bound of TCP/UDP destination
          port range
          If specified, `port_max` must also be specified, and must not be smaller. If
          unspecified, `port_max` must also be unspecified, allowing traffic on all
          destination ports.
    :attr str protocol: The protocol to enforce.
    :attr SecurityGroupRuleRemotePrototype remote: (optional) The remote 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 within the VPC.
          If unspecified, a CIDR block of `0.0.0.0/0` will be used to allow traffic from
          any source
          (or to any destination, for outbound rules).
    """

    def __init__(
        self,
        direction: str,
        protocol: str,
        *,
        ip_version: str = None,
        port_max: int = None,
        port_min: int = None,
        remote: 'SecurityGroupRuleRemotePrototype' = None,
    ) -> None:
        """
        Initialize a SecurityGroupRulePrototypeSecurityGroupRuleProtocolTCPUDP object.

        :param str direction: The direction of traffic to enforce.
        :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 property, if they
               are used. Alternatively, if `remote` references a security group, then this
               rule only applies to IP addresses (network interfaces) in that group
               matching this IP version.
        :param int port_max: (optional) The inclusive upper bound of TCP/UDP
               destination port range.
               If specified, `port_min` must also be specified, and must not be larger. If
               unspecified,
               `port_min` must also be unspecified, allowing traffic on all destination
               ports.
        :param int port_min: (optional) The inclusive lower bound of TCP/UDP
               destination port range
               If specified, `port_max` must also be specified, and must not be smaller.
               If unspecified, `port_max` must also be unspecified, allowing traffic on
               all destination ports.
        :param SecurityGroupRuleRemotePrototype remote: (optional) The remote 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 within the VPC.
               If unspecified, a CIDR block of `0.0.0.0/0` will be used to allow traffic
               from any source
               (or to any destination, for outbound rules).
        """
        # pylint: disable=super-init-not-called
        self.direction = direction
        self.ip_version = ip_version
        self.port_max = port_max
        self.port_min = port_min
        self.protocol = protocol
        self.remote = remote

    @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 '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')
        if 'remote' in _dict:
            args['remote'] = _dict.get('remote')
        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, '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, 'remote') and self.remote is not None:
            if isinstance(self.remote, dict):
                _dict['remote'] = self.remote
            else:
                _dict['remote'] = self.remote.to_dict()
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this 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.
        """

        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 property, if they are used. Alternatively, if `remote` references
        a security group, then this rule only applies to IP addresses (network interfaces)
        in that group matching this IP version.
        """

        IPV4 = 'ipv4'


    class ProtocolEnum(str, Enum):
        """
        The protocol to enforce.
        """

        TCP = 'tcp'
        UDP = 'udp'



class SecurityGroupRuleRemotePatchCIDR(SecurityGroupRuleRemotePatch):
    """
    SecurityGroupRuleRemotePatchCIDR.

    :attr str cidr_block: The CIDR block. This property may add support for IPv6
          CIDR blocks in the future. When processing a value in this property, verify that
          the CIDR block is in an expected format. If it is not, log an error. Optionally
          halt processing and surface the error, or bypass the resource on which the
          unexpected CIDR block format was encountered.
    """

    def __init__(
        self,
        cidr_block: str,
    ) -> None:
        """
        Initialize a SecurityGroupRuleRemotePatchCIDR object.

        :param str cidr_block: The CIDR block. This property may add support for
               IPv6 CIDR blocks in the future. When processing a value in this property,
               verify that the CIDR block is in an expected format. If it is not, log an
               error. Optionally halt processing and surface the error, or bypass the
               resource on which the unexpected CIDR block format was encountered.
        """
        # pylint: disable=super-init-not-called
        self.cidr_block = cidr_block

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'SecurityGroupRuleRemotePatchCIDR':
        """Initialize a SecurityGroupRuleRemotePatchCIDR object from a json dictionary."""
        args = {}
        if 'cidr_block' in _dict:
            args['cidr_block'] = _dict.get('cidr_block')
        else:
            raise ValueError('Required property \'cidr_block\' not present in SecurityGroupRuleRemotePatchCIDR JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SecurityGroupRuleRemotePatchCIDR object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'cidr_block') and self.cidr_block is not None:
            _dict['cidr_block'] = self.cidr_block
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this SecurityGroupRuleRemotePatchCIDR object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'SecurityGroupRuleRemotePatchCIDR') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'SecurityGroupRuleRemotePatchCIDR') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class SecurityGroupRuleRemotePatchIP(SecurityGroupRuleRemotePatch):
    """
    SecurityGroupRuleRemotePatchIP.

    :attr str address: The IP address.
          This property may add support for IPv6 addresses in the future. When processing
          a value in this property, verify that the address is in an expected format. If
          it is not, log an error. Optionally halt processing and surface the error, or
          bypass the resource on which the unexpected IP address format was encountered.
    """

    def __init__(
        self,
        address: str,
    ) -> None:
        """
        Initialize a SecurityGroupRuleRemotePatchIP object.

        :param str address: The IP address.
               This property may add support for IPv6 addresses in the future. When
               processing a value in this property, verify that the address is in an
               expected format. If it is not, log an error. Optionally halt processing and
               surface the error, or bypass the resource on which the unexpected IP
               address format was encountered.
        """
        # pylint: disable=super-init-not-called
        self.address = address

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'SecurityGroupRuleRemotePatchIP':
        """Initialize a SecurityGroupRuleRemotePatchIP object from a json dictionary."""
        args = {}
        if 'address' in _dict:
            args['address'] = _dict.get('address')
        else:
            raise ValueError('Required property \'address\' not present in SecurityGroupRuleRemotePatchIP JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SecurityGroupRuleRemotePatchIP object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'address') and self.address is not None:
            _dict['address'] = self.address
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this SecurityGroupRuleRemotePatchIP object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'SecurityGroupRuleRemotePatchIP') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'SecurityGroupRuleRemotePatchIP') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class SecurityGroupRuleRemotePatchSecurityGroupIdentity(SecurityGroupRuleRemotePatch):
    """
    Identifies a security group by a unique property.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a SecurityGroupRuleRemotePatchSecurityGroupIdentity object.

        """
        # pylint: disable=super-init-not-called
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['SecurityGroupRuleRemotePatchSecurityGroupIdentitySecurityGroupIdentityById', 'SecurityGroupRuleRemotePatchSecurityGroupIdentitySecurityGroupIdentityByCRN', 'SecurityGroupRuleRemotePatchSecurityGroupIdentitySecurityGroupIdentityByHref'])
        )
        raise Exception(msg)


class SecurityGroupRuleRemotePrototypeCIDR(SecurityGroupRuleRemotePrototype):
    """
    SecurityGroupRuleRemotePrototypeCIDR.

    :attr str cidr_block: The CIDR block. This property may add support for IPv6
          CIDR blocks in the future. When processing a value in this property, verify that
          the CIDR block is in an expected format. If it is not, log an error. Optionally
          halt processing and surface the error, or bypass the resource on which the
          unexpected CIDR block format was encountered.
    """

    def __init__(
        self,
        cidr_block: str,
    ) -> None:
        """
        Initialize a SecurityGroupRuleRemotePrototypeCIDR object.

        :param str cidr_block: The CIDR block. This property may add support for
               IPv6 CIDR blocks in the future. When processing a value in this property,
               verify that the CIDR block is in an expected format. If it is not, log an
               error. Optionally halt processing and surface the error, or bypass the
               resource on which the unexpected CIDR block format was encountered.
        """
        # pylint: disable=super-init-not-called
        self.cidr_block = cidr_block

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'SecurityGroupRuleRemotePrototypeCIDR':
        """Initialize a SecurityGroupRuleRemotePrototypeCIDR object from a json dictionary."""
        args = {}
        if 'cidr_block' in _dict:
            args['cidr_block'] = _dict.get('cidr_block')
        else:
            raise ValueError('Required property \'cidr_block\' not present in SecurityGroupRuleRemotePrototypeCIDR JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SecurityGroupRuleRemotePrototypeCIDR object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'cidr_block') and self.cidr_block is not None:
            _dict['cidr_block'] = self.cidr_block
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this SecurityGroupRuleRemotePrototypeCIDR object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'SecurityGroupRuleRemotePrototypeCIDR') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'SecurityGroupRuleRemotePrototypeCIDR') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class SecurityGroupRuleRemotePrototypeIP(SecurityGroupRuleRemotePrototype):
    """
    SecurityGroupRuleRemotePrototypeIP.

    :attr str address: The IP address.
          This property may add support for IPv6 addresses in the future. When processing
          a value in this property, verify that the address is in an expected format. If
          it is not, log an error. Optionally halt processing and surface the error, or
          bypass the resource on which the unexpected IP address format was encountered.
    """

    def __init__(
        self,
        address: str,
    ) -> None:
        """
        Initialize a SecurityGroupRuleRemotePrototypeIP object.

        :param str address: The IP address.
               This property may add support for IPv6 addresses in the future. When
               processing a value in this property, verify that the address is in an
               expected format. If it is not, log an error. Optionally halt processing and
               surface the error, or bypass the resource on which the unexpected IP
               address format was encountered.
        """
        # pylint: disable=super-init-not-called
        self.address = address

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'SecurityGroupRuleRemotePrototypeIP':
        """Initialize a SecurityGroupRuleRemotePrototypeIP object from a json dictionary."""
        args = {}
        if 'address' in _dict:
            args['address'] = _dict.get('address')
        else:
            raise ValueError('Required property \'address\' not present in SecurityGroupRuleRemotePrototypeIP JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SecurityGroupRuleRemotePrototypeIP object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'address') and self.address is not None:
            _dict['address'] = self.address
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this SecurityGroupRuleRemotePrototypeIP object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'SecurityGroupRuleRemotePrototypeIP') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'SecurityGroupRuleRemotePrototypeIP') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class SecurityGroupRuleRemotePrototypeSecurityGroupIdentity(SecurityGroupRuleRemotePrototype):
    """
    Identifies a security group by a unique property.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a SecurityGroupRuleRemotePrototypeSecurityGroupIdentity object.

        """
        # pylint: disable=super-init-not-called
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['SecurityGroupRuleRemotePrototypeSecurityGroupIdentitySecurityGroupIdentityById', 'SecurityGroupRuleRemotePrototypeSecurityGroupIdentitySecurityGroupIdentityByCRN', 'SecurityGroupRuleRemotePrototypeSecurityGroupIdentitySecurityGroupIdentityByHref'])
        )
        raise Exception(msg)


class SecurityGroupRuleRemoteCIDR(SecurityGroupRuleRemote):
    """
    SecurityGroupRuleRemoteCIDR.

    :attr str cidr_block: The CIDR block. This property may add support for IPv6
          CIDR blocks in the future. When processing a value in this property, verify that
          the CIDR block is in an expected format. If it is not, log an error. Optionally
          halt processing and surface the error, or bypass the resource on which the
          unexpected CIDR block format was encountered.
    """

    def __init__(
        self,
        cidr_block: str,
    ) -> None:
        """
        Initialize a SecurityGroupRuleRemoteCIDR object.

        :param str cidr_block: The CIDR block. This property may add support for
               IPv6 CIDR blocks in the future. When processing a value in this property,
               verify that the CIDR block is in an expected format. If it is not, log an
               error. Optionally halt processing and surface the error, or bypass the
               resource on which the unexpected CIDR block format was encountered.
        """
        # pylint: disable=super-init-not-called
        self.cidr_block = cidr_block

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'SecurityGroupRuleRemoteCIDR':
        """Initialize a SecurityGroupRuleRemoteCIDR object from a json dictionary."""
        args = {}
        if 'cidr_block' in _dict:
            args['cidr_block'] = _dict.get('cidr_block')
        else:
            raise ValueError('Required property \'cidr_block\' not present in SecurityGroupRuleRemoteCIDR JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SecurityGroupRuleRemoteCIDR object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'cidr_block') and self.cidr_block is not None:
            _dict['cidr_block'] = self.cidr_block
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this SecurityGroupRuleRemoteCIDR object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'SecurityGroupRuleRemoteCIDR') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'SecurityGroupRuleRemoteCIDR') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class SecurityGroupRuleRemoteIP(SecurityGroupRuleRemote):
    """
    SecurityGroupRuleRemoteIP.

    :attr str address: The IP address.
          This property may add support for IPv6 addresses in the future. When processing
          a value in this property, verify that the address is in an expected format. If
          it is not, log an error. Optionally halt processing and surface the error, or
          bypass the resource on which the unexpected IP address format was encountered.
    """

    def __init__(
        self,
        address: str,
    ) -> None:
        """
        Initialize a SecurityGroupRuleRemoteIP object.

        :param str address: The IP address.
               This property may add support for IPv6 addresses in the future. When
               processing a value in this property, verify that the address is in an
               expected format. If it is not, log an error. Optionally halt processing and
               surface the error, or bypass the resource on which the unexpected IP
               address format was encountered.
        """
        # pylint: disable=super-init-not-called
        self.address = address

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'SecurityGroupRuleRemoteIP':
        """Initialize a SecurityGroupRuleRemoteIP object from a json dictionary."""
        args = {}
        if 'address' in _dict:
            args['address'] = _dict.get('address')
        else:
            raise ValueError('Required property \'address\' not present in SecurityGroupRuleRemoteIP JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SecurityGroupRuleRemoteIP object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'address') and self.address is not None:
            _dict['address'] = self.address
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this SecurityGroupRuleRemoteIP object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'SecurityGroupRuleRemoteIP') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'SecurityGroupRuleRemoteIP') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class SecurityGroupRuleRemoteSecurityGroupReference(SecurityGroupRuleRemote):
    """
    SecurityGroupRuleRemoteSecurityGroupReference.

    :attr str crn: The security group's CRN.
    :attr SecurityGroupReferenceDeleted deleted: (optional) If present, this
          property indicates the referenced resource has been deleted, and provides
          some supplementary information.
    :attr str href: The security group's canonical URL.
    :attr str id: The unique identifier for this security group.
    :attr str name: The name for this security group. The name is unique across all
          security groups for the VPC.
    """

    def __init__(
        self,
        crn: str,
        href: str,
        id: str,
        name: str,
        *,
        deleted: 'SecurityGroupReferenceDeleted' = None,
    ) -> None:
        """
        Initialize a SecurityGroupRuleRemoteSecurityGroupReference object.

        :param str crn: The security group's CRN.
        :param str href: The security group's canonical URL.
        :param str id: The unique identifier for this security group.
        :param str name: The name for this security group. The name is unique
               across all security groups for the VPC.
        :param SecurityGroupReferenceDeleted deleted: (optional) If present, this
               property indicates the referenced resource has been deleted, and provides
               some supplementary information.
        """
        # pylint: disable=super-init-not-called
        self.crn = crn
        self.deleted = deleted
        self.href = href
        self.id = id
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'SecurityGroupRuleRemoteSecurityGroupReference':
        """Initialize a SecurityGroupRuleRemoteSecurityGroupReference object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError('Required property \'crn\' not present in SecurityGroupRuleRemoteSecurityGroupReference JSON')
        if 'deleted' in _dict:
            args['deleted'] = SecurityGroupReferenceDeleted.from_dict(_dict.get('deleted'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in SecurityGroupRuleRemoteSecurityGroupReference JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in SecurityGroupRuleRemoteSecurityGroupReference JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in SecurityGroupRuleRemoteSecurityGroupReference JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SecurityGroupRuleRemoteSecurityGroupReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'deleted') and self.deleted is not None:
            if isinstance(self.deleted, dict):
                _dict['deleted'] = self.deleted
            else:
                _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this SecurityGroupRuleRemoteSecurityGroupReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'SecurityGroupRuleRemoteSecurityGroupReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'SecurityGroupRuleRemoteSecurityGroupReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class SecurityGroupRuleSecurityGroupRuleProtocolAll(SecurityGroupRule):
    """
    A rule allowing traffic for all supported protocols.

    :attr str direction: The direction of traffic to enforce.
    :attr str href: The URL for this security group rule.
    :attr str id: The unique identifier for this security group rule.
    :attr str ip_version: The IP version to enforce. The format of `remote.address`
          or `remote.cidr_block` must match this property, if they are used.
          Alternatively, if `remote` references a security group, then this rule only
          applies to IP addresses (network interfaces) in that group matching this IP
          version.
    :attr SecurityGroupRuleRemote remote:
    :attr str protocol: The protocol to enforce.
    """

    def __init__(
        self,
        direction: str,
        href: str,
        id: str,
        ip_version: str,
        remote: 'SecurityGroupRuleRemote',
        protocol: str,
    ) -> None:
        """
        Initialize a SecurityGroupRuleSecurityGroupRuleProtocolAll object.

        :param str direction: The direction of traffic to enforce.
        :param str href: The URL for this security group rule.
        :param str id: The unique identifier for this security group rule.
        :param str ip_version: The IP version to enforce. The format of
               `remote.address` or `remote.cidr_block` must match this property, 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:
        :param str protocol: The protocol to enforce.
        """
        # pylint: disable=super-init-not-called
        self.direction = direction
        self.href = href
        self.id = id
        self.ip_version = ip_version
        self.remote = remote
        self.protocol = protocol

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'SecurityGroupRuleSecurityGroupRuleProtocolAll':
        """Initialize a SecurityGroupRuleSecurityGroupRuleProtocolAll object from a json dictionary."""
        args = {}
        if 'direction' in _dict:
            args['direction'] = _dict.get('direction')
        else:
            raise ValueError('Required property \'direction\' not present in SecurityGroupRuleSecurityGroupRuleProtocolAll JSON')
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in SecurityGroupRuleSecurityGroupRuleProtocolAll JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in SecurityGroupRuleSecurityGroupRuleProtocolAll JSON')
        if 'ip_version' in _dict:
            args['ip_version'] = _dict.get('ip_version')
        else:
            raise ValueError('Required property \'ip_version\' not present in SecurityGroupRuleSecurityGroupRuleProtocolAll JSON')
        if 'remote' in _dict:
            args['remote'] = _dict.get('remote')
        else:
            raise ValueError('Required property \'remote\' not present in SecurityGroupRuleSecurityGroupRuleProtocolAll JSON')
        if 'protocol' in _dict:
            args['protocol'] = _dict.get('protocol')
        else:
            raise ValueError('Required property \'protocol\' not present in SecurityGroupRuleSecurityGroupRuleProtocolAll JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SecurityGroupRuleSecurityGroupRuleProtocolAll object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'direction') and self.direction is not None:
            _dict['direction'] = self.direction
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'ip_version') and self.ip_version is not None:
            _dict['ip_version'] = self.ip_version
        if hasattr(self, 'remote') and self.remote is not None:
            if isinstance(self.remote, dict):
                _dict['remote'] = self.remote
            else:
                _dict['remote'] = self.remote.to_dict()
        if hasattr(self, 'protocol') and self.protocol is not None:
            _dict['protocol'] = self.protocol
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this SecurityGroupRuleSecurityGroupRuleProtocolAll object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'SecurityGroupRuleSecurityGroupRuleProtocolAll') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'SecurityGroupRuleSecurityGroupRuleProtocolAll') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class DirectionEnum(str, Enum):
        """
        The direction of traffic to enforce.
        """

        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 property, 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):
    """
    A rule specifying the ICMP traffic to allow.

    :attr str direction: The direction of traffic to enforce.
    :attr str href: The URL for this security group rule.
    :attr str id: The unique identifier for this security group rule.
    :attr str ip_version: The IP version to enforce. The format of `remote.address`
          or `remote.cidr_block` must match this property, if they are used.
          Alternatively, if `remote` references a security group, then this rule only
          applies to IP addresses (network interfaces) in that group matching this IP
          version.
    :attr SecurityGroupRuleRemote remote:
    :attr int code: (optional) The ICMP traffic code to allow. If absent, all codes
          are allowed.
    :attr str protocol: The protocol to enforce.
    :attr int type: (optional) The ICMP traffic type to allow. If absent, all types
          are allowed.
    """

    def __init__(
        self,
        direction: str,
        href: str,
        id: str,
        ip_version: str,
        remote: 'SecurityGroupRuleRemote',
        protocol: str,
        *,
        code: int = None,
        type: int = None,
    ) -> None:
        """
        Initialize a SecurityGroupRuleSecurityGroupRuleProtocolICMP object.

        :param str direction: The direction of traffic to enforce.
        :param str href: The URL for this security group rule.
        :param str id: The unique identifier for this security group rule.
        :param str ip_version: The IP version to enforce. The format of
               `remote.address` or `remote.cidr_block` must match this property, 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:
        :param str protocol: The protocol to enforce.
        :param int code: (optional) The ICMP traffic code to allow. If absent, all
               codes are allowed.
        :param int type: (optional) The ICMP traffic type to allow. If absent, all
               types are allowed.
        """
        # pylint: disable=super-init-not-called
        self.direction = direction
        self.href = href
        self.id = id
        self.ip_version = ip_version
        self.remote = remote
        self.code = code
        self.protocol = protocol
        self.type = type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'SecurityGroupRuleSecurityGroupRuleProtocolICMP':
        """Initialize a SecurityGroupRuleSecurityGroupRuleProtocolICMP object from a json dictionary."""
        args = {}
        if 'direction' in _dict:
            args['direction'] = _dict.get('direction')
        else:
            raise ValueError('Required property \'direction\' not present in SecurityGroupRuleSecurityGroupRuleProtocolICMP JSON')
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in SecurityGroupRuleSecurityGroupRuleProtocolICMP JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in SecurityGroupRuleSecurityGroupRuleProtocolICMP JSON')
        if 'ip_version' in _dict:
            args['ip_version'] = _dict.get('ip_version')
        else:
            raise ValueError('Required property \'ip_version\' not present in SecurityGroupRuleSecurityGroupRuleProtocolICMP JSON')
        if 'remote' in _dict:
            args['remote'] = _dict.get('remote')
        else:
            raise ValueError('Required property \'remote\' not present in SecurityGroupRuleSecurityGroupRuleProtocolICMP JSON')
        if 'code' in _dict:
            args['code'] = _dict.get('code')
        if 'protocol' in _dict:
            args['protocol'] = _dict.get('protocol')
        else:
            raise ValueError('Required property \'protocol\' not present in SecurityGroupRuleSecurityGroupRuleProtocolICMP JSON')
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SecurityGroupRuleSecurityGroupRuleProtocolICMP object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'direction') and self.direction is not None:
            _dict['direction'] = self.direction
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'ip_version') and self.ip_version is not None:
            _dict['ip_version'] = self.ip_version
        if hasattr(self, 'remote') and self.remote is not None:
            if isinstance(self.remote, dict):
                _dict['remote'] = self.remote
            else:
                _dict['remote'] = self.remote.to_dict()
        if hasattr(self, 'code') and self.code is not None:
            _dict['code'] = self.code
        if hasattr(self, 'protocol') and self.protocol is not None:
            _dict['protocol'] = self.protocol
        if hasattr(self, 'type') and self.type is not None:
            _dict['type'] = self.type
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this SecurityGroupRuleSecurityGroupRuleProtocolICMP object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'SecurityGroupRuleSecurityGroupRuleProtocolICMP') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'SecurityGroupRuleSecurityGroupRuleProtocolICMP') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class DirectionEnum(str, Enum):
        """
        The direction of traffic to enforce.
        """

        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 property, 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):
    """
    A rule specifying the TCP or UDP traffic to allow.
    Either both `port_min` and `port_max` will be present, or neither. When neither is
    present, all destination ports are allowed for the protocol. When both have the same
    value, that single destination port is allowed.

    :attr str direction: The direction of traffic to enforce.
    :attr str href: The URL for this security group rule.
    :attr str id: The unique identifier for this security group rule.
    :attr str ip_version: The IP version to enforce. The format of `remote.address`
          or `remote.cidr_block` must match this property, if they are used.
          Alternatively, if `remote` references a security group, then this rule only
          applies to IP addresses (network interfaces) in that group matching this IP
          version.
    :attr SecurityGroupRuleRemote remote:
    :attr int port_max: (optional) The inclusive upper bound of TCP/UDP 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.
    """

    def __init__(
        self,
        direction: str,
        href: str,
        id: str,
        ip_version: str,
        remote: 'SecurityGroupRuleRemote',
        protocol: str,
        *,
        port_max: int = None,
        port_min: int = None,
    ) -> None:
        """
        Initialize a SecurityGroupRuleSecurityGroupRuleProtocolTCPUDP object.

        :param str direction: The direction of traffic to enforce.
        :param str href: The URL for this security group rule.
        :param str id: The unique identifier for this security group rule.
        :param str ip_version: The IP version to enforce. The format of
               `remote.address` or `remote.cidr_block` must match this property, 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:
        :param str protocol: The protocol to enforce.
        :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.
        """
        # pylint: disable=super-init-not-called
        self.direction = direction
        self.href = href
        self.id = id
        self.ip_version = ip_version
        self.remote = remote
        self.port_max = port_max
        self.port_min = port_min
        self.protocol = protocol

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'SecurityGroupRuleSecurityGroupRuleProtocolTCPUDP':
        """Initialize a SecurityGroupRuleSecurityGroupRuleProtocolTCPUDP object from a json dictionary."""
        args = {}
        if 'direction' in _dict:
            args['direction'] = _dict.get('direction')
        else:
            raise ValueError('Required property \'direction\' not present in SecurityGroupRuleSecurityGroupRuleProtocolTCPUDP JSON')
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in SecurityGroupRuleSecurityGroupRuleProtocolTCPUDP JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in SecurityGroupRuleSecurityGroupRuleProtocolTCPUDP JSON')
        if 'ip_version' in _dict:
            args['ip_version'] = _dict.get('ip_version')
        else:
            raise ValueError('Required property \'ip_version\' not present in SecurityGroupRuleSecurityGroupRuleProtocolTCPUDP JSON')
        if 'remote' in _dict:
            args['remote'] = _dict.get('remote')
        else:
            raise ValueError('Required property \'remote\' not present in SecurityGroupRuleSecurityGroupRuleProtocolTCPUDP JSON')
        if 'port_max' in _dict:
            args['port_max'] = _dict.get('port_max')
        if 'port_min' in _dict:
            args['port_min'] = _dict.get('port_min')
        if 'protocol' in _dict:
            args['protocol'] = _dict.get('protocol')
        else:
            raise ValueError('Required property \'protocol\' not present in SecurityGroupRuleSecurityGroupRuleProtocolTCPUDP JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SecurityGroupRuleSecurityGroupRuleProtocolTCPUDP object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'direction') and self.direction is not None:
            _dict['direction'] = self.direction
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'ip_version') and self.ip_version is not None:
            _dict['ip_version'] = self.ip_version
        if hasattr(self, 'remote') and self.remote is not None:
            if isinstance(self.remote, dict):
                _dict['remote'] = self.remote
            else:
                _dict['remote'] = self.remote.to_dict()
        if hasattr(self, 'port_max') and self.port_max is not None:
            _dict['port_max'] = self.port_max
        if hasattr(self, 'port_min') and self.port_min is not None:
            _dict['port_min'] = self.port_min
        if hasattr(self, 'protocol') and self.protocol is not None:
            _dict['protocol'] = self.protocol
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this SecurityGroupRuleSecurityGroupRuleProtocolTCPUDP object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'SecurityGroupRuleSecurityGroupRuleProtocolTCPUDP') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'SecurityGroupRuleSecurityGroupRuleProtocolTCPUDP') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class DirectionEnum(str, Enum):
        """
        The direction of traffic to enforce.
        """

        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 property, 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 SecurityGroupTargetReferenceBareMetalServerNetworkInterfaceReferenceTargetContext(SecurityGroupTargetReference):
    """
    SecurityGroupTargetReferenceBareMetalServerNetworkInterfaceReferenceTargetContext.

    :attr BareMetalServerNetworkInterfaceReferenceTargetContextDeleted deleted:
          (optional) If present, this property indicates the referenced resource has been
          deleted, and provides
          some supplementary information.
    :attr str href: The URL for this bare metal server network interface.
    :attr str id: The unique identifier for this bare metal server network
          interface.
    :attr str name: The name for this bare metal server network interface.
    :attr str resource_type: The resource type.
    """

    def __init__(
        self,
        href: str,
        id: str,
        name: str,
        resource_type: str,
        *,
        deleted: 'BareMetalServerNetworkInterfaceReferenceTargetContextDeleted' = None,
    ) -> None:
        """
        Initialize a SecurityGroupTargetReferenceBareMetalServerNetworkInterfaceReferenceTargetContext object.

        :param str href: The URL for this bare metal server network interface.
        :param str id: The unique identifier for this bare metal server network
               interface.
        :param str name: The name for this bare metal server network interface.
        :param str resource_type: The resource type.
        :param BareMetalServerNetworkInterfaceReferenceTargetContextDeleted
               deleted: (optional) If present, this property indicates the referenced
               resource has been deleted, and provides
               some supplementary information.
        """
        # pylint: disable=super-init-not-called
        self.deleted = deleted
        self.href = href
        self.id = id
        self.name = name
        self.resource_type = resource_type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'SecurityGroupTargetReferenceBareMetalServerNetworkInterfaceReferenceTargetContext':
        """Initialize a SecurityGroupTargetReferenceBareMetalServerNetworkInterfaceReferenceTargetContext object from a json dictionary."""
        args = {}
        if 'deleted' in _dict:
            args['deleted'] = BareMetalServerNetworkInterfaceReferenceTargetContextDeleted.from_dict(_dict.get('deleted'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in SecurityGroupTargetReferenceBareMetalServerNetworkInterfaceReferenceTargetContext JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in SecurityGroupTargetReferenceBareMetalServerNetworkInterfaceReferenceTargetContext JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in SecurityGroupTargetReferenceBareMetalServerNetworkInterfaceReferenceTargetContext JSON')
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError('Required property \'resource_type\' not present in SecurityGroupTargetReferenceBareMetalServerNetworkInterfaceReferenceTargetContext JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SecurityGroupTargetReferenceBareMetalServerNetworkInterfaceReferenceTargetContext object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'deleted') and self.deleted is not None:
            if isinstance(self.deleted, dict):
                _dict['deleted'] = self.deleted
            else:
                _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'resource_type') and self.resource_type is not None:
            _dict['resource_type'] = self.resource_type
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this SecurityGroupTargetReferenceBareMetalServerNetworkInterfaceReferenceTargetContext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'SecurityGroupTargetReferenceBareMetalServerNetworkInterfaceReferenceTargetContext') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'SecurityGroupTargetReferenceBareMetalServerNetworkInterfaceReferenceTargetContext') -> 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 SecurityGroupTargetReferenceEndpointGatewayReference(SecurityGroupTargetReference):
    """
    SecurityGroupTargetReferenceEndpointGatewayReference.

    :attr str crn: The CRN for this endpoint gateway.
    :attr EndpointGatewayReferenceDeleted deleted: (optional) If present, this
          property indicates the referenced resource has been deleted, and provides
          some supplementary information.
    :attr str href: The URL for this endpoint gateway.
    :attr str id: The unique identifier for this endpoint gateway.
    :attr str name: The name for this endpoint gateway. The name is unique across
          all endpoint gateways in the VPC.
    :attr str resource_type: The resource type.
    """

    def __init__(
        self,
        crn: str,
        href: str,
        id: str,
        name: str,
        resource_type: str,
        *,
        deleted: 'EndpointGatewayReferenceDeleted' = None,
    ) -> None:
        """
        Initialize a SecurityGroupTargetReferenceEndpointGatewayReference object.

        :param str crn: The CRN for this endpoint gateway.
        :param str href: The URL for this endpoint gateway.
        :param str id: The unique identifier for this endpoint gateway.
        :param str name: The name for this endpoint gateway. The name is unique
               across all endpoint gateways in the VPC.
        :param str resource_type: The resource type.
        :param EndpointGatewayReferenceDeleted deleted: (optional) If present, this
               property indicates the referenced resource has been deleted, and provides
               some supplementary information.
        """
        # pylint: disable=super-init-not-called
        self.crn = crn
        self.deleted = deleted
        self.href = href
        self.id = id
        self.name = name
        self.resource_type = resource_type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'SecurityGroupTargetReferenceEndpointGatewayReference':
        """Initialize a SecurityGroupTargetReferenceEndpointGatewayReference object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError('Required property \'crn\' not present in SecurityGroupTargetReferenceEndpointGatewayReference JSON')
        if 'deleted' in _dict:
            args['deleted'] = EndpointGatewayReferenceDeleted.from_dict(_dict.get('deleted'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in SecurityGroupTargetReferenceEndpointGatewayReference JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in SecurityGroupTargetReferenceEndpointGatewayReference JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in SecurityGroupTargetReferenceEndpointGatewayReference JSON')
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError('Required property \'resource_type\' not present in SecurityGroupTargetReferenceEndpointGatewayReference JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SecurityGroupTargetReferenceEndpointGatewayReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'deleted') and self.deleted is not None:
            if isinstance(self.deleted, dict):
                _dict['deleted'] = self.deleted
            else:
                _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'resource_type') and self.resource_type is not None:
            _dict['resource_type'] = self.resource_type
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this SecurityGroupTargetReferenceEndpointGatewayReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'SecurityGroupTargetReferenceEndpointGatewayReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'SecurityGroupTargetReferenceEndpointGatewayReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        ENDPOINT_GATEWAY = 'endpoint_gateway'



class SecurityGroupTargetReferenceLoadBalancerReference(SecurityGroupTargetReference):
    """
    SecurityGroupTargetReferenceLoadBalancerReference.

    :attr str crn: The load balancer's CRN.
    :attr LoadBalancerReferenceDeleted deleted: (optional) If present, this property
          indicates the referenced resource has been deleted, and provides
          some supplementary information.
    :attr str href: The load balancer's canonical URL.
    :attr str id: The unique identifier for this load balancer.
    :attr str name: The name for this load balancer. The name is unique across all
          load balancers in the VPC.
    :attr str resource_type: The resource type.
    """

    def __init__(
        self,
        crn: str,
        href: str,
        id: str,
        name: str,
        resource_type: str,
        *,
        deleted: 'LoadBalancerReferenceDeleted' = None,
    ) -> None:
        """
        Initialize a SecurityGroupTargetReferenceLoadBalancerReference object.

        :param str crn: The load balancer's CRN.
        :param str href: The load balancer's canonical URL.
        :param str id: The unique identifier for this load balancer.
        :param str name: The name for this load balancer. The name is unique across
               all load balancers in the VPC.
        :param str resource_type: The resource type.
        :param LoadBalancerReferenceDeleted deleted: (optional) If present, this
               property indicates the referenced resource has been deleted, and provides
               some supplementary information.
        """
        # pylint: disable=super-init-not-called
        self.crn = crn
        self.deleted = deleted
        self.href = href
        self.id = id
        self.name = name
        self.resource_type = resource_type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'SecurityGroupTargetReferenceLoadBalancerReference':
        """Initialize a SecurityGroupTargetReferenceLoadBalancerReference object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError('Required property \'crn\' not present in SecurityGroupTargetReferenceLoadBalancerReference JSON')
        if 'deleted' in _dict:
            args['deleted'] = LoadBalancerReferenceDeleted.from_dict(_dict.get('deleted'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in SecurityGroupTargetReferenceLoadBalancerReference JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in SecurityGroupTargetReferenceLoadBalancerReference JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in SecurityGroupTargetReferenceLoadBalancerReference JSON')
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError('Required property \'resource_type\' not present in SecurityGroupTargetReferenceLoadBalancerReference JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SecurityGroupTargetReferenceLoadBalancerReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'deleted') and self.deleted is not None:
            if isinstance(self.deleted, dict):
                _dict['deleted'] = self.deleted
            else:
                _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'resource_type') and self.resource_type is not None:
            _dict['resource_type'] = self.resource_type
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this SecurityGroupTargetReferenceLoadBalancerReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'SecurityGroupTargetReferenceLoadBalancerReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'SecurityGroupTargetReferenceLoadBalancerReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        LOAD_BALANCER = 'load_balancer'



class SecurityGroupTargetReferenceNetworkInterfaceReferenceTargetContext(SecurityGroupTargetReference):
    """
    SecurityGroupTargetReferenceNetworkInterfaceReferenceTargetContext.

    :attr NetworkInterfaceReferenceTargetContextDeleted deleted: (optional) If
          present, this property indicates the referenced resource has been deleted, and
          provides
          some supplementary information.
    :attr str href: The URL for this instance network interface.
    :attr str id: The unique identifier for this instance network interface.
    :attr str name: The name for this instance network interface.
    :attr str resource_type: The resource type.
    """

    def __init__(
        self,
        href: str,
        id: str,
        name: str,
        resource_type: str,
        *,
        deleted: 'NetworkInterfaceReferenceTargetContextDeleted' = None,
    ) -> None:
        """
        Initialize a SecurityGroupTargetReferenceNetworkInterfaceReferenceTargetContext object.

        :param str href: The URL for this instance network interface.
        :param str id: The unique identifier for this instance network interface.
        :param str name: The name for this instance network interface.
        :param str resource_type: The resource type.
        :param NetworkInterfaceReferenceTargetContextDeleted deleted: (optional) If
               present, this property indicates the referenced resource has been deleted,
               and provides
               some supplementary information.
        """
        # pylint: disable=super-init-not-called
        self.deleted = deleted
        self.href = href
        self.id = id
        self.name = name
        self.resource_type = resource_type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'SecurityGroupTargetReferenceNetworkInterfaceReferenceTargetContext':
        """Initialize a SecurityGroupTargetReferenceNetworkInterfaceReferenceTargetContext object from a json dictionary."""
        args = {}
        if 'deleted' in _dict:
            args['deleted'] = NetworkInterfaceReferenceTargetContextDeleted.from_dict(_dict.get('deleted'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in SecurityGroupTargetReferenceNetworkInterfaceReferenceTargetContext JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in SecurityGroupTargetReferenceNetworkInterfaceReferenceTargetContext JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in SecurityGroupTargetReferenceNetworkInterfaceReferenceTargetContext JSON')
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError('Required property \'resource_type\' not present in SecurityGroupTargetReferenceNetworkInterfaceReferenceTargetContext JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SecurityGroupTargetReferenceNetworkInterfaceReferenceTargetContext object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'deleted') and self.deleted is not None:
            if isinstance(self.deleted, dict):
                _dict['deleted'] = self.deleted
            else:
                _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'resource_type') and self.resource_type is not None:
            _dict['resource_type'] = self.resource_type
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this SecurityGroupTargetReferenceNetworkInterfaceReferenceTargetContext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'SecurityGroupTargetReferenceNetworkInterfaceReferenceTargetContext') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'SecurityGroupTargetReferenceNetworkInterfaceReferenceTargetContext') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        NETWORK_INTERFACE = 'network_interface'



class SecurityGroupTargetReferenceVPNServerReference(SecurityGroupTargetReference):
    """
    SecurityGroupTargetReferenceVPNServerReference.

    :attr str crn: The CRN for this VPN server.
    :attr VPNServerReferenceDeleted deleted: (optional) If present, this property
          indicates the referenced resource has been deleted, and provides
          some supplementary information.
    :attr str href: The URL for this VPN server.
    :attr str id: The unique identifier for this VPN server.
    :attr str name: The name for this VPN server. The name is unique across all VPN
          servers in the VPC.
    :attr str resource_type: The resource type.
    """

    def __init__(
        self,
        crn: str,
        href: str,
        id: str,
        name: str,
        resource_type: str,
        *,
        deleted: 'VPNServerReferenceDeleted' = None,
    ) -> None:
        """
        Initialize a SecurityGroupTargetReferenceVPNServerReference object.

        :param str crn: The CRN for this VPN server.
        :param str href: The URL for this VPN server.
        :param str id: The unique identifier for this VPN server.
        :param str name: The name for this VPN server. The name is unique across
               all VPN servers in the VPC.
        :param str resource_type: The resource type.
        :param VPNServerReferenceDeleted deleted: (optional) If present, this
               property indicates the referenced resource has been deleted, and provides
               some supplementary information.
        """
        # pylint: disable=super-init-not-called
        self.crn = crn
        self.deleted = deleted
        self.href = href
        self.id = id
        self.name = name
        self.resource_type = resource_type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'SecurityGroupTargetReferenceVPNServerReference':
        """Initialize a SecurityGroupTargetReferenceVPNServerReference object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError('Required property \'crn\' not present in SecurityGroupTargetReferenceVPNServerReference JSON')
        if 'deleted' in _dict:
            args['deleted'] = VPNServerReferenceDeleted.from_dict(_dict.get('deleted'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in SecurityGroupTargetReferenceVPNServerReference JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in SecurityGroupTargetReferenceVPNServerReference JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in SecurityGroupTargetReferenceVPNServerReference JSON')
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError('Required property \'resource_type\' not present in SecurityGroupTargetReferenceVPNServerReference JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SecurityGroupTargetReferenceVPNServerReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'deleted') and self.deleted is not None:
            if isinstance(self.deleted, dict):
                _dict['deleted'] = self.deleted
            else:
                _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'resource_type') and self.resource_type is not None:
            _dict['resource_type'] = self.resource_type
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this SecurityGroupTargetReferenceVPNServerReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'SecurityGroupTargetReferenceVPNServerReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'SecurityGroupTargetReferenceVPNServerReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        VPN_SERVER = 'vpn_server'



class SecurityGroupTargetReferenceVirtualNetworkInterfaceReference(SecurityGroupTargetReference):
    """
    SecurityGroupTargetReferenceVirtualNetworkInterfaceReference.

    :attr str crn: The CRN for this virtual network interface.
    :attr VirtualNetworkInterfaceReferenceDeleted deleted: (optional) If present,
          this property indicates the referenced resource has been deleted, and provides
          some supplementary information.
    :attr str href: The URL for this virtual network interface.
    :attr str id: The unique identifier for this virtual network interface.
    :attr str name: The name for this virtual network interface. The name is unique
          across all virtual network interfaces in the VPC.
    :attr ReservedIPReference primary_ip: The primary IP for this virtual network
          interface.
    :attr str resource_type: The resource type.
    :attr SubnetReference subnet: The associated subnet.
    """

    def __init__(
        self,
        crn: str,
        href: str,
        id: str,
        name: str,
        primary_ip: 'ReservedIPReference',
        resource_type: str,
        subnet: 'SubnetReference',
        *,
        deleted: 'VirtualNetworkInterfaceReferenceDeleted' = None,
    ) -> None:
        """
        Initialize a SecurityGroupTargetReferenceVirtualNetworkInterfaceReference object.

        :param str crn: The CRN for this virtual network interface.
        :param str href: The URL for this virtual network interface.
        :param str id: The unique identifier for this virtual network interface.
        :param str name: The name for this virtual network interface. The name is
               unique across all virtual network interfaces in the VPC.
        :param ReservedIPReference primary_ip: The primary IP for this virtual
               network interface.
        :param str resource_type: The resource type.
        :param SubnetReference subnet: The associated subnet.
        :param VirtualNetworkInterfaceReferenceDeleted deleted: (optional) If
               present, this property indicates the referenced resource has been deleted,
               and provides
               some supplementary information.
        """
        # pylint: disable=super-init-not-called
        self.crn = crn
        self.deleted = deleted
        self.href = href
        self.id = id
        self.name = name
        self.primary_ip = primary_ip
        self.resource_type = resource_type
        self.subnet = subnet

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'SecurityGroupTargetReferenceVirtualNetworkInterfaceReference':
        """Initialize a SecurityGroupTargetReferenceVirtualNetworkInterfaceReference object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError('Required property \'crn\' not present in SecurityGroupTargetReferenceVirtualNetworkInterfaceReference JSON')
        if 'deleted' in _dict:
            args['deleted'] = VirtualNetworkInterfaceReferenceDeleted.from_dict(_dict.get('deleted'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in SecurityGroupTargetReferenceVirtualNetworkInterfaceReference JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in SecurityGroupTargetReferenceVirtualNetworkInterfaceReference JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in SecurityGroupTargetReferenceVirtualNetworkInterfaceReference JSON')
        if 'primary_ip' in _dict:
            args['primary_ip'] = ReservedIPReference.from_dict(_dict.get('primary_ip'))
        else:
            raise ValueError('Required property \'primary_ip\' not present in SecurityGroupTargetReferenceVirtualNetworkInterfaceReference JSON')
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError('Required property \'resource_type\' not present in SecurityGroupTargetReferenceVirtualNetworkInterfaceReference JSON')
        if 'subnet' in _dict:
            args['subnet'] = SubnetReference.from_dict(_dict.get('subnet'))
        else:
            raise ValueError('Required property \'subnet\' not present in SecurityGroupTargetReferenceVirtualNetworkInterfaceReference JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SecurityGroupTargetReferenceVirtualNetworkInterfaceReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'deleted') and self.deleted is not None:
            if isinstance(self.deleted, dict):
                _dict['deleted'] = self.deleted
            else:
                _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'primary_ip') and self.primary_ip is not None:
            if isinstance(self.primary_ip, dict):
                _dict['primary_ip'] = self.primary_ip
            else:
                _dict['primary_ip'] = self.primary_ip.to_dict()
        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:
            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 SecurityGroupTargetReferenceVirtualNetworkInterfaceReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'SecurityGroupTargetReferenceVirtualNetworkInterfaceReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'SecurityGroupTargetReferenceVirtualNetworkInterfaceReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        VIRTUAL_NETWORK_INTERFACE = 'virtual_network_interface'



class ShareIdentityByCRN(ShareIdentity):
    """
    ShareIdentityByCRN.

    :attr str crn: The CRN for this file share.
    """

    def __init__(
        self,
        crn: str,
    ) -> None:
        """
        Initialize a ShareIdentityByCRN object.

        :param str crn: The CRN for this file share.
        """
        # pylint: disable=super-init-not-called
        self.crn = crn

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ShareIdentityByCRN':
        """Initialize a ShareIdentityByCRN object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError('Required property \'crn\' not present in ShareIdentityByCRN JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ShareIdentityByCRN object from 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 ShareIdentityByCRN object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ShareIdentityByCRN') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ShareIdentityByCRN') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class ShareIdentityByHref(ShareIdentity):
    """
    ShareIdentityByHref.

    :attr str href: The URL for this file share.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a ShareIdentityByHref object.

        :param str href: The URL for this file share.
        """
        # pylint: disable=super-init-not-called
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ShareIdentityByHref':
        """Initialize a ShareIdentityByHref object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in ShareIdentityByHref JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ShareIdentityByHref object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(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 ShareIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ShareIdentityByHref') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ShareIdentityByHref') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class ShareIdentityById(ShareIdentity):
    """
    ShareIdentityById.

    :attr str id: The unique identifier for this file share.
    """

    def __init__(
        self,
        id: str,
    ) -> None:
        """
        Initialize a ShareIdentityById object.

        :param str id: The unique identifier for this file share.
        """
        # pylint: disable=super-init-not-called
        self.id = id

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ShareIdentityById':
        """Initialize a ShareIdentityById object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in ShareIdentityById JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ShareIdentityById object from 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 ShareIdentityById object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ShareIdentityById') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ShareIdentityById') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class ShareMountTargetPrototypeShareMountTargetByAccessControlModeSecurityGroup(ShareMountTargetPrototype):
    """
    The virtual network interface for this share mount target. The virtual network
    interface's VPC must not be used by a virtual network interface for another mount
    target for this share.
    Required if the share's `access_control_mode` is `security_group`.

    :attr str name: (optional) The name for this share mount target. The name must
          not be used by another mount target for the file share.
    :attr str transit_encryption: (optional) The transit encryption mode to use for
          this share mount target:
          - `none`: Not encrypted in transit.
          - `user_managed`: Encrypted in transit using an instance identity certificate.
          The
                            `access_control_mode` for the share must be `security_group`.
    :attr ShareMountTargetVirtualNetworkInterfacePrototype
          virtual_network_interface:
    """

    def __init__(
        self,
        virtual_network_interface: 'ShareMountTargetVirtualNetworkInterfacePrototype',
        *,
        name: str = None,
        transit_encryption: str = None,
    ) -> None:
        """
        Initialize a ShareMountTargetPrototypeShareMountTargetByAccessControlModeSecurityGroup object.

        :param ShareMountTargetVirtualNetworkInterfacePrototype
               virtual_network_interface:
        :param str name: (optional) The name for this share mount target. The name
               must not be used by another mount target for the file share.
        :param str transit_encryption: (optional) The transit encryption mode to
               use for this share mount target:
               - `none`: Not encrypted in transit.
               - `user_managed`: Encrypted in transit using an instance identity
               certificate.  The
                                 `access_control_mode` for the share must be
               `security_group`.
        """
        # pylint: disable=super-init-not-called
        self.name = name
        self.transit_encryption = transit_encryption
        self.virtual_network_interface = virtual_network_interface

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ShareMountTargetPrototypeShareMountTargetByAccessControlModeSecurityGroup':
        """Initialize a ShareMountTargetPrototypeShareMountTargetByAccessControlModeSecurityGroup object from a json dictionary."""
        args = {}
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        if 'transit_encryption' in _dict:
            args['transit_encryption'] = _dict.get('transit_encryption')
        if 'virtual_network_interface' in _dict:
            args['virtual_network_interface'] = _dict.get('virtual_network_interface')
        else:
            raise ValueError('Required property \'virtual_network_interface\' not present in ShareMountTargetPrototypeShareMountTargetByAccessControlModeSecurityGroup JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ShareMountTargetPrototypeShareMountTargetByAccessControlModeSecurityGroup object from 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, 'transit_encryption') and self.transit_encryption is not None:
            _dict['transit_encryption'] = self.transit_encryption
        if hasattr(self, 'virtual_network_interface') and self.virtual_network_interface is not None:
            if isinstance(self.virtual_network_interface, dict):
                _dict['virtual_network_interface'] = self.virtual_network_interface
            else:
                _dict['virtual_network_interface'] = self.virtual_network_interface.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 ShareMountTargetPrototypeShareMountTargetByAccessControlModeSecurityGroup object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ShareMountTargetPrototypeShareMountTargetByAccessControlModeSecurityGroup') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ShareMountTargetPrototypeShareMountTargetByAccessControlModeSecurityGroup') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class TransitEncryptionEnum(str, Enum):
        """
        The transit encryption mode to use for this share mount target:
        - `none`: Not encrypted in transit.
        - `user_managed`: Encrypted in transit using an instance identity certificate.
        The
                          `access_control_mode` for the share must be `security_group`.
        """

        NONE = 'none'
        USER_MANAGED = 'user_managed'



class ShareMountTargetPrototypeShareMountTargetByAccessControlModeVPC(ShareMountTargetPrototype):
    """
    The VPC in which clients can mount the file share using this mount target.  The VPC
    must not be used by another mount target for this share.
    Required if the share's `access_control_mode` is `vpc`.

    :attr str name: (optional) The name for this share mount target. The name must
          not be used by another mount target for the file share.
    :attr str transit_encryption: (optional) The transit encryption mode to use for
          this share mount target:
          - `none`: Not encrypted in transit.
          - `user_managed`: Encrypted in transit using an instance identity certificate.
          The
                            `access_control_mode` for the share must be `security_group`.
    :attr VPCIdentity vpc: Identifies a VPC by a unique property.
    """

    def __init__(
        self,
        vpc: 'VPCIdentity',
        *,
        name: str = None,
        transit_encryption: str = None,
    ) -> None:
        """
        Initialize a ShareMountTargetPrototypeShareMountTargetByAccessControlModeVPC object.

        :param VPCIdentity vpc: Identifies a VPC by a unique property.
        :param str name: (optional) The name for this share mount target. The name
               must not be used by another mount target for the file share.
        :param str transit_encryption: (optional) The transit encryption mode to
               use for this share mount target:
               - `none`: Not encrypted in transit.
               - `user_managed`: Encrypted in transit using an instance identity
               certificate.  The
                                 `access_control_mode` for the share must be
               `security_group`.
        """
        # pylint: disable=super-init-not-called
        self.name = name
        self.transit_encryption = transit_encryption
        self.vpc = vpc

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ShareMountTargetPrototypeShareMountTargetByAccessControlModeVPC':
        """Initialize a ShareMountTargetPrototypeShareMountTargetByAccessControlModeVPC object from a json dictionary."""
        args = {}
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        if 'transit_encryption' in _dict:
            args['transit_encryption'] = _dict.get('transit_encryption')
        if 'vpc' in _dict:
            args['vpc'] = _dict.get('vpc')
        else:
            raise ValueError('Required property \'vpc\' not present in ShareMountTargetPrototypeShareMountTargetByAccessControlModeVPC JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ShareMountTargetPrototypeShareMountTargetByAccessControlModeVPC object from 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, 'transit_encryption') and self.transit_encryption is not None:
            _dict['transit_encryption'] = self.transit_encryption
        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()
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this ShareMountTargetPrototypeShareMountTargetByAccessControlModeVPC object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ShareMountTargetPrototypeShareMountTargetByAccessControlModeVPC') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ShareMountTargetPrototypeShareMountTargetByAccessControlModeVPC') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class TransitEncryptionEnum(str, Enum):
        """
        The transit encryption mode to use for this share mount target:
        - `none`: Not encrypted in transit.
        - `user_managed`: Encrypted in transit using an instance identity certificate.
        The
                          `access_control_mode` for the share must be `security_group`.
        """

        NONE = 'none'
        USER_MANAGED = 'user_managed'



class ShareMountTargetVirtualNetworkInterfacePrototypeVirtualNetworkInterfacePrototypeShareMountTargetContext(ShareMountTargetVirtualNetworkInterfacePrototype):
    """
    The virtual network interface for this target.

    :attr str name: (optional) The name for this virtual network interface. The name
          must not be used by another virtual network interface in the VPC. If
          unspecified, the name will be a hyphenated list of randomly-selected words.
          Names beginning with `ibm-` are reserved for provider-owned resources, and are
          not allowed.
    :attr VirtualNetworkInterfacePrimaryIPPrototype primary_ip: (optional) The
          primary IP address to bind to the virtual network interface. May be either a
          reserved IP identity, or a reserved IP prototype object which will be used to
          create a
          new reserved IP.
          If a reserved IP identity is provided, the specified reserved IP must be
          unbound.
          If a reserved IP prototype object with an address is provided, the address must
          be
          available on the virtual network interface's subnet. If no address is specified,
          an available address on the subnet will be automatically selected and reserved.
    :attr ResourceGroupIdentity resource_group: (optional) The resource group to use
          for this virtual network interface. If unspecified, the
          share's resource group will be used.
    :attr List[SecurityGroupIdentity] security_groups: (optional) The security
          groups to use for this virtual network interface. If unspecified, the default
          security group of the VPC for the subnet is used.
    :attr SubnetIdentity subnet: (optional) The associated subnet. Required if
          `primary_ip` does not specify a reserved IP
          identity.
    """

    def __init__(
        self,
        *,
        name: str = None,
        primary_ip: 'VirtualNetworkInterfacePrimaryIPPrototype' = None,
        resource_group: 'ResourceGroupIdentity' = None,
        security_groups: List['SecurityGroupIdentity'] = None,
        subnet: 'SubnetIdentity' = None,
    ) -> None:
        """
        Initialize a ShareMountTargetVirtualNetworkInterfacePrototypeVirtualNetworkInterfacePrototypeShareMountTargetContext object.

        :param str name: (optional) The name for this virtual network interface.
               The name must not be used by another virtual network interface in the VPC.
               If unspecified, the name will be a hyphenated list of randomly-selected
               words. Names beginning with `ibm-` are reserved for provider-owned
               resources, and are not allowed.
        :param VirtualNetworkInterfacePrimaryIPPrototype primary_ip: (optional) The
               primary IP address to bind to the virtual network interface. May be either
               a
               reserved IP identity, or a reserved IP prototype object which will be used
               to create a
               new reserved IP.
               If a reserved IP identity is provided, the specified reserved IP must be
               unbound.
               If a reserved IP prototype object with an address is provided, the address
               must be
               available on the virtual network interface's subnet. If no address is
               specified,
               an available address on the subnet will be automatically selected and
               reserved.
        :param ResourceGroupIdentity resource_group: (optional) The resource group
               to use for this virtual network interface. If unspecified, the
               share's resource group will be used.
        :param List[SecurityGroupIdentity] security_groups: (optional) The security
               groups to use for this virtual network interface. If unspecified, the
               default security group of the VPC for the subnet is used.
        :param SubnetIdentity subnet: (optional) The associated subnet. Required if
               `primary_ip` does not specify a reserved IP
               identity.
        """
        # pylint: disable=super-init-not-called
        self.name = name
        self.primary_ip = primary_ip
        self.resource_group = resource_group
        self.security_groups = security_groups
        self.subnet = subnet

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ShareMountTargetVirtualNetworkInterfacePrototypeVirtualNetworkInterfacePrototypeShareMountTargetContext':
        """Initialize a ShareMountTargetVirtualNetworkInterfacePrototypeVirtualNetworkInterfacePrototypeShareMountTargetContext object from a json dictionary."""
        args = {}
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        if 'primary_ip' in _dict:
            args['primary_ip'] = _dict.get('primary_ip')
        if 'resource_group' in _dict:
            args['resource_group'] = _dict.get('resource_group')
        if 'security_groups' in _dict:
            args['security_groups'] = _dict.get('security_groups')
        if 'subnet' in _dict:
            args['subnet'] = _dict.get('subnet')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ShareMountTargetVirtualNetworkInterfacePrototypeVirtualNetworkInterfacePrototypeShareMountTargetContext object from 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_ip') and self.primary_ip is not None:
            if isinstance(self.primary_ip, dict):
                _dict['primary_ip'] = self.primary_ip
            else:
                _dict['primary_ip'] = self.primary_ip.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, 'security_groups') and self.security_groups is not None:
            security_groups_list = []
            for v in self.security_groups:
                if isinstance(v, dict):
                    security_groups_list.append(v)
                else:
                    security_groups_list.append(v.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 ShareMountTargetVirtualNetworkInterfacePrototypeVirtualNetworkInterfacePrototypeShareMountTargetContext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ShareMountTargetVirtualNetworkInterfacePrototypeVirtualNetworkInterfacePrototypeShareMountTargetContext') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ShareMountTargetVirtualNetworkInterfacePrototypeVirtualNetworkInterfacePrototypeShareMountTargetContext') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class ShareProfileCapacityDependentRange(ShareProfileCapacity):
    """
    The permitted total capacity (in gigabytes) of a share with this profile depends on
    its configuration.

    :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,
        max: int,
        min: int,
        step: int,
        type: str,
    ) -> None:
        """
        Initialize a ShareProfileCapacityDependentRange object.

        :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.max = max
        self.min = min
        self.step = step
        self.type = type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ShareProfileCapacityDependentRange':
        """Initialize a ShareProfileCapacityDependentRange object from a json dictionary."""
        args = {}
        if 'max' in _dict:
            args['max'] = _dict.get('max')
        else:
            raise ValueError('Required property \'max\' not present in ShareProfileCapacityDependentRange JSON')
        if 'min' in _dict:
            args['min'] = _dict.get('min')
        else:
            raise ValueError('Required property \'min\' not present in ShareProfileCapacityDependentRange JSON')
        if 'step' in _dict:
            args['step'] = _dict.get('step')
        else:
            raise ValueError('Required property \'step\' not present in ShareProfileCapacityDependentRange JSON')
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in ShareProfileCapacityDependentRange JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ShareProfileCapacityDependentRange object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'max') 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 ShareProfileCapacityDependentRange object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ShareProfileCapacityDependentRange') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ShareProfileCapacityDependentRange') -> 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'
        DEPENDENT_RANGE = 'dependent_range'



class ShareProfileCapacityEnum(ShareProfileCapacity):
    """
    The permitted total capacities (in gigabytes) of a share 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 ShareProfileCapacityEnum 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) -> 'ShareProfileCapacityEnum':
        """Initialize a ShareProfileCapacityEnum object from a json dictionary."""
        args = {}
        if 'default' in _dict:
            args['default'] = _dict.get('default')
        else:
            raise ValueError('Required property \'default\' not present in ShareProfileCapacityEnum JSON')
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in ShareProfileCapacityEnum JSON')
        if 'values' in _dict:
            args['values'] = _dict.get('values')
        else:
            raise ValueError('Required property \'values\' not present in ShareProfileCapacityEnum JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ShareProfileCapacityEnum object from 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 ShareProfileCapacityEnum object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ShareProfileCapacityEnum') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ShareProfileCapacityEnum') -> 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 ShareProfileCapacityFixed(ShareProfileCapacity):
    """
    The permitted total capacity (in gigabytes) of a share with this profile is fixed.

    :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 ShareProfileCapacityFixed 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) -> 'ShareProfileCapacityFixed':
        """Initialize a ShareProfileCapacityFixed object from a json dictionary."""
        args = {}
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in ShareProfileCapacityFixed JSON')
        if 'value' in _dict:
            args['value'] = _dict.get('value')
        else:
            raise ValueError('Required property \'value\' not present in ShareProfileCapacityFixed JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ShareProfileCapacityFixed object from 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 ShareProfileCapacityFixed object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ShareProfileCapacityFixed') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ShareProfileCapacityFixed') -> 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 ShareProfileCapacityRange(ShareProfileCapacity):
    """
    The permitted total capacity range (in gigabytes) of a share 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 ShareProfileCapacityRange 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) -> 'ShareProfileCapacityRange':
        """Initialize a ShareProfileCapacityRange object from a json dictionary."""
        args = {}
        if 'default' in _dict:
            args['default'] = _dict.get('default')
        else:
            raise ValueError('Required property \'default\' not present in ShareProfileCapacityRange JSON')
        if 'max' in _dict:
            args['max'] = _dict.get('max')
        else:
            raise ValueError('Required property \'max\' not present in ShareProfileCapacityRange JSON')
        if 'min' in _dict:
            args['min'] = _dict.get('min')
        else:
            raise ValueError('Required property \'min\' not present in ShareProfileCapacityRange JSON')
        if 'step' in _dict:
            args['step'] = _dict.get('step')
        else:
            raise ValueError('Required property \'step\' not present in ShareProfileCapacityRange JSON')
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in ShareProfileCapacityRange JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ShareProfileCapacityRange object from 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 ShareProfileCapacityRange object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ShareProfileCapacityRange') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ShareProfileCapacityRange') -> 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 ShareProfileIOPSDependentRange(ShareProfileIOPS):
    """
    The permitted IOPS range of a share with this profile depends on its configuration.

    :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,
        max: int,
        min: int,
        step: int,
        type: str,
    ) -> None:
        """
        Initialize a ShareProfileIOPSDependentRange object.

        :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.max = max
        self.min = min
        self.step = step
        self.type = type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ShareProfileIOPSDependentRange':
        """Initialize a ShareProfileIOPSDependentRange object from a json dictionary."""
        args = {}
        if 'max' in _dict:
            args['max'] = _dict.get('max')
        else:
            raise ValueError('Required property \'max\' not present in ShareProfileIOPSDependentRange JSON')
        if 'min' in _dict:
            args['min'] = _dict.get('min')
        else:
            raise ValueError('Required property \'min\' not present in ShareProfileIOPSDependentRange JSON')
        if 'step' in _dict:
            args['step'] = _dict.get('step')
        else:
            raise ValueError('Required property \'step\' not present in ShareProfileIOPSDependentRange JSON')
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in ShareProfileIOPSDependentRange JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ShareProfileIOPSDependentRange object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'max') 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 ShareProfileIOPSDependentRange object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ShareProfileIOPSDependentRange') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ShareProfileIOPSDependentRange') -> 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'
        DEPENDENT_RANGE = 'dependent_range'



class ShareProfileIOPSEnum(ShareProfileIOPS):
    """
    The permitted IOPS values of a share 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 ShareProfileIOPSEnum 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) -> 'ShareProfileIOPSEnum':
        """Initialize a ShareProfileIOPSEnum object from a json dictionary."""
        args = {}
        if 'default' in _dict:
            args['default'] = _dict.get('default')
        else:
            raise ValueError('Required property \'default\' not present in ShareProfileIOPSEnum JSON')
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in ShareProfileIOPSEnum JSON')
        if 'values' in _dict:
            args['values'] = _dict.get('values')
        else:
            raise ValueError('Required property \'values\' not present in ShareProfileIOPSEnum JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ShareProfileIOPSEnum object from 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 ShareProfileIOPSEnum object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ShareProfileIOPSEnum') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ShareProfileIOPSEnum') -> 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 ShareProfileIOPSFixed(ShareProfileIOPS):
    """
    The permitted IOPS of a share with this profile is fixed.

    :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 ShareProfileIOPSFixed 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) -> 'ShareProfileIOPSFixed':
        """Initialize a ShareProfileIOPSFixed object from a json dictionary."""
        args = {}
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in ShareProfileIOPSFixed JSON')
        if 'value' in _dict:
            args['value'] = _dict.get('value')
        else:
            raise ValueError('Required property \'value\' not present in ShareProfileIOPSFixed JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ShareProfileIOPSFixed object from 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 ShareProfileIOPSFixed object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ShareProfileIOPSFixed') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ShareProfileIOPSFixed') -> 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 ShareProfileIOPSRange(ShareProfileIOPS):
    """
    The permitted IOPS range of a share 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 ShareProfileIOPSRange 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) -> 'ShareProfileIOPSRange':
        """Initialize a ShareProfileIOPSRange object from a json dictionary."""
        args = {}
        if 'default' in _dict:
            args['default'] = _dict.get('default')
        else:
            raise ValueError('Required property \'default\' not present in ShareProfileIOPSRange JSON')
        if 'max' in _dict:
            args['max'] = _dict.get('max')
        else:
            raise ValueError('Required property \'max\' not present in ShareProfileIOPSRange JSON')
        if 'min' in _dict:
            args['min'] = _dict.get('min')
        else:
            raise ValueError('Required property \'min\' not present in ShareProfileIOPSRange JSON')
        if 'step' in _dict:
            args['step'] = _dict.get('step')
        else:
            raise ValueError('Required property \'step\' not present in ShareProfileIOPSRange JSON')
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in ShareProfileIOPSRange JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ShareProfileIOPSRange object from 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 ShareProfileIOPSRange object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ShareProfileIOPSRange') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ShareProfileIOPSRange') -> 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 ShareProfileIdentityByHref(ShareProfileIdentity):
    """
    ShareProfileIdentityByHref.

    :attr str href: The URL for this share profile.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a ShareProfileIdentityByHref object.

        :param str href: The URL for this share profile.
        """
        # pylint: disable=super-init-not-called
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ShareProfileIdentityByHref':
        """Initialize a ShareProfileIdentityByHref object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in ShareProfileIdentityByHref JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ShareProfileIdentityByHref object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(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 ShareProfileIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ShareProfileIdentityByHref') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ShareProfileIdentityByHref') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class ShareProfileIdentityByName(ShareProfileIdentity):
    """
    ShareProfileIdentityByName.

    :attr str name: The globally unique name for this share profile.
    """

    def __init__(
        self,
        name: str,
    ) -> None:
        """
        Initialize a ShareProfileIdentityByName object.

        :param str name: The globally unique name for this share profile.
        """
        # pylint: disable=super-init-not-called
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ShareProfileIdentityByName':
        """Initialize a ShareProfileIdentityByName object from a json dictionary."""
        args = {}
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in ShareProfileIdentityByName JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ShareProfileIdentityByName object from 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 ShareProfileIdentityByName object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ShareProfileIdentityByName') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ShareProfileIdentityByName') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class SharePrototypeShareBySize(SharePrototype):
    """
    Create a file share by size.

    :attr int iops: (optional) The maximum input/output operations per second (IOPS)
          for the file share. The share must be in the `defined_performance` profile
          family, and the value must be in the range supported by the share's specified
          size.
          In addition, each client accessing the share will be restricted to 48,000 IOPS.
    :attr List[ShareMountTargetPrototype] mount_targets: (optional) The mount
          targets for the file share. Each mount target must be in a unique VPC.
    :attr str name: (optional) The name for this share. The name must not be used by
          another share in the region. If unspecified, the name will be a hyphenated list
          of randomly-selected words.
    :attr ShareProfileIdentity profile: The
          [profile](https://cloud.ibm.com/docs/vpc?topic=vpc-file-storage-profiles) to use
          for this file share. The profile must support the share's specified IOPS and
          size.
    :attr SharePrototypeShareContext replica_share: (optional)
    :attr List[str] user_tags: (optional) Tags for this resource.
    :attr ZoneIdentity zone: The zone this file share will reside in.
          For a replica share, this must be a different zone in the same region as the
          source share.
    :attr str access_control_mode: (optional) The access control mode for the share:
          - `security_group`: The security groups on the virtual network interface for a
            mount target control access to the mount target. Mount targets for this share
            require a virtual network interface.
          - `vpc`: All clients in the VPC for a mount target have access to the mount
          target.
            Mount targets for this share require a VPC.
    :attr EncryptionKeyIdentity encryption_key: (optional) The root key to use to
          wrap the data encryption key for the share.
          If unspecified, the `encryption` type for the share will be `provider_managed`.
          The specified key may be in a different account, subject to IAM policies.
    :attr ShareInitialOwner initial_owner: (optional) The owner assigned to the file
          share at creation. Subsequent changes to the owner
          must be performed by a client that has mounted the file share.
    :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) will be
          used.
    :attr int size: The size of the file share rounded up to the next gigabyte.
          The maximum size for a share may increase in the future.
    """

    def __init__(
        self,
        profile: 'ShareProfileIdentity',
        zone: 'ZoneIdentity',
        size: int,
        *,
        iops: int = None,
        mount_targets: List['ShareMountTargetPrototype'] = None,
        name: str = None,
        replica_share: 'SharePrototypeShareContext' = None,
        user_tags: List[str] = None,
        access_control_mode: str = None,
        encryption_key: 'EncryptionKeyIdentity' = None,
        initial_owner: 'ShareInitialOwner' = None,
        resource_group: 'ResourceGroupIdentity' = None,
    ) -> None:
        """
        Initialize a SharePrototypeShareBySize object.

        :param ShareProfileIdentity profile: The
               [profile](https://cloud.ibm.com/docs/vpc?topic=vpc-file-storage-profiles)
               to use for this file share. The profile must support the share's specified
               IOPS and size.
        :param ZoneIdentity zone: The zone this file share will reside in.
               For a replica share, this must be a different zone in the same region as
               the source share.
        :param int size: The size of the file share rounded up to the next
               gigabyte.
               The maximum size for a share may increase in the future.
        :param int iops: (optional) The maximum input/output operations per second
               (IOPS) for the file share. The share must be in the `defined_performance`
               profile family, and the value must be in the range supported by the share's
               specified size.
               In addition, each client accessing the share will be restricted to 48,000
               IOPS.
        :param List[ShareMountTargetPrototype] mount_targets: (optional) The mount
               targets for the file share. Each mount target must be in a unique VPC.
        :param str name: (optional) The name for this share. The name must not be
               used by another share in the region. If unspecified, the name will be a
               hyphenated list of randomly-selected words.
        :param SharePrototypeShareContext replica_share: (optional)
        :param List[str] user_tags: (optional) Tags for this resource.
        :param str access_control_mode: (optional) The access control mode for the
               share:
               - `security_group`: The security groups on the virtual network interface
               for a
                 mount target control access to the mount target. Mount targets for this
               share
                 require a virtual network interface.
               - `vpc`: All clients in the VPC for a mount target have access to the mount
               target.
                 Mount targets for this share require a VPC.
        :param EncryptionKeyIdentity encryption_key: (optional) The root key to use
               to wrap the data encryption key for the share.
               If unspecified, the `encryption` type for the share will be
               `provider_managed`.
               The specified key may be in a different account, subject to IAM policies.
        :param ShareInitialOwner initial_owner: (optional) The owner assigned to
               the file share at creation. Subsequent changes to the owner
               must be performed by a client that has mounted the file share.
        :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) will be
               used.
        """
        # pylint: disable=super-init-not-called
        self.iops = iops
        self.mount_targets = mount_targets
        self.name = name
        self.profile = profile
        self.replica_share = replica_share
        self.user_tags = user_tags
        self.zone = zone
        self.access_control_mode = access_control_mode
        self.encryption_key = encryption_key
        self.initial_owner = initial_owner
        self.resource_group = resource_group
        self.size = size

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'SharePrototypeShareBySize':
        """Initialize a SharePrototypeShareBySize object from a json dictionary."""
        args = {}
        if 'iops' in _dict:
            args['iops'] = _dict.get('iops')
        if 'mount_targets' in _dict:
            args['mount_targets'] = _dict.get('mount_targets')
        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 SharePrototypeShareBySize JSON')
        if 'replica_share' in _dict:
            args['replica_share'] = SharePrototypeShareContext.from_dict(_dict.get('replica_share'))
        if 'user_tags' in _dict:
            args['user_tags'] = _dict.get('user_tags')
        if 'zone' in _dict:
            args['zone'] = _dict.get('zone')
        else:
            raise ValueError('Required property \'zone\' not present in SharePrototypeShareBySize JSON')
        if 'access_control_mode' in _dict:
            args['access_control_mode'] = _dict.get('access_control_mode')
        if 'encryption_key' in _dict:
            args['encryption_key'] = _dict.get('encryption_key')
        if 'initial_owner' in _dict:
            args['initial_owner'] = ShareInitialOwner.from_dict(_dict.get('initial_owner'))
        if 'resource_group' in _dict:
            args['resource_group'] = _dict.get('resource_group')
        if 'size' in _dict:
            args['size'] = _dict.get('size')
        else:
            raise ValueError('Required property \'size\' not present in SharePrototypeShareBySize JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SharePrototypeShareBySize object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'iops') and self.iops is not None:
            _dict['iops'] = self.iops
        if hasattr(self, 'mount_targets') and self.mount_targets is not None:
            mount_targets_list = []
            for v in self.mount_targets:
                if isinstance(v, dict):
                    mount_targets_list.append(v)
                else:
                    mount_targets_list.append(v.to_dict())
            _dict['mount_targets'] = mount_targets_list
        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, 'replica_share') and self.replica_share is not None:
            if isinstance(self.replica_share, dict):
                _dict['replica_share'] = self.replica_share
            else:
                _dict['replica_share'] = self.replica_share.to_dict()
        if hasattr(self, 'user_tags') and self.user_tags is not None:
            _dict['user_tags'] = self.user_tags
        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, 'access_control_mode') and self.access_control_mode is not None:
            _dict['access_control_mode'] = self.access_control_mode
        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, 'initial_owner') and self.initial_owner is not None:
            if isinstance(self.initial_owner, dict):
                _dict['initial_owner'] = self.initial_owner
            else:
                _dict['initial_owner'] = self.initial_owner.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, '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 SharePrototypeShareBySize object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'SharePrototypeShareBySize') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'SharePrototypeShareBySize') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class AccessControlModeEnum(str, Enum):
        """
        The access control mode for the share:
        - `security_group`: The security groups on the virtual network interface for a
          mount target control access to the mount target. Mount targets for this share
          require a virtual network interface.
        - `vpc`: All clients in the VPC for a mount target have access to the mount
        target.
          Mount targets for this share require a VPC.
        """

        SECURITY_GROUP = 'security_group'
        VPC = 'vpc'



class SharePrototypeShareBySourceShare(SharePrototype):
    """
    Create a replica file share for an existing file share. The values for
    `access_control_mode`,
    `encryption_key`, `initial_owner`, and `size` will be inherited from `source_share`.

    :attr int iops: (optional) The maximum input/output operations per second (IOPS)
          for the file share. The share must be in the `defined_performance` profile
          family, and the value must be in the range supported by the share's specified
          size.
          In addition, each client accessing the share will be restricted to 48,000 IOPS.
    :attr List[ShareMountTargetPrototype] mount_targets: (optional) The mount
          targets for the file share. Each mount target must be in a unique VPC.
    :attr str name: (optional) The name for this share. The name must not be used by
          another share in the region. If unspecified, the name will be a hyphenated list
          of randomly-selected words.
    :attr ShareProfileIdentity profile: The
          [profile](https://cloud.ibm.com/docs/vpc?topic=vpc-file-storage-profiles) to use
          for this file share. The profile must support the share's specified IOPS and
          size.
    :attr SharePrototypeShareContext replica_share: (optional)
    :attr List[str] user_tags: (optional) Tags for this resource.
    :attr ZoneIdentity zone: The zone this file share will reside in.
          For a replica share, this must be a different zone in the same region as the
          source share.
    :attr str replication_cron_spec: The cron specification for the file share
          replication schedule.
          Replication of a share can be scheduled to occur at most once per hour.
    :attr ResourceGroupIdentity resource_group: (optional) The resource group to
          use. If unspecified, the resource group from
          the source share will be used.
    :attr ShareIdentity source_share: The source file share for this replica file
          share. The specified file share must not
          already have a replica, and must not be a replica.
    """

    def __init__(
        self,
        profile: 'ShareProfileIdentity',
        zone: 'ZoneIdentity',
        replication_cron_spec: str,
        source_share: 'ShareIdentity',
        *,
        iops: int = None,
        mount_targets: List['ShareMountTargetPrototype'] = None,
        name: str = None,
        replica_share: 'SharePrototypeShareContext' = None,
        user_tags: List[str] = None,
        resource_group: 'ResourceGroupIdentity' = None,
    ) -> None:
        """
        Initialize a SharePrototypeShareBySourceShare object.

        :param ShareProfileIdentity profile: The
               [profile](https://cloud.ibm.com/docs/vpc?topic=vpc-file-storage-profiles)
               to use for this file share. The profile must support the share's specified
               IOPS and size.
        :param ZoneIdentity zone: The zone this file share will reside in.
               For a replica share, this must be a different zone in the same region as
               the source share.
        :param str replication_cron_spec: The cron specification for the file share
               replication schedule.
               Replication of a share can be scheduled to occur at most once per hour.
        :param ShareIdentity source_share: The source file share for this replica
               file share. The specified file share must not
               already have a replica, and must not be a replica.
        :param int iops: (optional) The maximum input/output operations per second
               (IOPS) for the file share. The share must be in the `defined_performance`
               profile family, and the value must be in the range supported by the share's
               specified size.
               In addition, each client accessing the share will be restricted to 48,000
               IOPS.
        :param List[ShareMountTargetPrototype] mount_targets: (optional) The mount
               targets for the file share. Each mount target must be in a unique VPC.
        :param str name: (optional) The name for this share. The name must not be
               used by another share in the region. If unspecified, the name will be a
               hyphenated list of randomly-selected words.
        :param SharePrototypeShareContext replica_share: (optional)
        :param List[str] user_tags: (optional) Tags for this resource.
        :param ResourceGroupIdentity resource_group: (optional) The resource group
               to use. If unspecified, the resource group from
               the source share will be used.
        """
        # pylint: disable=super-init-not-called
        self.iops = iops
        self.mount_targets = mount_targets
        self.name = name
        self.profile = profile
        self.replica_share = replica_share
        self.user_tags = user_tags
        self.zone = zone
        self.replication_cron_spec = replication_cron_spec
        self.resource_group = resource_group
        self.source_share = source_share

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'SharePrototypeShareBySourceShare':
        """Initialize a SharePrototypeShareBySourceShare object from a json dictionary."""
        args = {}
        if 'iops' in _dict:
            args['iops'] = _dict.get('iops')
        if 'mount_targets' in _dict:
            args['mount_targets'] = _dict.get('mount_targets')
        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 SharePrototypeShareBySourceShare JSON')
        if 'replica_share' in _dict:
            args['replica_share'] = SharePrototypeShareContext.from_dict(_dict.get('replica_share'))
        if 'user_tags' in _dict:
            args['user_tags'] = _dict.get('user_tags')
        if 'zone' in _dict:
            args['zone'] = _dict.get('zone')
        else:
            raise ValueError('Required property \'zone\' not present in SharePrototypeShareBySourceShare JSON')
        if 'replication_cron_spec' in _dict:
            args['replication_cron_spec'] = _dict.get('replication_cron_spec')
        else:
            raise ValueError('Required property \'replication_cron_spec\' not present in SharePrototypeShareBySourceShare JSON')
        if 'resource_group' in _dict:
            args['resource_group'] = _dict.get('resource_group')
        if 'source_share' in _dict:
            args['source_share'] = _dict.get('source_share')
        else:
            raise ValueError('Required property \'source_share\' not present in SharePrototypeShareBySourceShare JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SharePrototypeShareBySourceShare object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'iops') and self.iops is not None:
            _dict['iops'] = self.iops
        if hasattr(self, 'mount_targets') and self.mount_targets is not None:
            mount_targets_list = []
            for v in self.mount_targets:
                if isinstance(v, dict):
                    mount_targets_list.append(v)
                else:
                    mount_targets_list.append(v.to_dict())
            _dict['mount_targets'] = mount_targets_list
        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, 'replica_share') and self.replica_share is not None:
            if isinstance(self.replica_share, dict):
                _dict['replica_share'] = self.replica_share
            else:
                _dict['replica_share'] = self.replica_share.to_dict()
        if hasattr(self, 'user_tags') and self.user_tags is not None:
            _dict['user_tags'] = self.user_tags
        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, 'replication_cron_spec') and self.replication_cron_spec is not None:
            _dict['replication_cron_spec'] = self.replication_cron_spec
        if hasattr(self, 'resource_group') and self.resource_group is not None:
            if isinstance(self.resource_group, dict):
                _dict['resource_group'] = self.resource_group
            else:
                _dict['resource_group'] = self.resource_group.to_dict()
        if hasattr(self, 'source_share') and self.source_share is not None:
            if isinstance(self.source_share, dict):
                _dict['source_share'] = self.source_share
            else:
                _dict['source_share'] = self.source_share.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 SharePrototypeShareBySourceShare object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'SharePrototypeShareBySourceShare') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'SharePrototypeShareBySourceShare') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class SnapshotIdentityByCRN(SnapshotIdentity):
    """
    SnapshotIdentityByCRN.

    :attr str crn: The CRN of this snapshot.
    """

    def __init__(
        self,
        crn: str,
    ) -> None:
        """
        Initialize a SnapshotIdentityByCRN object.

        :param str crn: The CRN of this snapshot.
        """
        # pylint: disable=super-init-not-called
        self.crn = crn

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'SnapshotIdentityByCRN':
        """Initialize a SnapshotIdentityByCRN object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError('Required property \'crn\' not present in SnapshotIdentityByCRN JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SnapshotIdentityByCRN object from 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 SnapshotIdentityByCRN object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'SnapshotIdentityByCRN') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'SnapshotIdentityByCRN') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class SnapshotIdentityByHref(SnapshotIdentity):
    """
    SnapshotIdentityByHref.

    :attr str href: The URL for this snapshot.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a SnapshotIdentityByHref object.

        :param str href: The URL for this snapshot.
        """
        # pylint: disable=super-init-not-called
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'SnapshotIdentityByHref':
        """Initialize a SnapshotIdentityByHref object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in SnapshotIdentityByHref JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SnapshotIdentityByHref object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(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 SnapshotIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'SnapshotIdentityByHref') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'SnapshotIdentityByHref') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class SnapshotIdentityById(SnapshotIdentity):
    """
    SnapshotIdentityById.

    :attr str id: The unique identifier for this snapshot.
    """

    def __init__(
        self,
        id: str,
    ) -> None:
        """
        Initialize a SnapshotIdentityById object.

        :param str id: The unique identifier for this snapshot.
        """
        # pylint: disable=super-init-not-called
        self.id = id

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'SnapshotIdentityById':
        """Initialize a SnapshotIdentityById object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in SnapshotIdentityById JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SnapshotIdentityById object from 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 SnapshotIdentityById object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'SnapshotIdentityById') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'SnapshotIdentityById') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class SnapshotPrototypeSnapshotBySourceSnapshot(SnapshotPrototype):
    """
    SnapshotPrototypeSnapshotBySourceSnapshot.

    :attr List[SnapshotClonePrototype] clones: (optional) Clones to create for this
          snapshot.
    :attr str name: (optional) The name for this snapshot. The name must not be used
          by another snapshot in the region. If unspecified, the name will be a hyphenated
          list of randomly-selected words.
    :attr ResourceGroupIdentity resource_group: (optional)
    :attr List[str] user_tags: (optional) The [user
          tags](https://cloud.ibm.com/apidocs/tagging#types-of-tags) associated with this
          snapshot.
    :attr EncryptionKeyIdentity encryption_key: (optional) The root key to use to
          wrap the data encryption key for this snapshot.
          A key must be specified if and only if the source snapshot has an `encryption`
          type of
          `user_managed`. To maximize snapshot availability and sharing of snapshot data,
          specify
          a key in the same region as the new snapshot, and use the same encryption key
          for all
          snapshots using the same source volume.
          The specified key may be in a different account, subject to IAM policies.
    :attr SnapshotIdentityByCRN source_snapshot: The source snapshot (in another
          region) to create this snapshot from.
          The specified snapshot must not already be the source of another snapshot in
          this
          region.
    """

    def __init__(
        self,
        source_snapshot: 'SnapshotIdentityByCRN',
        *,
        clones: List['SnapshotClonePrototype'] = None,
        name: str = None,
        resource_group: 'ResourceGroupIdentity' = None,
        user_tags: List[str] = None,
        encryption_key: 'EncryptionKeyIdentity' = None,
    ) -> None:
        """
        Initialize a SnapshotPrototypeSnapshotBySourceSnapshot object.

        :param SnapshotIdentityByCRN source_snapshot: The source snapshot (in
               another region) to create this snapshot from.
               The specified snapshot must not already be the source of another snapshot
               in this
               region.
        :param List[SnapshotClonePrototype] clones: (optional) Clones to create for
               this snapshot.
        :param str name: (optional) The name for this snapshot. The name must not
               be used by another snapshot in the region. If unspecified, the name will be
               a hyphenated list of randomly-selected words.
        :param ResourceGroupIdentity resource_group: (optional)
        :param List[str] user_tags: (optional) The [user
               tags](https://cloud.ibm.com/apidocs/tagging#types-of-tags) associated with
               this snapshot.
        :param EncryptionKeyIdentity encryption_key: (optional) The root key to use
               to wrap the data encryption key for this snapshot.
               A key must be specified if and only if the source snapshot has an
               `encryption` type of
               `user_managed`. To maximize snapshot availability and sharing of snapshot
               data, specify
               a key in the same region as the new snapshot, and use the same encryption
               key for all
               snapshots using the same source volume.
               The specified key may be in a different account, subject to IAM policies.
        """
        # pylint: disable=super-init-not-called
        self.clones = clones
        self.name = name
        self.resource_group = resource_group
        self.user_tags = user_tags
        self.encryption_key = encryption_key
        self.source_snapshot = source_snapshot

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'SnapshotPrototypeSnapshotBySourceSnapshot':
        """Initialize a SnapshotPrototypeSnapshotBySourceSnapshot object from a json dictionary."""
        args = {}
        if 'clones' in _dict:
            args['clones'] = [SnapshotClonePrototype.from_dict(v) for v in _dict.get('clones')]
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        if 'resource_group' in _dict:
            args['resource_group'] = _dict.get('resource_group')
        if 'user_tags' in _dict:
            args['user_tags'] = _dict.get('user_tags')
        if 'encryption_key' in _dict:
            args['encryption_key'] = _dict.get('encryption_key')
        if 'source_snapshot' in _dict:
            args['source_snapshot'] = SnapshotIdentityByCRN.from_dict(_dict.get('source_snapshot'))
        else:
            raise ValueError('Required property \'source_snapshot\' not present in SnapshotPrototypeSnapshotBySourceSnapshot JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SnapshotPrototypeSnapshotBySourceSnapshot object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'clones') and self.clones is not None:
            clones_list = []
            for v in self.clones:
                if isinstance(v, dict):
                    clones_list.append(v)
                else:
                    clones_list.append(v.to_dict())
            _dict['clones'] = clones_list
        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, 'user_tags') and self.user_tags is not None:
            _dict['user_tags'] = self.user_tags
        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, 'source_snapshot') and self.source_snapshot is not None:
            if isinstance(self.source_snapshot, dict):
                _dict['source_snapshot'] = self.source_snapshot
            else:
                _dict['source_snapshot'] = self.source_snapshot.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 SnapshotPrototypeSnapshotBySourceSnapshot object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'SnapshotPrototypeSnapshotBySourceSnapshot') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'SnapshotPrototypeSnapshotBySourceSnapshot') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class SnapshotPrototypeSnapshotBySourceVolume(SnapshotPrototype):
    """
    SnapshotPrototypeSnapshotBySourceVolume.

    :attr List[SnapshotClonePrototype] clones: (optional) Clones to create for this
          snapshot.
    :attr str name: (optional) The name for this snapshot. The name must not be used
          by another snapshot in the region. If unspecified, the name will be a hyphenated
          list of randomly-selected words.
    :attr ResourceGroupIdentity resource_group: (optional)
    :attr List[str] user_tags: (optional) The [user
          tags](https://cloud.ibm.com/apidocs/tagging#types-of-tags) associated with this
          snapshot.
    :attr VolumeIdentity source_volume: The volume to create this snapshot from.
    """

    def __init__(
        self,
        source_volume: 'VolumeIdentity',
        *,
        clones: List['SnapshotClonePrototype'] = None,
        name: str = None,
        resource_group: 'ResourceGroupIdentity' = None,
        user_tags: List[str] = None,
    ) -> None:
        """
        Initialize a SnapshotPrototypeSnapshotBySourceVolume object.

        :param VolumeIdentity source_volume: The volume to create this snapshot
               from.
        :param List[SnapshotClonePrototype] clones: (optional) Clones to create for
               this snapshot.
        :param str name: (optional) The name for this snapshot. The name must not
               be used by another snapshot in the region. If unspecified, the name will be
               a hyphenated list of randomly-selected words.
        :param ResourceGroupIdentity resource_group: (optional)
        :param List[str] user_tags: (optional) The [user
               tags](https://cloud.ibm.com/apidocs/tagging#types-of-tags) associated with
               this snapshot.
        """
        # pylint: disable=super-init-not-called
        self.clones = clones
        self.name = name
        self.resource_group = resource_group
        self.user_tags = user_tags
        self.source_volume = source_volume

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'SnapshotPrototypeSnapshotBySourceVolume':
        """Initialize a SnapshotPrototypeSnapshotBySourceVolume object from a json dictionary."""
        args = {}
        if 'clones' in _dict:
            args['clones'] = [SnapshotClonePrototype.from_dict(v) for v in _dict.get('clones')]
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        if 'resource_group' in _dict:
            args['resource_group'] = _dict.get('resource_group')
        if 'user_tags' in _dict:
            args['user_tags'] = _dict.get('user_tags')
        if 'source_volume' in _dict:
            args['source_volume'] = _dict.get('source_volume')
        else:
            raise ValueError('Required property \'source_volume\' not present in SnapshotPrototypeSnapshotBySourceVolume JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SnapshotPrototypeSnapshotBySourceVolume object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'clones') and self.clones is not None:
            clones_list = []
            for v in self.clones:
                if isinstance(v, dict):
                    clones_list.append(v)
                else:
                    clones_list.append(v.to_dict())
            _dict['clones'] = clones_list
        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, 'user_tags') and self.user_tags is not None:
            _dict['user_tags'] = self.user_tags
        if hasattr(self, 'source_volume') and self.source_volume is not None:
            if isinstance(self.source_volume, dict):
                _dict['source_volume'] = self.source_volume
            else:
                _dict['source_volume'] = self.source_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 SnapshotPrototypeSnapshotBySourceVolume object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'SnapshotPrototypeSnapshotBySourceVolume') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'SnapshotPrototypeSnapshotBySourceVolume') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class SubnetIdentityByCRN(SubnetIdentity):
    """
    SubnetIdentityByCRN.

    :attr str crn: The CRN for this subnet.
    """

    def __init__(
        self,
        crn: str,
    ) -> None:
        """
        Initialize a SubnetIdentityByCRN object.

        :param str crn: The CRN for this subnet.
        """
        # pylint: disable=super-init-not-called
        self.crn = crn

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'SubnetIdentityByCRN':
        """Initialize a SubnetIdentityByCRN object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError('Required property \'crn\' not present in SubnetIdentityByCRN JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SubnetIdentityByCRN object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this SubnetIdentityByCRN object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'SubnetIdentityByCRN') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'SubnetIdentityByCRN') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class SubnetIdentityByHref(SubnetIdentity):
    """
    SubnetIdentityByHref.

    :attr str href: The URL for this subnet.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a SubnetIdentityByHref object.

        :param str href: The URL for this subnet.
        """
        # pylint: disable=super-init-not-called
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'SubnetIdentityByHref':
        """Initialize a SubnetIdentityByHref object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in SubnetIdentityByHref JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SubnetIdentityByHref object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this SubnetIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'SubnetIdentityByHref') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'SubnetIdentityByHref') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class SubnetIdentityById(SubnetIdentity):
    """
    SubnetIdentityById.

    :attr str id: The unique identifier for this subnet.
    """

    def __init__(
        self,
        id: str,
    ) -> None:
        """
        Initialize a SubnetIdentityById object.

        :param str id: The unique identifier for this subnet.
        """
        # pylint: disable=super-init-not-called
        self.id = id

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'SubnetIdentityById':
        """Initialize a SubnetIdentityById object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in SubnetIdentityById JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SubnetIdentityById object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this SubnetIdentityById object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'SubnetIdentityById') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'SubnetIdentityById') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class SubnetPrototypeSubnetByCIDR(SubnetPrototype):
    """
    SubnetPrototypeSubnetByCIDR.

    :attr str ip_version: (optional) The IP version(s) to support for this subnet.
    :attr str name: (optional) The name for this subnet. The name must not be used
          by another subnet in the VPC. 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 use
          for internet-bound traffic for this subnet. If unspecified, the subnet will not
          be attached to a public gateway.
    :attr ResourceGroupIdentity resource_group: (optional)
    :attr RoutingTableIdentity routing_table: (optional) The routing table to use
          for this subnet. If unspecified, the default routing table for the VPC is used.
          The routing table properties `route_direct_link_ingress`,
          `route_internet_ingress`, `route_transit_gateway_ingress`, and
          `route_vpc_zone_ingress` must be `false`.
    :attr VPCIdentity vpc: The VPC the subnet will reside in.
    :attr str ipv4_cidr_block: The IPv4 range of the subnet, expressed in CIDR
          format. The prefix length of the subnet's CIDR must be between `/9` (8,388,608
          addresses) and `/29` (8 addresses). The IPv4 range of the subnet's CIDR must
          fall within an existing address prefix in the VPC and must not overlap with any
          existing subnet. The subnet will be created in the zone of the address prefix
          that contains the IPv4 CIDR. If zone is specified, it must match the zone of the
          address prefix that contains the subnet's IPv4 CIDR.
    :attr ZoneIdentity zone: (optional) The zone this subnet will reside in.
    """

    def __init__(
        self,
        vpc: 'VPCIdentity',
        ipv4_cidr_block: str,
        *,
        ip_version: str = None,
        name: str = None,
        network_acl: 'NetworkACLIdentity' = None,
        public_gateway: 'PublicGatewayIdentity' = None,
        resource_group: 'ResourceGroupIdentity' = None,
        routing_table: 'RoutingTableIdentity' = None,
        zone: 'ZoneIdentity' = None,
    ) -> None:
        """
        Initialize a SubnetPrototypeSubnetByCIDR object.

        :param VPCIdentity vpc: The VPC the subnet will reside in.
        :param str ipv4_cidr_block: The IPv4 range of the subnet, expressed in CIDR
               format. The prefix length of the subnet's CIDR must be between `/9`
               (8,388,608 addresses) and `/29` (8 addresses). The IPv4 range of the
               subnet's CIDR must fall within an existing address prefix in the VPC and
               must not overlap with any existing subnet. The subnet will be created in
               the zone of the address prefix that contains the IPv4 CIDR. If zone is
               specified, it must match the zone of the address prefix that contains the
               subnet's IPv4 CIDR.
        :param str ip_version: (optional) The IP version(s) to support for this
               subnet.
        :param str name: (optional) The name for this subnet. The name must not be
               used by another subnet in the VPC. 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 use for internet-bound traffic for this subnet. If unspecified, the
               subnet will not be attached to a public gateway.
        :param ResourceGroupIdentity resource_group: (optional)
        :param RoutingTableIdentity routing_table: (optional) The routing table to
               use for this subnet. If unspecified, the default routing table for the VPC
               is used. The routing table properties `route_direct_link_ingress`,
               `route_internet_ingress`, `route_transit_gateway_ingress`, and
               `route_vpc_zone_ingress` must be `false`.
        :param ZoneIdentity zone: (optional) The zone this subnet will reside in.
        """
        # pylint: disable=super-init-not-called
        self.ip_version = ip_version
        self.name = name
        self.network_acl = network_acl
        self.public_gateway = public_gateway
        self.resource_group = resource_group
        self.routing_table = routing_table
        self.vpc = vpc
        self.ipv4_cidr_block = ipv4_cidr_block
        self.zone = zone

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'SubnetPrototypeSubnetByCIDR':
        """Initialize a SubnetPrototypeSubnetByCIDR object from a json dictionary."""
        args = {}
        if 'ip_version' in _dict:
            args['ip_version'] = _dict.get('ip_version')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        if 'network_acl' in _dict:
            args['network_acl'] = _dict.get('network_acl')
        if 'public_gateway' in _dict:
            args['public_gateway'] = _dict.get('public_gateway')
        if 'resource_group' in _dict:
            args['resource_group'] = _dict.get('resource_group')
        if 'routing_table' in _dict:
            args['routing_table'] = _dict.get('routing_table')
        if 'vpc' in _dict:
            args['vpc'] = _dict.get('vpc')
        else:
            raise ValueError('Required property \'vpc\' not present in SubnetPrototypeSubnetByCIDR JSON')
        if 'ipv4_cidr_block' in _dict:
            args['ipv4_cidr_block'] = _dict.get('ipv4_cidr_block')
        else:
            raise ValueError('Required property \'ipv4_cidr_block\' not present in SubnetPrototypeSubnetByCIDR JSON')
        if 'zone' in _dict:
            args['zone'] = _dict.get('zone')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SubnetPrototypeSubnetByCIDR object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'ip_version') and self.ip_version is not None:
            _dict['ip_version'] = self.ip_version
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'network_acl') and self.network_acl is not None:
            if isinstance(self.network_acl, dict):
                _dict['network_acl'] = self.network_acl
            else:
                _dict['network_acl'] = self.network_acl.to_dict()
        if hasattr(self, 'public_gateway') and self.public_gateway is not None:
            if isinstance(self.public_gateway, dict):
                _dict['public_gateway'] = self.public_gateway
            else:
                _dict['public_gateway'] = self.public_gateway.to_dict()
        if hasattr(self, 'resource_group') and self.resource_group is not None:
            if isinstance(self.resource_group, dict):
                _dict['resource_group'] = self.resource_group
            else:
                _dict['resource_group'] = self.resource_group.to_dict()
        if hasattr(self, 'routing_table') and self.routing_table is not None:
            if isinstance(self.routing_table, dict):
                _dict['routing_table'] = self.routing_table
            else:
                _dict['routing_table'] = self.routing_table.to_dict()
        if hasattr(self, 'vpc') and self.vpc is not None:
            if isinstance(self.vpc, dict):
                _dict['vpc'] = self.vpc
            else:
                _dict['vpc'] = self.vpc.to_dict()
        if hasattr(self, 'ipv4_cidr_block') and self.ipv4_cidr_block is not None:
            _dict['ipv4_cidr_block'] = self.ipv4_cidr_block
        if hasattr(self, 'zone') and self.zone is not None:
            if isinstance(self.zone, dict):
                _dict['zone'] = self.zone
            else:
                _dict['zone'] = self.zone.to_dict()
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this SubnetPrototypeSubnetByCIDR object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'SubnetPrototypeSubnetByCIDR') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'SubnetPrototypeSubnetByCIDR') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class IpVersionEnum(str, Enum):
        """
        The IP version(s) to support for this subnet.
        """

        IPV4 = 'ipv4'



class SubnetPrototypeSubnetByTotalCount(SubnetPrototype):
    """
    SubnetPrototypeSubnetByTotalCount.

    :attr str ip_version: (optional) The IP version(s) to support for this subnet.
    :attr str name: (optional) The name for this subnet. The name must not be used
          by another subnet in the VPC. 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 use
          for internet-bound traffic for this subnet. If unspecified, the subnet will not
          be attached to a public gateway.
    :attr ResourceGroupIdentity resource_group: (optional)
    :attr RoutingTableIdentity routing_table: (optional) The routing table to use
          for this subnet. If unspecified, the default routing table for the VPC is used.
          The routing table properties `route_direct_link_ingress`,
          `route_internet_ingress`, `route_transit_gateway_ingress`, and
          `route_vpc_zone_ingress` must be `false`.
    :attr VPCIdentity vpc: The VPC the subnet will reside in.
    :attr int total_ipv4_address_count: The total number of IPv4 addresses required.
          Must be a power of 2. The VPC must have a default address prefix in the
          specified zone, and that prefix must have a free CIDR range with at least this
          number of addresses.
    :attr ZoneIdentity zone: The zone this subnet will reside in.
    """

    def __init__(
        self,
        vpc: 'VPCIdentity',
        total_ipv4_address_count: int,
        zone: 'ZoneIdentity',
        *,
        ip_version: str = None,
        name: str = None,
        network_acl: 'NetworkACLIdentity' = None,
        public_gateway: 'PublicGatewayIdentity' = None,
        resource_group: 'ResourceGroupIdentity' = None,
        routing_table: 'RoutingTableIdentity' = None,
    ) -> None:
        """
        Initialize a SubnetPrototypeSubnetByTotalCount object.

        :param VPCIdentity vpc: The VPC the subnet will reside in.
        :param int total_ipv4_address_count: The total number of IPv4 addresses
               required. Must be a power of 2. The VPC must have a default address prefix
               in the specified zone, and that prefix must have a free CIDR range with at
               least this number of addresses.
        :param ZoneIdentity zone: The zone this subnet will reside in.
        :param str ip_version: (optional) The IP version(s) to support for this
               subnet.
        :param str name: (optional) The name for this subnet. The name must not be
               used by another subnet in the VPC. 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 use for internet-bound traffic for this subnet. If unspecified, the
               subnet will not be attached to a public gateway.
        :param ResourceGroupIdentity resource_group: (optional)
        :param RoutingTableIdentity routing_table: (optional) The routing table to
               use for this subnet. If unspecified, the default routing table for the VPC
               is used. The routing table properties `route_direct_link_ingress`,
               `route_internet_ingress`, `route_transit_gateway_ingress`, and
               `route_vpc_zone_ingress` must be `false`.
        """
        # pylint: disable=super-init-not-called
        self.ip_version = ip_version
        self.name = name
        self.network_acl = network_acl
        self.public_gateway = public_gateway
        self.resource_group = resource_group
        self.routing_table = routing_table
        self.vpc = vpc
        self.total_ipv4_address_count = total_ipv4_address_count
        self.zone = zone

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'SubnetPrototypeSubnetByTotalCount':
        """Initialize a SubnetPrototypeSubnetByTotalCount object from a json dictionary."""
        args = {}
        if 'ip_version' in _dict:
            args['ip_version'] = _dict.get('ip_version')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        if 'network_acl' in _dict:
            args['network_acl'] = _dict.get('network_acl')
        if 'public_gateway' in _dict:
            args['public_gateway'] = _dict.get('public_gateway')
        if 'resource_group' in _dict:
            args['resource_group'] = _dict.get('resource_group')
        if 'routing_table' in _dict:
            args['routing_table'] = _dict.get('routing_table')
        if 'vpc' in _dict:
            args['vpc'] = _dict.get('vpc')
        else:
            raise ValueError('Required property \'vpc\' not present in SubnetPrototypeSubnetByTotalCount JSON')
        if 'total_ipv4_address_count' in _dict:
            args['total_ipv4_address_count'] = _dict.get('total_ipv4_address_count')
        else:
            raise ValueError('Required property \'total_ipv4_address_count\' not present in SubnetPrototypeSubnetByTotalCount JSON')
        if 'zone' in _dict:
            args['zone'] = _dict.get('zone')
        else:
            raise ValueError('Required property \'zone\' not present in SubnetPrototypeSubnetByTotalCount JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SubnetPrototypeSubnetByTotalCount object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'ip_version') and self.ip_version is not None:
            _dict['ip_version'] = self.ip_version
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'network_acl') and self.network_acl is not None:
            if isinstance(self.network_acl, dict):
                _dict['network_acl'] = self.network_acl
            else:
                _dict['network_acl'] = self.network_acl.to_dict()
        if hasattr(self, 'public_gateway') and self.public_gateway is not None:
            if isinstance(self.public_gateway, dict):
                _dict['public_gateway'] = self.public_gateway
            else:
                _dict['public_gateway'] = self.public_gateway.to_dict()
        if hasattr(self, 'resource_group') and self.resource_group is not None:
            if isinstance(self.resource_group, dict):
                _dict['resource_group'] = self.resource_group
            else:
                _dict['resource_group'] = self.resource_group.to_dict()
        if hasattr(self, 'routing_table') and self.routing_table is not None:
            if isinstance(self.routing_table, dict):
                _dict['routing_table'] = self.routing_table
            else:
                _dict['routing_table'] = self.routing_table.to_dict()
        if hasattr(self, 'vpc') and self.vpc is not None:
            if isinstance(self.vpc, dict):
                _dict['vpc'] = self.vpc
            else:
                _dict['vpc'] = self.vpc.to_dict()
        if hasattr(self, 'total_ipv4_address_count') and self.total_ipv4_address_count is not None:
            _dict['total_ipv4_address_count'] = self.total_ipv4_address_count
        if hasattr(self, 'zone') and self.zone is not None:
            if isinstance(self.zone, dict):
                _dict['zone'] = self.zone
            else:
                _dict['zone'] = self.zone.to_dict()
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this SubnetPrototypeSubnetByTotalCount object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'SubnetPrototypeSubnetByTotalCount') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'SubnetPrototypeSubnetByTotalCount') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class IpVersionEnum(str, Enum):
        """
        The IP version(s) to support for this subnet.
        """

        IPV4 = 'ipv4'



class SubnetPublicGatewayPatchPublicGatewayIdentityByCRN(SubnetPublicGatewayPatch):
    """
    SubnetPublicGatewayPatchPublicGatewayIdentityByCRN.

    :attr str crn: The CRN for this public gateway.
    """

    def __init__(
        self,
        crn: str,
    ) -> None:
        """
        Initialize a SubnetPublicGatewayPatchPublicGatewayIdentityByCRN 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) -> 'SubnetPublicGatewayPatchPublicGatewayIdentityByCRN':
        """Initialize a SubnetPublicGatewayPatchPublicGatewayIdentityByCRN object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError('Required property \'crn\' not present in SubnetPublicGatewayPatchPublicGatewayIdentityByCRN JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SubnetPublicGatewayPatchPublicGatewayIdentityByCRN object from 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 SubnetPublicGatewayPatchPublicGatewayIdentityByCRN object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'SubnetPublicGatewayPatchPublicGatewayIdentityByCRN') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'SubnetPublicGatewayPatchPublicGatewayIdentityByCRN') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class SubnetPublicGatewayPatchPublicGatewayIdentityByHref(SubnetPublicGatewayPatch):
    """
    SubnetPublicGatewayPatchPublicGatewayIdentityByHref.

    :attr str href: The URL for this public gateway.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a SubnetPublicGatewayPatchPublicGatewayIdentityByHref 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) -> 'SubnetPublicGatewayPatchPublicGatewayIdentityByHref':
        """Initialize a SubnetPublicGatewayPatchPublicGatewayIdentityByHref object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in SubnetPublicGatewayPatchPublicGatewayIdentityByHref JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SubnetPublicGatewayPatchPublicGatewayIdentityByHref object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(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 SubnetPublicGatewayPatchPublicGatewayIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'SubnetPublicGatewayPatchPublicGatewayIdentityByHref') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'SubnetPublicGatewayPatchPublicGatewayIdentityByHref') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class SubnetPublicGatewayPatchPublicGatewayIdentityById(SubnetPublicGatewayPatch):
    """
    SubnetPublicGatewayPatchPublicGatewayIdentityById.

    :attr str id: The unique identifier for this public gateway.
    """

    def __init__(
        self,
        id: str,
    ) -> None:
        """
        Initialize a SubnetPublicGatewayPatchPublicGatewayIdentityById 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) -> 'SubnetPublicGatewayPatchPublicGatewayIdentityById':
        """Initialize a SubnetPublicGatewayPatchPublicGatewayIdentityById object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in SubnetPublicGatewayPatchPublicGatewayIdentityById JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SubnetPublicGatewayPatchPublicGatewayIdentityById object from 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 SubnetPublicGatewayPatchPublicGatewayIdentityById object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'SubnetPublicGatewayPatchPublicGatewayIdentityById') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'SubnetPublicGatewayPatchPublicGatewayIdentityById') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class TrustedProfileIdentityTrustedProfileByCRN(TrustedProfileIdentity):
    """
    TrustedProfileIdentityTrustedProfileByCRN.

    :attr str crn: The CRN for this trusted profile.
    """

    def __init__(
        self,
        crn: str,
    ) -> None:
        """
        Initialize a TrustedProfileIdentityTrustedProfileByCRN object.

        :param str crn: The CRN for this trusted profile.
        """
        # pylint: disable=super-init-not-called
        self.crn = crn

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'TrustedProfileIdentityTrustedProfileByCRN':
        """Initialize a TrustedProfileIdentityTrustedProfileByCRN object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError('Required property \'crn\' not present in TrustedProfileIdentityTrustedProfileByCRN JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a TrustedProfileIdentityTrustedProfileByCRN object from 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 TrustedProfileIdentityTrustedProfileByCRN object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'TrustedProfileIdentityTrustedProfileByCRN') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'TrustedProfileIdentityTrustedProfileByCRN') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class TrustedProfileIdentityTrustedProfileById(TrustedProfileIdentity):
    """
    TrustedProfileIdentityTrustedProfileById.

    :attr str id: The unique identifier for this trusted profile.
    """

    def __init__(
        self,
        id: str,
    ) -> None:
        """
        Initialize a TrustedProfileIdentityTrustedProfileById object.

        :param str id: The unique identifier for this trusted profile.
        """
        # pylint: disable=super-init-not-called
        self.id = id

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'TrustedProfileIdentityTrustedProfileById':
        """Initialize a TrustedProfileIdentityTrustedProfileById object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in TrustedProfileIdentityTrustedProfileById JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a TrustedProfileIdentityTrustedProfileById object from 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 TrustedProfileIdentityTrustedProfileById object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'TrustedProfileIdentityTrustedProfileById') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'TrustedProfileIdentityTrustedProfileById') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VPCDNSResolverPrototypeVPCDNSResolverTypeManualPrototype(VPCDNSResolverPrototype):
    """
    Manually specify the DNS server addresses for this VPC.

    :attr List[DNSServerPrototype] manual_servers: The DNS servers to use for this
          VPC. All the DNS servers must either:
          - have a unique `zone_affinity`, or
          - not have a `zone_affinity`.
    :attr str type: The type of the DNS resolver to use.
    """

    def __init__(
        self,
        manual_servers: List['DNSServerPrototype'],
        type: str,
    ) -> None:
        """
        Initialize a VPCDNSResolverPrototypeVPCDNSResolverTypeManualPrototype object.

        :param List[DNSServerPrototype] manual_servers: The DNS servers to use for
               this VPC. All the DNS servers must either:
               - have a unique `zone_affinity`, or
               - not have a `zone_affinity`.
        :param str type: The type of the DNS resolver to use.
        """
        # pylint: disable=super-init-not-called
        self.manual_servers = manual_servers
        self.type = type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPCDNSResolverPrototypeVPCDNSResolverTypeManualPrototype':
        """Initialize a VPCDNSResolverPrototypeVPCDNSResolverTypeManualPrototype object from a json dictionary."""
        args = {}
        if 'manual_servers' in _dict:
            args['manual_servers'] = [DNSServerPrototype.from_dict(v) for v in _dict.get('manual_servers')]
        else:
            raise ValueError('Required property \'manual_servers\' not present in VPCDNSResolverPrototypeVPCDNSResolverTypeManualPrototype JSON')
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in VPCDNSResolverPrototypeVPCDNSResolverTypeManualPrototype JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPCDNSResolverPrototypeVPCDNSResolverTypeManualPrototype object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'manual_servers') and self.manual_servers is not None:
            manual_servers_list = []
            for v in self.manual_servers:
                if isinstance(v, dict):
                    manual_servers_list.append(v)
                else:
                    manual_servers_list.append(v.to_dict())
            _dict['manual_servers'] = manual_servers_list
        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 VPCDNSResolverPrototypeVPCDNSResolverTypeManualPrototype object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPCDNSResolverPrototypeVPCDNSResolverTypeManualPrototype') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPCDNSResolverPrototypeVPCDNSResolverTypeManualPrototype') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class TypeEnum(str, Enum):
        """
        The type of the DNS resolver to use.
        """

        MANUAL = 'manual'



class VPCDNSResolverPrototypeVPCDNSResolverTypeSystemPrototype(VPCDNSResolverPrototype):
    """
    The system will provide DNS server addresses for this VPC. The system-provided DNS
    server addresses depend on whether any endpoint gateways reside in the VPC, and
    whether a
    [DNS Services](https://cloud.ibm.com/docs/dns-svcs) instance is configured for the
    VPC.

    :attr str type: (optional) The type of the DNS resolver to use.
    """

    def __init__(
        self,
        *,
        type: str = None,
    ) -> None:
        """
        Initialize a VPCDNSResolverPrototypeVPCDNSResolverTypeSystemPrototype object.

        :param str type: (optional) The type of the DNS resolver to use.
        """
        # pylint: disable=super-init-not-called
        self.type = type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPCDNSResolverPrototypeVPCDNSResolverTypeSystemPrototype':
        """Initialize a VPCDNSResolverPrototypeVPCDNSResolverTypeSystemPrototype object from a json dictionary."""
        args = {}
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPCDNSResolverPrototypeVPCDNSResolverTypeSystemPrototype object from 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 VPCDNSResolverPrototypeVPCDNSResolverTypeSystemPrototype object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPCDNSResolverPrototypeVPCDNSResolverTypeSystemPrototype') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPCDNSResolverPrototypeVPCDNSResolverTypeSystemPrototype') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class TypeEnum(str, Enum):
        """
        The type of the DNS resolver to use.
        """

        SYSTEM = 'system'



class VPCDNSResolverTypeDelegated(VPCDNSResolver):
    """
    The DNS server addresses are delegated to the DNS resolver of another VPC.

    :attr List[DNSServer] servers: The DNS servers for this VPC. The servers are
          populated:
          - by the system when `dns.resolver.type` is `system`
          - using the DNS servers in `dns.resolver.vpc` when `dns.resolver.type` is
          `delegated`
          - using `dns.resolver.manual_servers` when the `dns.resolver.type` is `manual`.
    :attr str type: The type of the DNS resolver used for the VPC.
    :attr VPCReferenceDNSResolverContext vpc: The VPC whose DNS resolver provides
          the DNS server addresses for this VPC.
          The VPC may be remote and therefore may not be directly retrievable.
    """

    def __init__(
        self,
        servers: List['DNSServer'],
        type: str,
        vpc: 'VPCReferenceDNSResolverContext',
    ) -> None:
        """
        Initialize a VPCDNSResolverTypeDelegated object.

        :param List[DNSServer] servers: The DNS servers for this VPC. The servers
               are populated:
               - by the system when `dns.resolver.type` is `system`
               - using the DNS servers in `dns.resolver.vpc` when `dns.resolver.type` is
               `delegated`
               - using `dns.resolver.manual_servers` when the `dns.resolver.type` is
               `manual`.
        :param str type: The type of the DNS resolver used for the VPC.
        :param VPCReferenceDNSResolverContext vpc: The VPC whose DNS resolver
               provides the DNS server addresses for this VPC.
               The VPC may be remote and therefore may not be directly retrievable.
        """
        # pylint: disable=super-init-not-called
        self.servers = servers
        self.type = type
        self.vpc = vpc

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPCDNSResolverTypeDelegated':
        """Initialize a VPCDNSResolverTypeDelegated object from a json dictionary."""
        args = {}
        if 'servers' in _dict:
            args['servers'] = [DNSServer.from_dict(v) for v in _dict.get('servers')]
        else:
            raise ValueError('Required property \'servers\' not present in VPCDNSResolverTypeDelegated JSON')
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in VPCDNSResolverTypeDelegated JSON')
        if 'vpc' in _dict:
            args['vpc'] = VPCReferenceDNSResolverContext.from_dict(_dict.get('vpc'))
        else:
            raise ValueError('Required property \'vpc\' not present in VPCDNSResolverTypeDelegated JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPCDNSResolverTypeDelegated object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'servers') and self.servers is not None:
            servers_list = []
            for v in self.servers:
                if isinstance(v, dict):
                    servers_list.append(v)
                else:
                    servers_list.append(v.to_dict())
            _dict['servers'] = servers_list
        if hasattr(self, 'type') and self.type is not None:
            _dict['type'] = self.type
        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()
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VPCDNSResolverTypeDelegated object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPCDNSResolverTypeDelegated') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPCDNSResolverTypeDelegated') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class TypeEnum(str, Enum):
        """
        The type of the DNS resolver used for the VPC.
        """

        DELEGATED = 'delegated'



class VPCDNSResolverTypeManual(VPCDNSResolver):
    """
    The DNS server addresses are manually specified.

    :attr List[DNSServer] servers: The DNS servers for this VPC. The servers are
          populated:
          - by the system when `dns.resolver.type` is `system`
          - using the DNS servers in `dns.resolver.vpc` when `dns.resolver.type` is
          `delegated`
          - using `dns.resolver.manual_servers` when the `dns.resolver.type` is `manual`.
    :attr List[DNSServer] manual_servers: The manually specified DNS servers for
          this VPC.
    :attr str type: The type of the DNS resolver used for the VPC.
    """

    def __init__(
        self,
        servers: List['DNSServer'],
        manual_servers: List['DNSServer'],
        type: str,
    ) -> None:
        """
        Initialize a VPCDNSResolverTypeManual object.

        :param List[DNSServer] servers: The DNS servers for this VPC. The servers
               are populated:
               - by the system when `dns.resolver.type` is `system`
               - using the DNS servers in `dns.resolver.vpc` when `dns.resolver.type` is
               `delegated`
               - using `dns.resolver.manual_servers` when the `dns.resolver.type` is
               `manual`.
        :param List[DNSServer] manual_servers: The manually specified DNS servers
               for this VPC.
        :param str type: The type of the DNS resolver used for the VPC.
        """
        # pylint: disable=super-init-not-called
        self.servers = servers
        self.manual_servers = manual_servers
        self.type = type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPCDNSResolverTypeManual':
        """Initialize a VPCDNSResolverTypeManual object from a json dictionary."""
        args = {}
        if 'servers' in _dict:
            args['servers'] = [DNSServer.from_dict(v) for v in _dict.get('servers')]
        else:
            raise ValueError('Required property \'servers\' not present in VPCDNSResolverTypeManual JSON')
        if 'manual_servers' in _dict:
            args['manual_servers'] = [DNSServer.from_dict(v) for v in _dict.get('manual_servers')]
        else:
            raise ValueError('Required property \'manual_servers\' not present in VPCDNSResolverTypeManual JSON')
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in VPCDNSResolverTypeManual JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPCDNSResolverTypeManual object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'servers') and self.servers is not None:
            servers_list = []
            for v in self.servers:
                if isinstance(v, dict):
                    servers_list.append(v)
                else:
                    servers_list.append(v.to_dict())
            _dict['servers'] = servers_list
        if hasattr(self, 'manual_servers') and self.manual_servers is not None:
            manual_servers_list = []
            for v in self.manual_servers:
                if isinstance(v, dict):
                    manual_servers_list.append(v)
                else:
                    manual_servers_list.append(v.to_dict())
            _dict['manual_servers'] = manual_servers_list
        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 VPCDNSResolverTypeManual object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPCDNSResolverTypeManual') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPCDNSResolverTypeManual') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class TypeEnum(str, Enum):
        """
        The type of the DNS resolver used for the VPC.
        """

        MANUAL = 'manual'



class VPCDNSResolverTypeSystem(VPCDNSResolver):
    """
    The DNS server addresses are provided by the system and depend on the configuration.

    :attr List[DNSServer] servers: The DNS servers for this VPC. The servers are
          populated:
          - by the system when `dns.resolver.type` is `system`
          - using the DNS servers in `dns.resolver.vpc` when `dns.resolver.type` is
          `delegated`
          - using `dns.resolver.manual_servers` when the `dns.resolver.type` is `manual`.
    :attr str configuration: The configuration of the system DNS resolver for this
          VPC.
          - `custom_resolver`: A custom DNS resolver is configured for this VPC.
          - `private_resolver`: A private DNS resolver is configured for this VPC.
          Applicable when
            the VPC has either or both of the following:
              - at least one endpoint gateway residing in it
              - a [DNS Services](https://cloud.ibm.com/docs/dns-svcs) private zone
          configured for it
          - `default`: The provider default DNS resolvers are configured for this VPC.
            This system DNS resolver configuration is used when the VPC has:
            - no custom DNS resolver configured for it, and
            - no endpoint gateways residing in it, and
            - no [DNS Services](https://cloud.ibm.com/docs/dns-svcs) private zone
          configured for it.
    :attr str type: The type of the DNS resolver used for the VPC.
    """

    def __init__(
        self,
        servers: List['DNSServer'],
        configuration: str,
        type: str,
    ) -> None:
        """
        Initialize a VPCDNSResolverTypeSystem object.

        :param List[DNSServer] servers: The DNS servers for this VPC. The servers
               are populated:
               - by the system when `dns.resolver.type` is `system`
               - using the DNS servers in `dns.resolver.vpc` when `dns.resolver.type` is
               `delegated`
               - using `dns.resolver.manual_servers` when the `dns.resolver.type` is
               `manual`.
        :param str configuration: The configuration of the system DNS resolver for
               this VPC.
               - `custom_resolver`: A custom DNS resolver is configured for this VPC.
               - `private_resolver`: A private DNS resolver is configured for this VPC.
               Applicable when
                 the VPC has either or both of the following:
                   - at least one endpoint gateway residing in it
                   - a [DNS Services](https://cloud.ibm.com/docs/dns-svcs) private zone
               configured for it
               - `default`: The provider default DNS resolvers are configured for this
               VPC.
                 This system DNS resolver configuration is used when the VPC has:
                 - no custom DNS resolver configured for it, and
                 - no endpoint gateways residing in it, and
                 - no [DNS Services](https://cloud.ibm.com/docs/dns-svcs) private zone
               configured for it.
        :param str type: The type of the DNS resolver used for the VPC.
        """
        # pylint: disable=super-init-not-called
        self.servers = servers
        self.configuration = configuration
        self.type = type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPCDNSResolverTypeSystem':
        """Initialize a VPCDNSResolverTypeSystem object from a json dictionary."""
        args = {}
        if 'servers' in _dict:
            args['servers'] = [DNSServer.from_dict(v) for v in _dict.get('servers')]
        else:
            raise ValueError('Required property \'servers\' not present in VPCDNSResolverTypeSystem JSON')
        if 'configuration' in _dict:
            args['configuration'] = _dict.get('configuration')
        else:
            raise ValueError('Required property \'configuration\' not present in VPCDNSResolverTypeSystem JSON')
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in VPCDNSResolverTypeSystem JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPCDNSResolverTypeSystem object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'servers') and self.servers is not None:
            servers_list = []
            for v in self.servers:
                if isinstance(v, dict):
                    servers_list.append(v)
                else:
                    servers_list.append(v.to_dict())
            _dict['servers'] = servers_list
        if hasattr(self, 'configuration') and self.configuration is not None:
            _dict['configuration'] = self.configuration
        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 VPCDNSResolverTypeSystem object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPCDNSResolverTypeSystem') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPCDNSResolverTypeSystem') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ConfigurationEnum(str, Enum):
        """
        The configuration of the system DNS resolver for this VPC.
        - `custom_resolver`: A custom DNS resolver is configured for this VPC.
        - `private_resolver`: A private DNS resolver is configured for this VPC.
        Applicable when
          the VPC has either or both of the following:
            - at least one endpoint gateway residing in it
            - a [DNS Services](https://cloud.ibm.com/docs/dns-svcs) private zone
        configured for it
        - `default`: The provider default DNS resolvers are configured for this VPC.
          This system DNS resolver configuration is used when the VPC has:
          - no custom DNS resolver configured for it, and
          - no endpoint gateways residing in it, and
          - no [DNS Services](https://cloud.ibm.com/docs/dns-svcs) private zone configured
        for it.
        """

        CUSTOM_RESOLVER = 'custom_resolver'
        DEFAULT = 'default'
        PRIVATE_RESOLVER = 'private_resolver'


    class TypeEnum(str, Enum):
        """
        The type of the DNS resolver used for the VPC.
        """

        SYSTEM = 'system'



class VPCDNSResolverVPCPatchVPCIdentityByCRN(VPCDNSResolverVPCPatch):
    """
    VPCDNSResolverVPCPatchVPCIdentityByCRN.

    :attr str crn: The CRN for this VPC.
    """

    def __init__(
        self,
        crn: str,
    ) -> None:
        """
        Initialize a VPCDNSResolverVPCPatchVPCIdentityByCRN 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) -> 'VPCDNSResolverVPCPatchVPCIdentityByCRN':
        """Initialize a VPCDNSResolverVPCPatchVPCIdentityByCRN object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError('Required property \'crn\' not present in VPCDNSResolverVPCPatchVPCIdentityByCRN JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPCDNSResolverVPCPatchVPCIdentityByCRN object from 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 VPCDNSResolverVPCPatchVPCIdentityByCRN object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPCDNSResolverVPCPatchVPCIdentityByCRN') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPCDNSResolverVPCPatchVPCIdentityByCRN') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VPCDNSResolverVPCPatchVPCIdentityByHref(VPCDNSResolverVPCPatch):
    """
    VPCDNSResolverVPCPatchVPCIdentityByHref.

    :attr str href: The URL for this VPC.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a VPCDNSResolverVPCPatchVPCIdentityByHref 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) -> 'VPCDNSResolverVPCPatchVPCIdentityByHref':
        """Initialize a VPCDNSResolverVPCPatchVPCIdentityByHref object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in VPCDNSResolverVPCPatchVPCIdentityByHref JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPCDNSResolverVPCPatchVPCIdentityByHref object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(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 VPCDNSResolverVPCPatchVPCIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPCDNSResolverVPCPatchVPCIdentityByHref') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPCDNSResolverVPCPatchVPCIdentityByHref') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VPCDNSResolverVPCPatchVPCIdentityById(VPCDNSResolverVPCPatch):
    """
    VPCDNSResolverVPCPatchVPCIdentityById.

    :attr str id: The unique identifier for this VPC.
    """

    def __init__(
        self,
        id: str,
    ) -> None:
        """
        Initialize a VPCDNSResolverVPCPatchVPCIdentityById 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) -> 'VPCDNSResolverVPCPatchVPCIdentityById':
        """Initialize a VPCDNSResolverVPCPatchVPCIdentityById object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in VPCDNSResolverVPCPatchVPCIdentityById JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPCDNSResolverVPCPatchVPCIdentityById object from 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 VPCDNSResolverVPCPatchVPCIdentityById object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPCDNSResolverVPCPatchVPCIdentityById') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPCDNSResolverVPCPatchVPCIdentityById') -> 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 VPNGatewayConnectionIKEPolicyPatchIKEPolicyIdentityByHref(VPNGatewayConnectionIKEPolicyPatch):
    """
    VPNGatewayConnectionIKEPolicyPatchIKEPolicyIdentityByHref.

    :attr str href: The IKE policy's canonical URL.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a VPNGatewayConnectionIKEPolicyPatchIKEPolicyIdentityByHref 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) -> 'VPNGatewayConnectionIKEPolicyPatchIKEPolicyIdentityByHref':
        """Initialize a VPNGatewayConnectionIKEPolicyPatchIKEPolicyIdentityByHref object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in VPNGatewayConnectionIKEPolicyPatchIKEPolicyIdentityByHref JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPNGatewayConnectionIKEPolicyPatchIKEPolicyIdentityByHref object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(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 VPNGatewayConnectionIKEPolicyPatchIKEPolicyIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPNGatewayConnectionIKEPolicyPatchIKEPolicyIdentityByHref') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPNGatewayConnectionIKEPolicyPatchIKEPolicyIdentityByHref') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VPNGatewayConnectionIKEPolicyPatchIKEPolicyIdentityById(VPNGatewayConnectionIKEPolicyPatch):
    """
    VPNGatewayConnectionIKEPolicyPatchIKEPolicyIdentityById.

    :attr str id: The unique identifier for this IKE policy.
    """

    def __init__(
        self,
        id: str,
    ) -> None:
        """
        Initialize a VPNGatewayConnectionIKEPolicyPatchIKEPolicyIdentityById 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) -> 'VPNGatewayConnectionIKEPolicyPatchIKEPolicyIdentityById':
        """Initialize a VPNGatewayConnectionIKEPolicyPatchIKEPolicyIdentityById object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in VPNGatewayConnectionIKEPolicyPatchIKEPolicyIdentityById JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPNGatewayConnectionIKEPolicyPatchIKEPolicyIdentityById object from 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 VPNGatewayConnectionIKEPolicyPatchIKEPolicyIdentityById object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPNGatewayConnectionIKEPolicyPatchIKEPolicyIdentityById') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPNGatewayConnectionIKEPolicyPatchIKEPolicyIdentityById') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VPNGatewayConnectionIKEPolicyPrototypeIKEPolicyIdentityByHref(VPNGatewayConnectionIKEPolicyPrototype):
    """
    VPNGatewayConnectionIKEPolicyPrototypeIKEPolicyIdentityByHref.

    :attr str href: The IKE policy's canonical URL.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a VPNGatewayConnectionIKEPolicyPrototypeIKEPolicyIdentityByHref 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) -> 'VPNGatewayConnectionIKEPolicyPrototypeIKEPolicyIdentityByHref':
        """Initialize a VPNGatewayConnectionIKEPolicyPrototypeIKEPolicyIdentityByHref object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in VPNGatewayConnectionIKEPolicyPrototypeIKEPolicyIdentityByHref JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPNGatewayConnectionIKEPolicyPrototypeIKEPolicyIdentityByHref object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(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 VPNGatewayConnectionIKEPolicyPrototypeIKEPolicyIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPNGatewayConnectionIKEPolicyPrototypeIKEPolicyIdentityByHref') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPNGatewayConnectionIKEPolicyPrototypeIKEPolicyIdentityByHref') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VPNGatewayConnectionIKEPolicyPrototypeIKEPolicyIdentityById(VPNGatewayConnectionIKEPolicyPrototype):
    """
    VPNGatewayConnectionIKEPolicyPrototypeIKEPolicyIdentityById.

    :attr str id: The unique identifier for this IKE policy.
    """

    def __init__(
        self,
        id: str,
    ) -> None:
        """
        Initialize a VPNGatewayConnectionIKEPolicyPrototypeIKEPolicyIdentityById 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) -> 'VPNGatewayConnectionIKEPolicyPrototypeIKEPolicyIdentityById':
        """Initialize a VPNGatewayConnectionIKEPolicyPrototypeIKEPolicyIdentityById object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in VPNGatewayConnectionIKEPolicyPrototypeIKEPolicyIdentityById JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPNGatewayConnectionIKEPolicyPrototypeIKEPolicyIdentityById object from 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 VPNGatewayConnectionIKEPolicyPrototypeIKEPolicyIdentityById object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPNGatewayConnectionIKEPolicyPrototypeIKEPolicyIdentityById') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPNGatewayConnectionIKEPolicyPrototypeIKEPolicyIdentityById') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VPNGatewayConnectionIPsecPolicyPatchIPsecPolicyIdentityByHref(VPNGatewayConnectionIPsecPolicyPatch):
    """
    VPNGatewayConnectionIPsecPolicyPatchIPsecPolicyIdentityByHref.

    :attr str href: The IPsec policy's canonical URL.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a VPNGatewayConnectionIPsecPolicyPatchIPsecPolicyIdentityByHref 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) -> 'VPNGatewayConnectionIPsecPolicyPatchIPsecPolicyIdentityByHref':
        """Initialize a VPNGatewayConnectionIPsecPolicyPatchIPsecPolicyIdentityByHref object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in VPNGatewayConnectionIPsecPolicyPatchIPsecPolicyIdentityByHref JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPNGatewayConnectionIPsecPolicyPatchIPsecPolicyIdentityByHref object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(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 VPNGatewayConnectionIPsecPolicyPatchIPsecPolicyIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPNGatewayConnectionIPsecPolicyPatchIPsecPolicyIdentityByHref') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPNGatewayConnectionIPsecPolicyPatchIPsecPolicyIdentityByHref') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VPNGatewayConnectionIPsecPolicyPatchIPsecPolicyIdentityById(VPNGatewayConnectionIPsecPolicyPatch):
    """
    VPNGatewayConnectionIPsecPolicyPatchIPsecPolicyIdentityById.

    :attr str id: The unique identifier for this IPsec policy.
    """

    def __init__(
        self,
        id: str,
    ) -> None:
        """
        Initialize a VPNGatewayConnectionIPsecPolicyPatchIPsecPolicyIdentityById 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) -> 'VPNGatewayConnectionIPsecPolicyPatchIPsecPolicyIdentityById':
        """Initialize a VPNGatewayConnectionIPsecPolicyPatchIPsecPolicyIdentityById object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in VPNGatewayConnectionIPsecPolicyPatchIPsecPolicyIdentityById JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPNGatewayConnectionIPsecPolicyPatchIPsecPolicyIdentityById object from 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 VPNGatewayConnectionIPsecPolicyPatchIPsecPolicyIdentityById object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPNGatewayConnectionIPsecPolicyPatchIPsecPolicyIdentityById') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPNGatewayConnectionIPsecPolicyPatchIPsecPolicyIdentityById') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VPNGatewayConnectionIPsecPolicyPrototypeIPsecPolicyIdentityByHref(VPNGatewayConnectionIPsecPolicyPrototype):
    """
    VPNGatewayConnectionIPsecPolicyPrototypeIPsecPolicyIdentityByHref.

    :attr str href: The IPsec policy's canonical URL.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a VPNGatewayConnectionIPsecPolicyPrototypeIPsecPolicyIdentityByHref 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) -> 'VPNGatewayConnectionIPsecPolicyPrototypeIPsecPolicyIdentityByHref':
        """Initialize a VPNGatewayConnectionIPsecPolicyPrototypeIPsecPolicyIdentityByHref object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in VPNGatewayConnectionIPsecPolicyPrototypeIPsecPolicyIdentityByHref JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPNGatewayConnectionIPsecPolicyPrototypeIPsecPolicyIdentityByHref object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(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 VPNGatewayConnectionIPsecPolicyPrototypeIPsecPolicyIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPNGatewayConnectionIPsecPolicyPrototypeIPsecPolicyIdentityByHref') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPNGatewayConnectionIPsecPolicyPrototypeIPsecPolicyIdentityByHref') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VPNGatewayConnectionIPsecPolicyPrototypeIPsecPolicyIdentityById(VPNGatewayConnectionIPsecPolicyPrototype):
    """
    VPNGatewayConnectionIPsecPolicyPrototypeIPsecPolicyIdentityById.

    :attr str id: The unique identifier for this IPsec policy.
    """

    def __init__(
        self,
        id: str,
    ) -> None:
        """
        Initialize a VPNGatewayConnectionIPsecPolicyPrototypeIPsecPolicyIdentityById 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) -> 'VPNGatewayConnectionIPsecPolicyPrototypeIPsecPolicyIdentityById':
        """Initialize a VPNGatewayConnectionIPsecPolicyPrototypeIPsecPolicyIdentityById object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in VPNGatewayConnectionIPsecPolicyPrototypeIPsecPolicyIdentityById JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPNGatewayConnectionIPsecPolicyPrototypeIPsecPolicyIdentityById object from 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 VPNGatewayConnectionIPsecPolicyPrototypeIPsecPolicyIdentityById object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPNGatewayConnectionIPsecPolicyPrototypeIPsecPolicyIdentityById') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPNGatewayConnectionIPsecPolicyPrototypeIPsecPolicyIdentityById') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VPNGatewayConnectionPatchVPNGatewayConnectionStaticRouteModePatch(VPNGatewayConnectionPatch):
    """
    VPNGatewayConnectionPatchVPNGatewayConnectionStaticRouteModePatch.

    :attr bool admin_state_up: (optional) If set to false, the VPN gateway
          connection is shut down.
    :attr VPNGatewayConnectionDPDPatch dead_peer_detection: (optional)
    :attr VPNGatewayConnectionIKEPolicyPatch ike_policy: (optional)
    :attr VPNGatewayConnectionIPsecPolicyPatch ipsec_policy: (optional)
    :attr str name: (optional) The name for this VPN gateway connection. The name
          must not be used by another connection for the VPN gateway.
    :attr str peer_address: (optional) The IP address of the peer VPN gateway.
    :attr str psk: (optional) The pre-shared key.
    :attr str routing_protocol: (optional) Routing protocols are disabled for this
          VPN gateway connection.
    """

    def __init__(
        self,
        *,
        admin_state_up: bool = None,
        dead_peer_detection: 'VPNGatewayConnectionDPDPatch' = None,
        ike_policy: 'VPNGatewayConnectionIKEPolicyPatch' = None,
        ipsec_policy: 'VPNGatewayConnectionIPsecPolicyPatch' = None,
        name: str = None,
        peer_address: str = None,
        psk: str = None,
        routing_protocol: str = None,
    ) -> None:
        """
        Initialize a VPNGatewayConnectionPatchVPNGatewayConnectionStaticRouteModePatch object.

        :param bool admin_state_up: (optional) If set to false, the VPN gateway
               connection is shut down.
        :param VPNGatewayConnectionDPDPatch dead_peer_detection: (optional)
        :param VPNGatewayConnectionIKEPolicyPatch ike_policy: (optional)
        :param VPNGatewayConnectionIPsecPolicyPatch ipsec_policy: (optional)
        :param str name: (optional) The name for this VPN gateway connection. The
               name must not be used by another connection for the VPN gateway.
        :param str peer_address: (optional) The IP address of the peer VPN gateway.
        :param str psk: (optional) The pre-shared key.
        :param str routing_protocol: (optional) Routing protocols are disabled for
               this VPN gateway connection.
        """
        # pylint: disable=super-init-not-called
        self.admin_state_up = admin_state_up
        self.dead_peer_detection = dead_peer_detection
        self.ike_policy = ike_policy
        self.ipsec_policy = ipsec_policy
        self.name = name
        self.peer_address = peer_address
        self.psk = psk
        self.routing_protocol = routing_protocol

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPNGatewayConnectionPatchVPNGatewayConnectionStaticRouteModePatch':
        """Initialize a VPNGatewayConnectionPatchVPNGatewayConnectionStaticRouteModePatch object from a json dictionary."""
        args = {}
        if 'admin_state_up' in _dict:
            args['admin_state_up'] = _dict.get('admin_state_up')
        if 'dead_peer_detection' in _dict:
            args['dead_peer_detection'] = VPNGatewayConnectionDPDPatch.from_dict(_dict.get('dead_peer_detection'))
        if 'ike_policy' in _dict:
            args['ike_policy'] = _dict.get('ike_policy')
        if 'ipsec_policy' in _dict:
            args['ipsec_policy'] = _dict.get('ipsec_policy')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        if 'peer_address' in _dict:
            args['peer_address'] = _dict.get('peer_address')
        if 'psk' in _dict:
            args['psk'] = _dict.get('psk')
        if 'routing_protocol' in _dict:
            args['routing_protocol'] = _dict.get('routing_protocol')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPNGatewayConnectionPatchVPNGatewayConnectionStaticRouteModePatch object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'admin_state_up') and self.admin_state_up is not None:
            _dict['admin_state_up'] = self.admin_state_up
        if hasattr(self, 'dead_peer_detection') and self.dead_peer_detection is not None:
            if isinstance(self.dead_peer_detection, dict):
                _dict['dead_peer_detection'] = self.dead_peer_detection
            else:
                _dict['dead_peer_detection'] = self.dead_peer_detection.to_dict()
        if hasattr(self, 'ike_policy') and self.ike_policy is not None:
            if isinstance(self.ike_policy, dict):
                _dict['ike_policy'] = self.ike_policy
            else:
                _dict['ike_policy'] = self.ike_policy.to_dict()
        if hasattr(self, 'ipsec_policy') and self.ipsec_policy is not None:
            if isinstance(self.ipsec_policy, dict):
                _dict['ipsec_policy'] = self.ipsec_policy
            else:
                _dict['ipsec_policy'] = self.ipsec_policy.to_dict()
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'peer_address') and self.peer_address is not None:
            _dict['peer_address'] = self.peer_address
        if hasattr(self, 'psk') and self.psk is not None:
            _dict['psk'] = self.psk
        if hasattr(self, 'routing_protocol') and self.routing_protocol is not None:
            _dict['routing_protocol'] = self.routing_protocol
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VPNGatewayConnectionPatchVPNGatewayConnectionStaticRouteModePatch object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPNGatewayConnectionPatchVPNGatewayConnectionStaticRouteModePatch') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPNGatewayConnectionPatchVPNGatewayConnectionStaticRouteModePatch') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class RoutingProtocolEnum(str, Enum):
        """
        Routing protocols are disabled for this VPN gateway connection.
        """

        NONE = 'none'



class VPNGatewayConnectionPolicyMode(VPNGatewayConnection):
    """
    VPNGatewayConnectionPolicyMode.

    :attr bool admin_state_up: If set to false, the VPN gateway connection is shut
          down.
    :attr str authentication_mode: The authentication mode. Only `psk` is currently
          supported.
    :attr datetime created_at: The date and time that this VPN gateway connection
          was created.
    :attr VPNGatewayConnectionDPD dead_peer_detection:
    :attr str href: The VPN connection's canonical URL.
    :attr str id: The unique identifier for this VPN gateway connection.
    :attr IKEPolicyReference ike_policy: (optional) The IKE policy. If absent,
          [auto-negotiation is
          used](https://cloud.ibm.com/docs/vpc?topic=vpc-using-vpn&interface=ui#ike-auto-negotiation-phase-1).
    :attr IPsecPolicyReference ipsec_policy: (optional) The IPsec policy. If absent,
          [auto-negotiation is
          used](https://cloud.ibm.com/docs/vpc?topic=vpc-using-vpn&interface=ui#ipsec-auto-negotiation-phase-2).
    :attr str mode: The mode of the VPN gateway.
    :attr str name: The name for this VPN gateway connection. The name is unique
          across all connections for the VPN gateway.
    :attr str peer_address: The IP address of the peer VPN gateway.
    :attr str psk: The pre-shared key.
    :attr str resource_type: The resource type.
    :attr str status: The status of a VPN gateway connection.
    :attr List[VPNGatewayConnectionStatusReason] status_reasons: The reasons for the
          current VPN gateway connection status (if any):
          - `cannot_authenticate_connection`: Failed to authenticate a connection because
          of
            mismatched IKE ID and PSK (check IKE ID and PSK in peer VPN configuration)
          - `internal_error`: Internal error (contact IBM support)
          - `ike_policy_mismatch`: None of the proposed IKE crypto suites was acceptable
          (check
             the IKE policies on both sides of the VPN)
          - `ike_v1_id_local_remote_cidr_mismatch`: Invalid IKE ID or mismatched local
          CIDRs and
            remote CIDRs in IKE V1 (check the IKE ID or the local CIDRs and remote CIDRs
          in IKE
            V1 configuration)
          - `ike_v2_local_remote_cidr_mismatch`: Mismatched local CIDRs and remote CIDRs
          in IKE
            V2 (check the local CIDRs and remote CIDRs in IKE V2 configuration)
          - `ipsec_policy_mismatch`: None of the proposed IPsec crypto suites was
          acceptable
            (check the IPsec policies on both sides of the VPN)
          - `peer_not_responding`: No response from peer (check network ACL configuration,
          peer
            availability, and on-premise firewall configuration)
          The enumerated reason code values for this property will expand in the future.
          When processing this property, check for and log unknown values. Optionally halt
          processing and surface the error, or bypass the resource on which the unexpected
          reason code was encountered.
    :attr List[str] local_cidrs: The local CIDRs for this resource.
    :attr List[str] peer_cidrs: The 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,
        status_reasons: List['VPNGatewayConnectionStatusReason'],
        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 name for this VPN gateway connection. The name is
               unique across all connections for the VPN gateway.
        :param str peer_address: The IP address of the peer VPN gateway.
        :param str psk: The pre-shared key.
        :param str resource_type: The resource type.
        :param str status: The status of a VPN gateway connection.
        :param List[VPNGatewayConnectionStatusReason] status_reasons: The reasons
               for the current VPN gateway connection status (if any):
               - `cannot_authenticate_connection`: Failed to authenticate a connection
               because of
                 mismatched IKE ID and PSK (check IKE ID and PSK in peer VPN
               configuration)
               - `internal_error`: Internal error (contact IBM support)
               - `ike_policy_mismatch`: None of the proposed IKE crypto suites was
               acceptable (check
                  the IKE policies on both sides of the VPN)
               - `ike_v1_id_local_remote_cidr_mismatch`: Invalid IKE ID or mismatched
               local CIDRs and
                 remote CIDRs in IKE V1 (check the IKE ID or the local CIDRs and remote
               CIDRs in IKE
                 V1 configuration)
               - `ike_v2_local_remote_cidr_mismatch`: Mismatched local CIDRs and remote
               CIDRs in IKE
                 V2 (check the local CIDRs and remote CIDRs in IKE V2 configuration)
               - `ipsec_policy_mismatch`: None of the proposed IPsec crypto suites was
               acceptable
                 (check the IPsec policies on both sides of the VPN)
               - `peer_not_responding`: No response from peer (check network ACL
               configuration, peer
                 availability, and on-premise firewall configuration)
               The enumerated reason code values for this property will expand in the
               future. When processing this property, check for and log unknown values.
               Optionally halt processing and surface the error, or bypass the resource on
               which the unexpected reason code was encountered.
        :param List[str] local_cidrs: The local CIDRs for this resource.
        :param List[str] peer_cidrs: The peer CIDRs for this resource.
        :param IKEPolicyReference ike_policy: (optional) The IKE policy. If absent,
               [auto-negotiation is
               used](https://cloud.ibm.com/docs/vpc?topic=vpc-using-vpn&interface=ui#ike-auto-negotiation-phase-1).
        :param IPsecPolicyReference ipsec_policy: (optional) The IPsec policy. If
               absent, [auto-negotiation is
               used](https://cloud.ibm.com/docs/vpc?topic=vpc-using-vpn&interface=ui#ipsec-auto-negotiation-phase-2).
        """
        # 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.status_reasons = status_reasons
        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 'status_reasons' in _dict:
            args['status_reasons'] = [VPNGatewayConnectionStatusReason.from_dict(v) for v in _dict.get('status_reasons')]
        else:
            raise ValueError('Required property \'status_reasons\' 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:
            if isinstance(self.dead_peer_detection, dict):
                _dict['dead_peer_detection'] = self.dead_peer_detection
            else:
                _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:
            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, '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, 'status_reasons') and self.status_reasons is not None:
            status_reasons_list = []
            for v in self.status_reasons:
                if isinstance(v, dict):
                    status_reasons_list.append(v)
                else:
                    status_reasons_list.append(v.to_dict())
            _dict['status_reasons'] = status_reasons_list
        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 VPNGatewayConnectionIKEPolicyPrototype ike_policy: (optional)
    :attr VPNGatewayConnectionIPsecPolicyPrototype ipsec_policy: (optional)
    :attr str name: (optional) The name for this VPN gateway connection. The name
          must not be used by another connection for the VPN gateway. If unspecified, the
          name will be a hyphenated list of randomly-selected words.
    :attr str peer_address: The IP address of the peer VPN gateway.
    :attr str psk: The pre-shared key.
    :attr List[str] local_cidrs: The local CIDRs for this resource.
    :attr List[str] peer_cidrs: The 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: 'VPNGatewayConnectionIKEPolicyPrototype' = None,
        ipsec_policy: 'VPNGatewayConnectionIPsecPolicyPrototype' = 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 pre-shared key.
        :param List[str] local_cidrs: The local CIDRs for this resource.
        :param List[str] peer_cidrs: The 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 VPNGatewayConnectionIKEPolicyPrototype ike_policy: (optional)
        :param VPNGatewayConnectionIPsecPolicyPrototype ipsec_policy: (optional)
        :param str name: (optional) The name for this VPN gateway connection. The
               name must not be used by another connection for the VPN gateway. If
               unspecified, the name will be a hyphenated list of randomly-selected words.
        """
        # 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:
            if isinstance(self.dead_peer_detection, dict):
                _dict['dead_peer_detection'] = self.dead_peer_detection
            else:
                _dict['dead_peer_detection'] = self.dead_peer_detection.to_dict()
        if hasattr(self, 'ike_policy') and self.ike_policy is not None:
            if isinstance(self.ike_policy, dict):
                _dict['ike_policy'] = self.ike_policy
            else:
                _dict['ike_policy'] = self.ike_policy.to_dict()
        if hasattr(self, 'ipsec_policy') and self.ipsec_policy is not None:
            if isinstance(self.ipsec_policy, dict):
                _dict['ipsec_policy'] = self.ipsec_policy
            else:
                _dict['ipsec_policy'] = self.ipsec_policy.to_dict()
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'peer_address') and self.peer_address is not None:
            _dict['peer_address'] = self.peer_address
        if hasattr(self, 'psk') and self.psk is not None:
            _dict['psk'] = self.psk
        if hasattr(self, 'local_cidrs') and self.local_cidrs is not None:
            _dict['local_cidrs'] = self.local_cidrs
        if hasattr(self, 'peer_cidrs') and self.peer_cidrs is not None:
            _dict['peer_cidrs'] = self.peer_cidrs
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VPNGatewayConnectionPrototypeVPNGatewayConnectionPolicyModePrototype object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPNGatewayConnectionPrototypeVPNGatewayConnectionPolicyModePrototype') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPNGatewayConnectionPrototypeVPNGatewayConnectionPolicyModePrototype') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VPNGatewayConnectionPrototypeVPNGatewayConnectionStaticRouteModePrototype(VPNGatewayConnectionPrototype):
    """
    VPNGatewayConnectionPrototypeVPNGatewayConnectionStaticRouteModePrototype.

    :attr bool admin_state_up: (optional) If set to false, the VPN gateway
          connection is shut down.
    :attr VPNGatewayConnectionDPDPrototype dead_peer_detection: (optional)
    :attr VPNGatewayConnectionIKEPolicyPrototype ike_policy: (optional)
    :attr VPNGatewayConnectionIPsecPolicyPrototype ipsec_policy: (optional)
    :attr str name: (optional) The name for this VPN gateway connection. The name
          must not be used by another connection for the VPN gateway. If unspecified, the
          name will be a hyphenated list of randomly-selected words.
    :attr str peer_address: The IP address of the peer VPN gateway.
    :attr str psk: The pre-shared key.
    :attr str routing_protocol: (optional) Routing protocols are disabled for this
          VPN gateway connection.
    """

    def __init__(
        self,
        peer_address: str,
        psk: str,
        *,
        admin_state_up: bool = None,
        dead_peer_detection: 'VPNGatewayConnectionDPDPrototype' = None,
        ike_policy: 'VPNGatewayConnectionIKEPolicyPrototype' = None,
        ipsec_policy: 'VPNGatewayConnectionIPsecPolicyPrototype' = None,
        name: str = None,
        routing_protocol: str = None,
    ) -> None:
        """
        Initialize a VPNGatewayConnectionPrototypeVPNGatewayConnectionStaticRouteModePrototype object.

        :param str peer_address: The IP address of the peer VPN gateway.
        :param str psk: The pre-shared key.
        :param bool admin_state_up: (optional) If set to false, the VPN gateway
               connection is shut down.
        :param VPNGatewayConnectionDPDPrototype dead_peer_detection: (optional)
        :param VPNGatewayConnectionIKEPolicyPrototype ike_policy: (optional)
        :param VPNGatewayConnectionIPsecPolicyPrototype ipsec_policy: (optional)
        :param str name: (optional) The name for this VPN gateway connection. The
               name must not be used by another connection for the VPN gateway. If
               unspecified, the name will be a hyphenated list of randomly-selected words.
        :param str routing_protocol: (optional) Routing protocols are disabled for
               this VPN gateway connection.
        """
        # pylint: disable=super-init-not-called
        self.admin_state_up = admin_state_up
        self.dead_peer_detection = dead_peer_detection
        self.ike_policy = ike_policy
        self.ipsec_policy = ipsec_policy
        self.name = name
        self.peer_address = peer_address
        self.psk = psk
        self.routing_protocol = routing_protocol

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPNGatewayConnectionPrototypeVPNGatewayConnectionStaticRouteModePrototype':
        """Initialize a VPNGatewayConnectionPrototypeVPNGatewayConnectionStaticRouteModePrototype object from a json dictionary."""
        args = {}
        if 'admin_state_up' in _dict:
            args['admin_state_up'] = _dict.get('admin_state_up')
        if 'dead_peer_detection' in _dict:
            args['dead_peer_detection'] = VPNGatewayConnectionDPDPrototype.from_dict(_dict.get('dead_peer_detection'))
        if 'ike_policy' in _dict:
            args['ike_policy'] = _dict.get('ike_policy')
        if 'ipsec_policy' in _dict:
            args['ipsec_policy'] = _dict.get('ipsec_policy')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        if 'peer_address' in _dict:
            args['peer_address'] = _dict.get('peer_address')
        else:
            raise ValueError('Required property \'peer_address\' not present in VPNGatewayConnectionPrototypeVPNGatewayConnectionStaticRouteModePrototype JSON')
        if 'psk' in _dict:
            args['psk'] = _dict.get('psk')
        else:
            raise ValueError('Required property \'psk\' not present in VPNGatewayConnectionPrototypeVPNGatewayConnectionStaticRouteModePrototype JSON')
        if 'routing_protocol' in _dict:
            args['routing_protocol'] = _dict.get('routing_protocol')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPNGatewayConnectionPrototypeVPNGatewayConnectionStaticRouteModePrototype object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'admin_state_up') and self.admin_state_up is not None:
            _dict['admin_state_up'] = self.admin_state_up
        if hasattr(self, 'dead_peer_detection') and self.dead_peer_detection is not None:
            if isinstance(self.dead_peer_detection, dict):
                _dict['dead_peer_detection'] = self.dead_peer_detection
            else:
                _dict['dead_peer_detection'] = self.dead_peer_detection.to_dict()
        if hasattr(self, 'ike_policy') and self.ike_policy is not None:
            if isinstance(self.ike_policy, dict):
                _dict['ike_policy'] = self.ike_policy
            else:
                _dict['ike_policy'] = self.ike_policy.to_dict()
        if hasattr(self, 'ipsec_policy') and self.ipsec_policy is not None:
            if isinstance(self.ipsec_policy, dict):
                _dict['ipsec_policy'] = self.ipsec_policy
            else:
                _dict['ipsec_policy'] = self.ipsec_policy.to_dict()
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'peer_address') and self.peer_address is not None:
            _dict['peer_address'] = self.peer_address
        if hasattr(self, 'psk') and self.psk is not None:
            _dict['psk'] = self.psk
        if hasattr(self, 'routing_protocol') and self.routing_protocol is not None:
            _dict['routing_protocol'] = self.routing_protocol
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VPNGatewayConnectionPrototypeVPNGatewayConnectionStaticRouteModePrototype object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPNGatewayConnectionPrototypeVPNGatewayConnectionStaticRouteModePrototype') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPNGatewayConnectionPrototypeVPNGatewayConnectionStaticRouteModePrototype') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class RoutingProtocolEnum(str, Enum):
        """
        Routing protocols are disabled for this VPN gateway connection.
        """

        NONE = 'none'



class VPNGatewayConnectionStaticRouteMode(VPNGatewayConnection):
    """
    VPNGatewayConnectionStaticRouteMode.

    :attr bool admin_state_up: If set to false, the VPN gateway connection is shut
          down.
    :attr str authentication_mode: The authentication mode. Only `psk` is currently
          supported.
    :attr datetime created_at: The date and time that this VPN gateway connection
          was created.
    :attr VPNGatewayConnectionDPD dead_peer_detection:
    :attr str href: The VPN connection's canonical URL.
    :attr str id: The unique identifier for this VPN gateway connection.
    :attr IKEPolicyReference ike_policy: (optional) The IKE policy. If absent,
          [auto-negotiation is
          used](https://cloud.ibm.com/docs/vpc?topic=vpc-using-vpn&interface=ui#ike-auto-negotiation-phase-1).
    :attr IPsecPolicyReference ipsec_policy: (optional) The IPsec policy. If absent,
          [auto-negotiation is
          used](https://cloud.ibm.com/docs/vpc?topic=vpc-using-vpn&interface=ui#ipsec-auto-negotiation-phase-2).
    :attr str mode: The mode of the VPN gateway.
    :attr str name: The name for this VPN gateway connection. The name is unique
          across all connections for the VPN gateway.
    :attr str peer_address: The IP address of the peer VPN gateway.
    :attr str psk: The pre-shared key.
    :attr str resource_type: The resource type.
    :attr str status: The status of a VPN gateway connection.
    :attr List[VPNGatewayConnectionStatusReason] status_reasons: The reasons for the
          current VPN gateway connection status (if any):
          - `cannot_authenticate_connection`: Failed to authenticate a connection because
          of
            mismatched IKE ID and PSK (check IKE ID and PSK in peer VPN configuration)
          - `internal_error`: Internal error (contact IBM support)
          - `ike_policy_mismatch`: None of the proposed IKE crypto suites was acceptable
          (check
             the IKE policies on both sides of the VPN)
          - `ike_v1_id_local_remote_cidr_mismatch`: Invalid IKE ID or mismatched local
          CIDRs and
            remote CIDRs in IKE V1 (check the IKE ID or the local CIDRs and remote CIDRs
          in IKE
            V1 configuration)
          - `ike_v2_local_remote_cidr_mismatch`: Mismatched local CIDRs and remote CIDRs
          in IKE
            V2 (check the local CIDRs and remote CIDRs in IKE V2 configuration)
          - `ipsec_policy_mismatch`: None of the proposed IPsec crypto suites was
          acceptable
            (check the IPsec policies on both sides of the VPN)
          - `peer_not_responding`: No response from peer (check network ACL configuration,
          peer
            availability, and on-premise firewall configuration)
          The enumerated reason code values for this property will expand in the future.
          When processing this property, check for and log unknown values. Optionally halt
          processing and surface the error, or bypass the resource on which the unexpected
          reason code was encountered.
    :attr str routing_protocol: Routing protocols are disabled for this VPN gateway
          connection.
    :attr List[VPNGatewayConnectionStaticRouteModeTunnel] tunnels: The VPN tunnel
          configuration for this VPN gateway connection (in static route mode).
    """

    def __init__(
        self,
        admin_state_up: bool,
        authentication_mode: str,
        created_at: datetime,
        dead_peer_detection: 'VPNGatewayConnectionDPD',
        href: str,
        id: str,
        mode: str,
        name: str,
        peer_address: str,
        psk: str,
        resource_type: str,
        status: str,
        status_reasons: List['VPNGatewayConnectionStatusReason'],
        routing_protocol: str,
        tunnels: List['VPNGatewayConnectionStaticRouteModeTunnel'],
        *,
        ike_policy: 'IKEPolicyReference' = None,
        ipsec_policy: 'IPsecPolicyReference' = None,
    ) -> None:
        """
        Initialize a VPNGatewayConnectionStaticRouteMode object.

        :param bool admin_state_up: If set to false, the VPN gateway connection is
               shut down.
        :param str authentication_mode: The authentication mode. Only `psk` is
               currently supported.
        :param datetime created_at: The date and time that this VPN gateway
               connection was created.
        :param VPNGatewayConnectionDPD dead_peer_detection:
        :param str href: The VPN connection's canonical URL.
        :param str id: The unique identifier for this VPN gateway connection.
        :param str mode: The mode of the VPN gateway.
        :param str name: The name for this VPN gateway connection. The name is
               unique across all connections for the VPN gateway.
        :param str peer_address: The IP address of the peer VPN gateway.
        :param str psk: The pre-shared key.
        :param str resource_type: The resource type.
        :param str status: The status of a VPN gateway connection.
        :param List[VPNGatewayConnectionStatusReason] status_reasons: The reasons
               for the current VPN gateway connection status (if any):
               - `cannot_authenticate_connection`: Failed to authenticate a connection
               because of
                 mismatched IKE ID and PSK (check IKE ID and PSK in peer VPN
               configuration)
               - `internal_error`: Internal error (contact IBM support)
               - `ike_policy_mismatch`: None of the proposed IKE crypto suites was
               acceptable (check
                  the IKE policies on both sides of the VPN)
               - `ike_v1_id_local_remote_cidr_mismatch`: Invalid IKE ID or mismatched
               local CIDRs and
                 remote CIDRs in IKE V1 (check the IKE ID or the local CIDRs and remote
               CIDRs in IKE
                 V1 configuration)
               - `ike_v2_local_remote_cidr_mismatch`: Mismatched local CIDRs and remote
               CIDRs in IKE
                 V2 (check the local CIDRs and remote CIDRs in IKE V2 configuration)
               - `ipsec_policy_mismatch`: None of the proposed IPsec crypto suites was
               acceptable
                 (check the IPsec policies on both sides of the VPN)
               - `peer_not_responding`: No response from peer (check network ACL
               configuration, peer
                 availability, and on-premise firewall configuration)
               The enumerated reason code values for this property will expand in the
               future. When processing this property, check for and log unknown values.
               Optionally halt processing and surface the error, or bypass the resource on
               which the unexpected reason code was encountered.
        :param str routing_protocol: Routing protocols are disabled for this VPN
               gateway connection.
        :param List[VPNGatewayConnectionStaticRouteModeTunnel] tunnels: The VPN
               tunnel configuration for this VPN gateway connection (in static route
               mode).
        :param IKEPolicyReference ike_policy: (optional) The IKE policy. If absent,
               [auto-negotiation is
               used](https://cloud.ibm.com/docs/vpc?topic=vpc-using-vpn&interface=ui#ike-auto-negotiation-phase-1).
        :param IPsecPolicyReference ipsec_policy: (optional) The IPsec policy. If
               absent, [auto-negotiation is
               used](https://cloud.ibm.com/docs/vpc?topic=vpc-using-vpn&interface=ui#ipsec-auto-negotiation-phase-2).
        """
        # 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.status_reasons = status_reasons
        self.routing_protocol = routing_protocol
        self.tunnels = tunnels

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPNGatewayConnectionStaticRouteMode':
        """Initialize a VPNGatewayConnectionStaticRouteMode object from a json dictionary."""
        args = {}
        if 'admin_state_up' in _dict:
            args['admin_state_up'] = _dict.get('admin_state_up')
        else:
            raise ValueError('Required property \'admin_state_up\' not present in VPNGatewayConnectionStaticRouteMode JSON')
        if 'authentication_mode' in _dict:
            args['authentication_mode'] = _dict.get('authentication_mode')
        else:
            raise ValueError('Required property \'authentication_mode\' not present in VPNGatewayConnectionStaticRouteMode JSON')
        if 'created_at' in _dict:
            args['created_at'] = string_to_datetime(_dict.get('created_at'))
        else:
            raise ValueError('Required property \'created_at\' not present in VPNGatewayConnectionStaticRouteMode JSON')
        if 'dead_peer_detection' in _dict:
            args['dead_peer_detection'] = VPNGatewayConnectionDPD.from_dict(_dict.get('dead_peer_detection'))
        else:
            raise ValueError('Required property \'dead_peer_detection\' not present in VPNGatewayConnectionStaticRouteMode JSON')
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in VPNGatewayConnectionStaticRouteMode JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in VPNGatewayConnectionStaticRouteMode JSON')
        if 'ike_policy' in _dict:
            args['ike_policy'] = IKEPolicyReference.from_dict(_dict.get('ike_policy'))
        if 'ipsec_policy' in _dict:
            args['ipsec_policy'] = IPsecPolicyReference.from_dict(_dict.get('ipsec_policy'))
        if 'mode' in _dict:
            args['mode'] = _dict.get('mode')
        else:
            raise ValueError('Required property \'mode\' not present in VPNGatewayConnectionStaticRouteMode JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in VPNGatewayConnectionStaticRouteMode JSON')
        if 'peer_address' in _dict:
            args['peer_address'] = _dict.get('peer_address')
        else:
            raise ValueError('Required property \'peer_address\' not present in VPNGatewayConnectionStaticRouteMode JSON')
        if 'psk' in _dict:
            args['psk'] = _dict.get('psk')
        else:
            raise ValueError('Required property \'psk\' not present in VPNGatewayConnectionStaticRouteMode JSON')
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError('Required property \'resource_type\' not present in VPNGatewayConnectionStaticRouteMode JSON')
        if 'status' in _dict:
            args['status'] = _dict.get('status')
        else:
            raise ValueError('Required property \'status\' not present in VPNGatewayConnectionStaticRouteMode JSON')
        if 'status_reasons' in _dict:
            args['status_reasons'] = [VPNGatewayConnectionStatusReason.from_dict(v) for v in _dict.get('status_reasons')]
        else:
            raise ValueError('Required property \'status_reasons\' not present in VPNGatewayConnectionStaticRouteMode JSON')
        if 'routing_protocol' in _dict:
            args['routing_protocol'] = _dict.get('routing_protocol')
        else:
            raise ValueError('Required property \'routing_protocol\' not present in VPNGatewayConnectionStaticRouteMode JSON')
        if 'tunnels' in _dict:
            args['tunnels'] = [VPNGatewayConnectionStaticRouteModeTunnel.from_dict(v) for v in _dict.get('tunnels')]
        else:
            raise ValueError('Required property \'tunnels\' not present in VPNGatewayConnectionStaticRouteMode JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPNGatewayConnectionStaticRouteMode object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'admin_state_up') and self.admin_state_up is not None:
            _dict['admin_state_up'] = self.admin_state_up
        if hasattr(self, 'authentication_mode') and self.authentication_mode is not None:
            _dict['authentication_mode'] = self.authentication_mode
        if hasattr(self, 'created_at') and self.created_at is not None:
            _dict['created_at'] = datetime_to_string(self.created_at)
        if hasattr(self, 'dead_peer_detection') and self.dead_peer_detection is not None:
            if isinstance(self.dead_peer_detection, dict):
                _dict['dead_peer_detection'] = self.dead_peer_detection
            else:
                _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:
            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, '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, 'status_reasons') and self.status_reasons is not None:
            status_reasons_list = []
            for v in self.status_reasons:
                if isinstance(v, dict):
                    status_reasons_list.append(v)
                else:
                    status_reasons_list.append(v.to_dict())
            _dict['status_reasons'] = status_reasons_list
        if hasattr(self, 'routing_protocol') and self.routing_protocol is not None:
            _dict['routing_protocol'] = self.routing_protocol
        if hasattr(self, 'tunnels') and self.tunnels is not None:
            tunnels_list = []
            for v in self.tunnels:
                if isinstance(v, dict):
                    tunnels_list.append(v)
                else:
                    tunnels_list.append(v.to_dict())
            _dict['tunnels'] = tunnels_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 VPNGatewayConnectionStaticRouteMode object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPNGatewayConnectionStaticRouteMode') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPNGatewayConnectionStaticRouteMode') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class AuthenticationModeEnum(str, Enum):
        """
        The authentication mode. Only `psk` is currently supported.
        """

        PSK = 'psk'


    class ModeEnum(str, Enum):
        """
        The mode of the VPN gateway.
        """

        POLICY = 'policy'
        ROUTE = 'route'


    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        VPN_GATEWAY_CONNECTION = 'vpn_gateway_connection'


    class StatusEnum(str, Enum):
        """
        The status of a VPN gateway connection.
        """

        DOWN = 'down'
        UP = 'up'


    class RoutingProtocolEnum(str, Enum):
        """
        Routing protocols are disabled for this VPN gateway connection.
        """

        NONE = 'none'



class VPNGatewayPolicyMode(VPNGateway):
    """
    VPNGatewayPolicyMode.

    :attr List[VPNGatewayConnectionReference] connections: Connections for this VPN
          gateway.
    :attr datetime created_at: The date and time that this VPN gateway was created.
    :attr str crn: The VPN gateway's CRN.
    :attr List[VPNGatewayHealthReason] health_reasons: The reasons for the current
          VPN gateway health_state (if any):
          - `cannot_create_vpc_route`: VPN cannot create route (check for conflict)
          - `cannot_reserve_ip_address`: IP address exhaustion (release addresses on the
          VPN's
            subnet)
          - `internal_error`: Internal error (contact IBM support)
          The enumerated reason code values for this property will expand in the future.
          When processing this property, check for and log unknown values. Optionally halt
          processing and surface the error, or bypass the resource on which the unexpected
          reason code was encountered.
    :attr str health_state: The health of this resource.
          - `ok`: No abnormal behavior detected
          - `degraded`: Experiencing compromised performance, capacity, or connectivity
          - `faulted`: Completely unreachable, inoperative, or otherwise entirely
          incapacitated
          - `inapplicable`: The health state does not apply because of the current
          lifecycle state. A resource with a lifecycle state of `failed` or `deleting`
          will have a health state of `inapplicable`. A `pending` resource may also have
          this state.
    :attr str href: The VPN gateway's canonical URL.
    :attr str id: The unique identifier for this VPN gateway.
    :attr List[VPNGatewayLifecycleReason] lifecycle_reasons: The reasons for the
          current VPN gateway lifecycle_state (if any):
          - `resource_suspended_by_provider`: The resource has been suspended (contact IBM
            support)
          The enumerated reason code values for this property will expand in the future.
          When processing this property, check for and log unknown values. Optionally halt
          processing and surface the error, or bypass the resource on which the unexpected
          reason code was encountered.
    :attr str lifecycle_state: The lifecycle state of the VPN gateway.
    :attr List[VPNGatewayMember] members: Collection of VPN gateway members.
    :attr str name: The name for this VPN gateway. The name is unique across all VPN
          gateways in the VPC.
    :attr ResourceGroupReference resource_group: The resource group for this VPN
          gateway.
    :attr str resource_type: The resource type.
    :attr SubnetReference subnet:
    :attr VPCReference vpc: The VPC this VPN gateway resides in.
    :attr str mode: Policy mode VPN gateway.
    """

    def __init__(
        self,
        connections: List['VPNGatewayConnectionReference'],
        created_at: datetime,
        crn: str,
        health_reasons: List['VPNGatewayHealthReason'],
        health_state: str,
        href: str,
        id: str,
        lifecycle_reasons: List['VPNGatewayLifecycleReason'],
        lifecycle_state: str,
        members: List['VPNGatewayMember'],
        name: str,
        resource_group: 'ResourceGroupReference',
        resource_type: str,
        subnet: 'SubnetReference',
        vpc: 'VPCReference',
        mode: str,
    ) -> None:
        """
        Initialize a VPNGatewayPolicyMode object.

        :param List[VPNGatewayConnectionReference] connections: Connections for
               this VPN gateway.
        :param datetime created_at: The date and time that this VPN gateway was
               created.
        :param str crn: The VPN gateway's CRN.
        :param List[VPNGatewayHealthReason] health_reasons: The reasons for the
               current VPN gateway health_state (if any):
               - `cannot_create_vpc_route`: VPN cannot create route (check for conflict)
               - `cannot_reserve_ip_address`: IP address exhaustion (release addresses on
               the VPN's
                 subnet)
               - `internal_error`: Internal error (contact IBM support)
               The enumerated reason code values for this property will expand in the
               future. When processing this property, check for and log unknown values.
               Optionally halt processing and surface the error, or bypass the resource on
               which the unexpected reason code was encountered.
        :param str health_state: The health of this resource.
               - `ok`: No abnormal behavior detected
               - `degraded`: Experiencing compromised performance, capacity, or
               connectivity
               - `faulted`: Completely unreachable, inoperative, or otherwise entirely
               incapacitated
               - `inapplicable`: The health state does not apply because of the current
               lifecycle state. A resource with a lifecycle state of `failed` or
               `deleting` will have a health state of `inapplicable`. A `pending` resource
               may also have this state.
        :param str href: The VPN gateway's canonical URL.
        :param str id: The unique identifier for this VPN gateway.
        :param List[VPNGatewayLifecycleReason] lifecycle_reasons: The reasons for
               the current VPN gateway lifecycle_state (if any):
               - `resource_suspended_by_provider`: The resource has been suspended
               (contact IBM
                 support)
               The enumerated reason code values for this property will expand in the
               future. When processing this property, check for and log unknown values.
               Optionally halt processing and surface the error, or bypass the resource on
               which the unexpected reason code was encountered.
        :param str lifecycle_state: The lifecycle state of the VPN gateway.
        :param List[VPNGatewayMember] members: Collection of VPN gateway members.
        :param str name: The name for this VPN gateway. The name is unique across
               all VPN gateways in the VPC.
        :param ResourceGroupReference resource_group: The resource group for this
               VPN gateway.
        :param str resource_type: The resource type.
        :param SubnetReference subnet:
        :param VPCReference vpc: The VPC this VPN gateway resides in.
        :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.health_reasons = health_reasons
        self.health_state = health_state
        self.href = href
        self.id = id
        self.lifecycle_reasons = lifecycle_reasons
        self.lifecycle_state = lifecycle_state
        self.members = members
        self.name = name
        self.resource_group = resource_group
        self.resource_type = resource_type
        self.subnet = subnet
        self.vpc = vpc
        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(v) for v 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 'health_reasons' in _dict:
            args['health_reasons'] = [VPNGatewayHealthReason.from_dict(v) for v in _dict.get('health_reasons')]
        else:
            raise ValueError('Required property \'health_reasons\' not present in VPNGatewayPolicyMode JSON')
        if 'health_state' in _dict:
            args['health_state'] = _dict.get('health_state')
        else:
            raise ValueError('Required property \'health_state\' 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 'lifecycle_reasons' in _dict:
            args['lifecycle_reasons'] = [VPNGatewayLifecycleReason.from_dict(v) for v in _dict.get('lifecycle_reasons')]
        else:
            raise ValueError('Required property \'lifecycle_reasons\' not present in VPNGatewayPolicyMode JSON')
        if 'lifecycle_state' in _dict:
            args['lifecycle_state'] = _dict.get('lifecycle_state')
        else:
            raise ValueError('Required property \'lifecycle_state\' not present in VPNGatewayPolicyMode JSON')
        if 'members' in _dict:
            args['members'] = [VPNGatewayMember.from_dict(v) for v 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 'subnet' in _dict:
            args['subnet'] = SubnetReference.from_dict(_dict.get('subnet'))
        else:
            raise ValueError('Required property \'subnet\' not present in VPNGatewayPolicyMode JSON')
        if 'vpc' in _dict:
            args['vpc'] = VPCReference.from_dict(_dict.get('vpc'))
        else:
            raise ValueError('Required property \'vpc\' 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:
            connections_list = []
            for v in self.connections:
                if isinstance(v, dict):
                    connections_list.append(v)
                else:
                    connections_list.append(v.to_dict())
            _dict['connections'] = connections_list
        if hasattr(self, 'created_at') and self.created_at is not None:
            _dict['created_at'] = datetime_to_string(self.created_at)
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'health_reasons') and self.health_reasons is not None:
            health_reasons_list = []
            for v in self.health_reasons:
                if isinstance(v, dict):
                    health_reasons_list.append(v)
                else:
                    health_reasons_list.append(v.to_dict())
            _dict['health_reasons'] = health_reasons_list
        if hasattr(self, 'health_state') and self.health_state is not None:
            _dict['health_state'] = self.health_state
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'lifecycle_reasons') and self.lifecycle_reasons is not None:
            lifecycle_reasons_list = []
            for v in self.lifecycle_reasons:
                if isinstance(v, dict):
                    lifecycle_reasons_list.append(v)
                else:
                    lifecycle_reasons_list.append(v.to_dict())
            _dict['lifecycle_reasons'] = lifecycle_reasons_list
        if hasattr(self, 'lifecycle_state') and self.lifecycle_state is not None:
            _dict['lifecycle_state'] = self.lifecycle_state
        if hasattr(self, 'members') and self.members is not None:
            members_list = []
            for v in self.members:
                if isinstance(v, dict):
                    members_list.append(v)
                else:
                    members_list.append(v.to_dict())
            _dict['members'] = members_list
        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, '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:
            if isinstance(self.subnet, dict):
                _dict['subnet'] = self.subnet
            else:
                _dict['subnet'] = self.subnet.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, '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 HealthStateEnum(str, Enum):
        """
        The health of this resource.
        - `ok`: No abnormal behavior detected
        - `degraded`: Experiencing compromised performance, capacity, or connectivity
        - `faulted`: Completely unreachable, inoperative, or otherwise entirely
        incapacitated
        - `inapplicable`: The health state does not apply because of the current lifecycle
        state. A resource with a lifecycle state of `failed` or `deleting` will have a
        health state of `inapplicable`. A `pending` resource may also have this state.
        """

        DEGRADED = 'degraded'
        FAULTED = 'faulted'
        INAPPLICABLE = 'inapplicable'
        OK = 'ok'


    class LifecycleStateEnum(str, Enum):
        """
        The lifecycle state of the VPN gateway.
        """

        DELETING = 'deleting'
        FAILED = 'failed'
        PENDING = 'pending'
        STABLE = 'stable'
        SUSPENDED = 'suspended'
        UPDATING = 'updating'
        WAITING = 'waiting'


    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        VPN_GATEWAY = 'vpn_gateway'


    class ModeEnum(str, Enum):
        """
        Policy mode VPN gateway.
        """

        POLICY = 'policy'



class VPNGatewayPrototypeVPNGatewayPolicyModePrototype(VPNGatewayPrototype):
    """
    VPNGatewayPrototypeVPNGatewayPolicyModePrototype.

    :attr str name: (optional) The name for this VPN gateway. The name must not be
          used by another VPN gateway in the VPC. If unspecified, the name will be a
          hyphenated list of randomly-selected words.
    :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 name for this VPN gateway. The name must
               not be used by another VPN gateway in the VPC. If unspecified, the name
               will be a hyphenated list of randomly-selected words.
        :param ResourceGroupIdentity resource_group: (optional)
        :param str mode: (optional) Policy mode VPN gateway.
        """
        # pylint: disable=super-init-not-called
        self.name = name
        self.resource_group = resource_group
        self.subnet = subnet
        self.mode = mode

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPNGatewayPrototypeVPNGatewayPolicyModePrototype':
        """Initialize a VPNGatewayPrototypeVPNGatewayPolicyModePrototype object from a json dictionary."""
        args = {}
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        if 'resource_group' in _dict:
            args['resource_group'] = _dict.get('resource_group')
        if 'subnet' in _dict:
            args['subnet'] = _dict.get('subnet')
        else:
            raise ValueError('Required property \'subnet\' not present in VPNGatewayPrototypeVPNGatewayPolicyModePrototype JSON')
        if 'mode' in _dict:
            args['mode'] = _dict.get('mode')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPNGatewayPrototypeVPNGatewayPolicyModePrototype object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'resource_group') and self.resource_group is not None:
            if isinstance(self.resource_group, dict):
                _dict['resource_group'] = self.resource_group
            else:
                _dict['resource_group'] = self.resource_group.to_dict()
        if hasattr(self, 'subnet') and self.subnet is not None:
            if isinstance(self.subnet, dict):
                _dict['subnet'] = self.subnet
            else:
                _dict['subnet'] = self.subnet.to_dict()
        if hasattr(self, 'mode') and self.mode is not None:
            _dict['mode'] = self.mode
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VPNGatewayPrototypeVPNGatewayPolicyModePrototype object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPNGatewayPrototypeVPNGatewayPolicyModePrototype') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPNGatewayPrototypeVPNGatewayPolicyModePrototype') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ModeEnum(str, Enum):
        """
        Policy mode VPN gateway.
        """

        POLICY = 'policy'



class VPNGatewayPrototypeVPNGatewayRouteModePrototype(VPNGatewayPrototype):
    """
    VPNGatewayPrototypeVPNGatewayRouteModePrototype.

    :attr str name: (optional) The name for this VPN gateway. The name must not be
          used by another VPN gateway in the VPC. If unspecified, the name will be a
          hyphenated list of randomly-selected words.
    :attr ResourceGroupIdentity resource_group: (optional)
    :attr SubnetIdentity subnet:
    :attr str mode: (optional) Route mode VPN gateway.
    """

    def __init__(
        self,
        subnet: 'SubnetIdentity',
        *,
        name: str = None,
        resource_group: 'ResourceGroupIdentity' = None,
        mode: str = None,
    ) -> None:
        """
        Initialize a VPNGatewayPrototypeVPNGatewayRouteModePrototype object.

        :param SubnetIdentity subnet:
        :param str name: (optional) The name for this VPN gateway. The name must
               not be used by another VPN gateway in the VPC. If unspecified, the name
               will be a hyphenated list of randomly-selected words.
        :param ResourceGroupIdentity resource_group: (optional)
        :param str mode: (optional) Route mode VPN gateway.
        """
        # pylint: disable=super-init-not-called
        self.name = name
        self.resource_group = resource_group
        self.subnet = subnet
        self.mode = mode

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPNGatewayPrototypeVPNGatewayRouteModePrototype':
        """Initialize a VPNGatewayPrototypeVPNGatewayRouteModePrototype object from a json dictionary."""
        args = {}
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        if 'resource_group' in _dict:
            args['resource_group'] = _dict.get('resource_group')
        if 'subnet' in _dict:
            args['subnet'] = _dict.get('subnet')
        else:
            raise ValueError('Required property \'subnet\' not present in VPNGatewayPrototypeVPNGatewayRouteModePrototype JSON')
        if 'mode' in _dict:
            args['mode'] = _dict.get('mode')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPNGatewayPrototypeVPNGatewayRouteModePrototype object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'resource_group') and self.resource_group is not None:
            if isinstance(self.resource_group, dict):
                _dict['resource_group'] = self.resource_group
            else:
                _dict['resource_group'] = self.resource_group.to_dict()
        if hasattr(self, 'subnet') and self.subnet is not None:
            if isinstance(self.subnet, dict):
                _dict['subnet'] = self.subnet
            else:
                _dict['subnet'] = self.subnet.to_dict()
        if hasattr(self, 'mode') and self.mode is not None:
            _dict['mode'] = self.mode
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VPNGatewayPrototypeVPNGatewayRouteModePrototype object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPNGatewayPrototypeVPNGatewayRouteModePrototype') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPNGatewayPrototypeVPNGatewayRouteModePrototype') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ModeEnum(str, Enum):
        """
        Route mode VPN gateway.
        """

        ROUTE = 'route'



class VPNGatewayRouteMode(VPNGateway):
    """
    VPNGatewayRouteMode.

    :attr List[VPNGatewayConnectionReference] connections: Connections for this VPN
          gateway.
    :attr datetime created_at: The date and time that this VPN gateway was created.
    :attr str crn: The VPN gateway's CRN.
    :attr List[VPNGatewayHealthReason] health_reasons: The reasons for the current
          VPN gateway health_state (if any):
          - `cannot_create_vpc_route`: VPN cannot create route (check for conflict)
          - `cannot_reserve_ip_address`: IP address exhaustion (release addresses on the
          VPN's
            subnet)
          - `internal_error`: Internal error (contact IBM support)
          The enumerated reason code values for this property will expand in the future.
          When processing this property, check for and log unknown values. Optionally halt
          processing and surface the error, or bypass the resource on which the unexpected
          reason code was encountered.
    :attr str health_state: The health of this resource.
          - `ok`: No abnormal behavior detected
          - `degraded`: Experiencing compromised performance, capacity, or connectivity
          - `faulted`: Completely unreachable, inoperative, or otherwise entirely
          incapacitated
          - `inapplicable`: The health state does not apply because of the current
          lifecycle state. A resource with a lifecycle state of `failed` or `deleting`
          will have a health state of `inapplicable`. A `pending` resource may also have
          this state.
    :attr str href: The VPN gateway's canonical URL.
    :attr str id: The unique identifier for this VPN gateway.
    :attr List[VPNGatewayLifecycleReason] lifecycle_reasons: The reasons for the
          current VPN gateway lifecycle_state (if any):
          - `resource_suspended_by_provider`: The resource has been suspended (contact IBM
            support)
          The enumerated reason code values for this property will expand in the future.
          When processing this property, check for and log unknown values. Optionally halt
          processing and surface the error, or bypass the resource on which the unexpected
          reason code was encountered.
    :attr str lifecycle_state: The lifecycle state of the VPN gateway.
    :attr List[VPNGatewayMember] members: Collection of VPN gateway members.
    :attr str name: The name for this VPN gateway. The name is unique across all VPN
          gateways in the VPC.
    :attr ResourceGroupReference resource_group: The resource group for this VPN
          gateway.
    :attr str resource_type: The resource type.
    :attr SubnetReference subnet:
    :attr VPCReference vpc: The VPC this VPN gateway resides in.
    :attr str mode: Route mode VPN gateway.
    """

    def __init__(
        self,
        connections: List['VPNGatewayConnectionReference'],
        created_at: datetime,
        crn: str,
        health_reasons: List['VPNGatewayHealthReason'],
        health_state: str,
        href: str,
        id: str,
        lifecycle_reasons: List['VPNGatewayLifecycleReason'],
        lifecycle_state: str,
        members: List['VPNGatewayMember'],
        name: str,
        resource_group: 'ResourceGroupReference',
        resource_type: str,
        subnet: 'SubnetReference',
        vpc: 'VPCReference',
        mode: str,
    ) -> None:
        """
        Initialize a VPNGatewayRouteMode object.

        :param List[VPNGatewayConnectionReference] connections: Connections for
               this VPN gateway.
        :param datetime created_at: The date and time that this VPN gateway was
               created.
        :param str crn: The VPN gateway's CRN.
        :param List[VPNGatewayHealthReason] health_reasons: The reasons for the
               current VPN gateway health_state (if any):
               - `cannot_create_vpc_route`: VPN cannot create route (check for conflict)
               - `cannot_reserve_ip_address`: IP address exhaustion (release addresses on
               the VPN's
                 subnet)
               - `internal_error`: Internal error (contact IBM support)
               The enumerated reason code values for this property will expand in the
               future. When processing this property, check for and log unknown values.
               Optionally halt processing and surface the error, or bypass the resource on
               which the unexpected reason code was encountered.
        :param str health_state: The health of this resource.
               - `ok`: No abnormal behavior detected
               - `degraded`: Experiencing compromised performance, capacity, or
               connectivity
               - `faulted`: Completely unreachable, inoperative, or otherwise entirely
               incapacitated
               - `inapplicable`: The health state does not apply because of the current
               lifecycle state. A resource with a lifecycle state of `failed` or
               `deleting` will have a health state of `inapplicable`. A `pending` resource
               may also have this state.
        :param str href: The VPN gateway's canonical URL.
        :param str id: The unique identifier for this VPN gateway.
        :param List[VPNGatewayLifecycleReason] lifecycle_reasons: The reasons for
               the current VPN gateway lifecycle_state (if any):
               - `resource_suspended_by_provider`: The resource has been suspended
               (contact IBM
                 support)
               The enumerated reason code values for this property will expand in the
               future. When processing this property, check for and log unknown values.
               Optionally halt processing and surface the error, or bypass the resource on
               which the unexpected reason code was encountered.
        :param str lifecycle_state: The lifecycle state of the VPN gateway.
        :param List[VPNGatewayMember] members: Collection of VPN gateway members.
        :param str name: The name for this VPN gateway. The name is unique across
               all VPN gateways in the VPC.
        :param ResourceGroupReference resource_group: The resource group for this
               VPN gateway.
        :param str resource_type: The resource type.
        :param SubnetReference subnet:
        :param VPCReference vpc: The VPC this VPN gateway resides in.
        :param str mode: Route mode VPN gateway.
        """
        # pylint: disable=super-init-not-called
        self.connections = connections
        self.created_at = created_at
        self.crn = crn
        self.health_reasons = health_reasons
        self.health_state = health_state
        self.href = href
        self.id = id
        self.lifecycle_reasons = lifecycle_reasons
        self.lifecycle_state = lifecycle_state
        self.members = members
        self.name = name
        self.resource_group = resource_group
        self.resource_type = resource_type
        self.subnet = subnet
        self.vpc = vpc
        self.mode = mode

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPNGatewayRouteMode':
        """Initialize a VPNGatewayRouteMode object from a json dictionary."""
        args = {}
        if 'connections' in _dict:
            args['connections'] = [VPNGatewayConnectionReference.from_dict(v) for v in _dict.get('connections')]
        else:
            raise ValueError('Required property \'connections\' not present in VPNGatewayRouteMode JSON')
        if 'created_at' in _dict:
            args['created_at'] = string_to_datetime(_dict.get('created_at'))
        else:
            raise ValueError('Required property \'created_at\' not present in VPNGatewayRouteMode JSON')
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError('Required property \'crn\' not present in VPNGatewayRouteMode JSON')
        if 'health_reasons' in _dict:
            args['health_reasons'] = [VPNGatewayHealthReason.from_dict(v) for v in _dict.get('health_reasons')]
        else:
            raise ValueError('Required property \'health_reasons\' not present in VPNGatewayRouteMode JSON')
        if 'health_state' in _dict:
            args['health_state'] = _dict.get('health_state')
        else:
            raise ValueError('Required property \'health_state\' not present in VPNGatewayRouteMode JSON')
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in VPNGatewayRouteMode JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in VPNGatewayRouteMode JSON')
        if 'lifecycle_reasons' in _dict:
            args['lifecycle_reasons'] = [VPNGatewayLifecycleReason.from_dict(v) for v in _dict.get('lifecycle_reasons')]
        else:
            raise ValueError('Required property \'lifecycle_reasons\' not present in VPNGatewayRouteMode JSON')
        if 'lifecycle_state' in _dict:
            args['lifecycle_state'] = _dict.get('lifecycle_state')
        else:
            raise ValueError('Required property \'lifecycle_state\' not present in VPNGatewayRouteMode JSON')
        if 'members' in _dict:
            args['members'] = [VPNGatewayMember.from_dict(v) for v in _dict.get('members')]
        else:
            raise ValueError('Required property \'members\' not present in VPNGatewayRouteMode JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in VPNGatewayRouteMode JSON')
        if 'resource_group' in _dict:
            args['resource_group'] = ResourceGroupReference.from_dict(_dict.get('resource_group'))
        else:
            raise ValueError('Required property \'resource_group\' not present in VPNGatewayRouteMode JSON')
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError('Required property \'resource_type\' not present in VPNGatewayRouteMode JSON')
        if 'subnet' in _dict:
            args['subnet'] = SubnetReference.from_dict(_dict.get('subnet'))
        else:
            raise ValueError('Required property \'subnet\' not present in VPNGatewayRouteMode JSON')
        if 'vpc' in _dict:
            args['vpc'] = VPCReference.from_dict(_dict.get('vpc'))
        else:
            raise ValueError('Required property \'vpc\' not present in VPNGatewayRouteMode JSON')
        if 'mode' in _dict:
            args['mode'] = _dict.get('mode')
        else:
            raise ValueError('Required property \'mode\' not present in VPNGatewayRouteMode JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPNGatewayRouteMode object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'connections') and self.connections is not None:
            connections_list = []
            for v in self.connections:
                if isinstance(v, dict):
                    connections_list.append(v)
                else:
                    connections_list.append(v.to_dict())
            _dict['connections'] = connections_list
        if hasattr(self, 'created_at') and self.created_at is not None:
            _dict['created_at'] = datetime_to_string(self.created_at)
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'health_reasons') and self.health_reasons is not None:
            health_reasons_list = []
            for v in self.health_reasons:
                if isinstance(v, dict):
                    health_reasons_list.append(v)
                else:
                    health_reasons_list.append(v.to_dict())
            _dict['health_reasons'] = health_reasons_list
        if hasattr(self, 'health_state') and self.health_state is not None:
            _dict['health_state'] = self.health_state
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'lifecycle_reasons') and self.lifecycle_reasons is not None:
            lifecycle_reasons_list = []
            for v in self.lifecycle_reasons:
                if isinstance(v, dict):
                    lifecycle_reasons_list.append(v)
                else:
                    lifecycle_reasons_list.append(v.to_dict())
            _dict['lifecycle_reasons'] = lifecycle_reasons_list
        if hasattr(self, 'lifecycle_state') and self.lifecycle_state is not None:
            _dict['lifecycle_state'] = self.lifecycle_state
        if hasattr(self, 'members') and self.members is not None:
            members_list = []
            for v in self.members:
                if isinstance(v, dict):
                    members_list.append(v)
                else:
                    members_list.append(v.to_dict())
            _dict['members'] = members_list
        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, '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:
            if isinstance(self.subnet, dict):
                _dict['subnet'] = self.subnet
            else:
                _dict['subnet'] = self.subnet.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, 'mode') and self.mode is not None:
            _dict['mode'] = self.mode
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VPNGatewayRouteMode object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPNGatewayRouteMode') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPNGatewayRouteMode') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class HealthStateEnum(str, Enum):
        """
        The health of this resource.
        - `ok`: No abnormal behavior detected
        - `degraded`: Experiencing compromised performance, capacity, or connectivity
        - `faulted`: Completely unreachable, inoperative, or otherwise entirely
        incapacitated
        - `inapplicable`: The health state does not apply because of the current lifecycle
        state. A resource with a lifecycle state of `failed` or `deleting` will have a
        health state of `inapplicable`. A `pending` resource may also have this state.
        """

        DEGRADED = 'degraded'
        FAULTED = 'faulted'
        INAPPLICABLE = 'inapplicable'
        OK = 'ok'


    class LifecycleStateEnum(str, Enum):
        """
        The lifecycle state of the VPN gateway.
        """

        DELETING = 'deleting'
        FAILED = 'failed'
        PENDING = 'pending'
        STABLE = 'stable'
        SUSPENDED = 'suspended'
        UPDATING = 'updating'
        WAITING = 'waiting'


    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        VPN_GATEWAY = 'vpn_gateway'


    class ModeEnum(str, Enum):
        """
        Route mode VPN gateway.
        """

        ROUTE = 'route'



class VPNServerAuthenticationByCertificate(VPNServerAuthentication):
    """
    VPNServerAuthenticationByCertificate.

    :attr str method: The type of authentication.
    :attr CertificateInstanceReference client_ca: The certificate instance used for
          the VPN client certificate authority (CA).
    :attr str crl: (optional) The certificate revocation list contents, encoded in
          PEM format.
    """

    def __init__(
        self,
        method: str,
        client_ca: 'CertificateInstanceReference',
        *,
        crl: str = None,
    ) -> None:
        """
        Initialize a VPNServerAuthenticationByCertificate object.

        :param str method: The type of authentication.
        :param CertificateInstanceReference client_ca: The certificate instance
               used for the VPN client certificate authority (CA).
        :param str crl: (optional) The certificate revocation list contents,
               encoded in PEM format.
        """
        # pylint: disable=super-init-not-called
        self.method = method
        self.client_ca = client_ca
        self.crl = crl

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPNServerAuthenticationByCertificate':
        """Initialize a VPNServerAuthenticationByCertificate object from a json dictionary."""
        args = {}
        if 'method' in _dict:
            args['method'] = _dict.get('method')
        else:
            raise ValueError('Required property \'method\' not present in VPNServerAuthenticationByCertificate JSON')
        if 'client_ca' in _dict:
            args['client_ca'] = CertificateInstanceReference.from_dict(_dict.get('client_ca'))
        else:
            raise ValueError('Required property \'client_ca\' not present in VPNServerAuthenticationByCertificate JSON')
        if 'crl' in _dict:
            args['crl'] = _dict.get('crl')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPNServerAuthenticationByCertificate object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'method') and self.method is not None:
            _dict['method'] = self.method
        if hasattr(self, 'client_ca') and self.client_ca is not None:
            if isinstance(self.client_ca, dict):
                _dict['client_ca'] = self.client_ca
            else:
                _dict['client_ca'] = self.client_ca.to_dict()
        if hasattr(self, 'crl') and self.crl is not None:
            _dict['crl'] = self.crl
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VPNServerAuthenticationByCertificate object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPNServerAuthenticationByCertificate') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPNServerAuthenticationByCertificate') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class MethodEnum(str, Enum):
        """
        The type of authentication.
        """

        CERTIFICATE = 'certificate'
        USERNAME = 'username'



class VPNServerAuthenticationByUsername(VPNServerAuthentication):
    """
    VPNServerAuthenticationByUsername.

    :attr str method: The type of authentication.
    :attr VPNServerAuthenticationByUsernameIdProvider identity_provider: The type of
          identity provider to be used by VPN client.
    """

    def __init__(
        self,
        method: str,
        identity_provider: 'VPNServerAuthenticationByUsernameIdProvider',
    ) -> None:
        """
        Initialize a VPNServerAuthenticationByUsername object.

        :param str method: The type of authentication.
        :param VPNServerAuthenticationByUsernameIdProvider identity_provider: The
               type of identity provider to be used by VPN client.
        """
        # pylint: disable=super-init-not-called
        self.method = method
        self.identity_provider = identity_provider

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPNServerAuthenticationByUsername':
        """Initialize a VPNServerAuthenticationByUsername object from a json dictionary."""
        args = {}
        if 'method' in _dict:
            args['method'] = _dict.get('method')
        else:
            raise ValueError('Required property \'method\' not present in VPNServerAuthenticationByUsername JSON')
        if 'identity_provider' in _dict:
            args['identity_provider'] = _dict.get('identity_provider')
        else:
            raise ValueError('Required property \'identity_provider\' not present in VPNServerAuthenticationByUsername JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPNServerAuthenticationByUsername object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'method') and self.method is not None:
            _dict['method'] = self.method
        if hasattr(self, 'identity_provider') and self.identity_provider is not None:
            if isinstance(self.identity_provider, dict):
                _dict['identity_provider'] = self.identity_provider
            else:
                _dict['identity_provider'] = self.identity_provider.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 VPNServerAuthenticationByUsername object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPNServerAuthenticationByUsername') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPNServerAuthenticationByUsername') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class MethodEnum(str, Enum):
        """
        The type of authentication.
        """

        CERTIFICATE = 'certificate'
        USERNAME = 'username'



class VPNServerAuthenticationByUsernameIdProviderByIAM(VPNServerAuthenticationByUsernameIdProvider):
    """
    VPNServerAuthenticationByUsernameIdProviderByIAM.

    :attr str provider_type: The type of identity provider to be used by the VPN
          client.
          - `iam`: IBM identity and access management
          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 route on which the unexpected
          property value was encountered.
    """

    def __init__(
        self,
        provider_type: str,
    ) -> None:
        """
        Initialize a VPNServerAuthenticationByUsernameIdProviderByIAM object.

        :param str provider_type: The type of identity provider to be used by the
               VPN client.
               - `iam`: IBM identity and access management
               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 route on
               which the unexpected property value was encountered.
        """
        # pylint: disable=super-init-not-called
        self.provider_type = provider_type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPNServerAuthenticationByUsernameIdProviderByIAM':
        """Initialize a VPNServerAuthenticationByUsernameIdProviderByIAM object from a json dictionary."""
        args = {}
        if 'provider_type' in _dict:
            args['provider_type'] = _dict.get('provider_type')
        else:
            raise ValueError('Required property \'provider_type\' not present in VPNServerAuthenticationByUsernameIdProviderByIAM JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPNServerAuthenticationByUsernameIdProviderByIAM object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'provider_type') and self.provider_type is not None:
            _dict['provider_type'] = self.provider_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 VPNServerAuthenticationByUsernameIdProviderByIAM object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPNServerAuthenticationByUsernameIdProviderByIAM') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPNServerAuthenticationByUsernameIdProviderByIAM') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ProviderTypeEnum(str, Enum):
        """
        The type of identity provider to be used by the VPN client.
        - `iam`: IBM identity and access management
        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 route on which the unexpected
        property value was encountered.
        """

        IAM = 'iam'



class VPNServerAuthenticationPrototypeVPNServerAuthenticationByCertificatePrototype(VPNServerAuthenticationPrototype):
    """
    VPNServerAuthenticationPrototypeVPNServerAuthenticationByCertificatePrototype.

    :attr str method: The type of authentication.
    :attr CertificateInstanceIdentity client_ca: The certificate instance to use for
          the VPN client certificate authority (CA).
    :attr str crl: (optional) The certificate revocation list contents, encoded in
          PEM format.
    """

    def __init__(
        self,
        method: str,
        client_ca: 'CertificateInstanceIdentity',
        *,
        crl: str = None,
    ) -> None:
        """
        Initialize a VPNServerAuthenticationPrototypeVPNServerAuthenticationByCertificatePrototype object.

        :param str method: The type of authentication.
        :param CertificateInstanceIdentity client_ca: The certificate instance to
               use for the VPN client certificate authority (CA).
        :param str crl: (optional) The certificate revocation list contents,
               encoded in PEM format.
        """
        # pylint: disable=super-init-not-called
        self.method = method
        self.client_ca = client_ca
        self.crl = crl

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPNServerAuthenticationPrototypeVPNServerAuthenticationByCertificatePrototype':
        """Initialize a VPNServerAuthenticationPrototypeVPNServerAuthenticationByCertificatePrototype object from a json dictionary."""
        args = {}
        if 'method' in _dict:
            args['method'] = _dict.get('method')
        else:
            raise ValueError('Required property \'method\' not present in VPNServerAuthenticationPrototypeVPNServerAuthenticationByCertificatePrototype JSON')
        if 'client_ca' in _dict:
            args['client_ca'] = _dict.get('client_ca')
        else:
            raise ValueError('Required property \'client_ca\' not present in VPNServerAuthenticationPrototypeVPNServerAuthenticationByCertificatePrototype JSON')
        if 'crl' in _dict:
            args['crl'] = _dict.get('crl')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPNServerAuthenticationPrototypeVPNServerAuthenticationByCertificatePrototype object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'method') and self.method is not None:
            _dict['method'] = self.method
        if hasattr(self, 'client_ca') and self.client_ca is not None:
            if isinstance(self.client_ca, dict):
                _dict['client_ca'] = self.client_ca
            else:
                _dict['client_ca'] = self.client_ca.to_dict()
        if hasattr(self, 'crl') and self.crl is not None:
            _dict['crl'] = self.crl
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VPNServerAuthenticationPrototypeVPNServerAuthenticationByCertificatePrototype object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPNServerAuthenticationPrototypeVPNServerAuthenticationByCertificatePrototype') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPNServerAuthenticationPrototypeVPNServerAuthenticationByCertificatePrototype') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class MethodEnum(str, Enum):
        """
        The type of authentication.
        """

        CERTIFICATE = 'certificate'
        USERNAME = 'username'



class VPNServerAuthenticationPrototypeVPNServerAuthenticationByUsernamePrototype(VPNServerAuthenticationPrototype):
    """
    VPNServerAuthenticationPrototypeVPNServerAuthenticationByUsernamePrototype.

    :attr str method: The type of authentication.
    :attr VPNServerAuthenticationByUsernameIdProvider identity_provider: The type of
          identity provider to be used by VPN client.
    """

    def __init__(
        self,
        method: str,
        identity_provider: 'VPNServerAuthenticationByUsernameIdProvider',
    ) -> None:
        """
        Initialize a VPNServerAuthenticationPrototypeVPNServerAuthenticationByUsernamePrototype object.

        :param str method: The type of authentication.
        :param VPNServerAuthenticationByUsernameIdProvider identity_provider: The
               type of identity provider to be used by VPN client.
        """
        # pylint: disable=super-init-not-called
        self.method = method
        self.identity_provider = identity_provider

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPNServerAuthenticationPrototypeVPNServerAuthenticationByUsernamePrototype':
        """Initialize a VPNServerAuthenticationPrototypeVPNServerAuthenticationByUsernamePrototype object from a json dictionary."""
        args = {}
        if 'method' in _dict:
            args['method'] = _dict.get('method')
        else:
            raise ValueError('Required property \'method\' not present in VPNServerAuthenticationPrototypeVPNServerAuthenticationByUsernamePrototype JSON')
        if 'identity_provider' in _dict:
            args['identity_provider'] = _dict.get('identity_provider')
        else:
            raise ValueError('Required property \'identity_provider\' not present in VPNServerAuthenticationPrototypeVPNServerAuthenticationByUsernamePrototype JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPNServerAuthenticationPrototypeVPNServerAuthenticationByUsernamePrototype object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'method') and self.method is not None:
            _dict['method'] = self.method
        if hasattr(self, 'identity_provider') and self.identity_provider is not None:
            if isinstance(self.identity_provider, dict):
                _dict['identity_provider'] = self.identity_provider
            else:
                _dict['identity_provider'] = self.identity_provider.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 VPNServerAuthenticationPrototypeVPNServerAuthenticationByUsernamePrototype object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPNServerAuthenticationPrototypeVPNServerAuthenticationByUsernamePrototype') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPNServerAuthenticationPrototypeVPNServerAuthenticationByUsernamePrototype') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class MethodEnum(str, Enum):
        """
        The type of authentication.
        """

        CERTIFICATE = 'certificate'
        USERNAME = 'username'



class VirtualNetworkInterfacePrimaryIPPrototypeReservedIPIdentityVirtualNetworkInterfacePrimaryIPContext(VirtualNetworkInterfacePrimaryIPPrototype):
    """
    Identifies a reserved IP by a unique property. Required if `subnet` is not specified.
    The reserved IP must be currently unbound.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a VirtualNetworkInterfacePrimaryIPPrototypeReservedIPIdentityVirtualNetworkInterfacePrimaryIPContext object.

        """
        # pylint: disable=super-init-not-called
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['VirtualNetworkInterfacePrimaryIPPrototypeReservedIPIdentityVirtualNetworkInterfacePrimaryIPContextById', 'VirtualNetworkInterfacePrimaryIPPrototypeReservedIPIdentityVirtualNetworkInterfacePrimaryIPContextByHref'])
        )
        raise Exception(msg)


class VirtualNetworkInterfacePrimaryIPPrototypeReservedIPPrototypeVirtualNetworkInterfacePrimaryIPContext(VirtualNetworkInterfacePrimaryIPPrototype):
    """
    The prototype for a new reserved IP. Requires `subnet` to be specified.

    :attr str address: (optional) The IP address to reserve, which must not already
          be reserved on the subnet.
          If unspecified, an available address on the subnet will automatically be
          selected.
    :attr bool auto_delete: (optional) Indicates whether this reserved IP member
          will be automatically deleted when either
          `target` is deleted, or the reserved IP is unbound.
    :attr str name: (optional) The name for this reserved IP. The name must not be
          used by another reserved IP in the subnet. Names starting with `ibm-` are
          reserved for provider-owned resources, and are not allowed. If unspecified, the
          name will be a hyphenated list of randomly-selected words.
    """

    def __init__(
        self,
        *,
        address: str = None,
        auto_delete: bool = None,
        name: str = None,
    ) -> None:
        """
        Initialize a VirtualNetworkInterfacePrimaryIPPrototypeReservedIPPrototypeVirtualNetworkInterfacePrimaryIPContext object.

        :param str address: (optional) The IP address to reserve, which must not
               already be reserved on the subnet.
               If unspecified, an available address on the subnet will automatically be
               selected.
        :param bool auto_delete: (optional) Indicates whether this reserved IP
               member will be automatically deleted when either
               `target` is deleted, or the reserved IP is unbound.
        :param str name: (optional) The name for this reserved IP. The name must
               not be used by another reserved IP in the subnet. Names starting with
               `ibm-` are reserved for provider-owned resources, and are not allowed. If
               unspecified, the name will be a hyphenated list of randomly-selected words.
        """
        # pylint: disable=super-init-not-called
        self.address = address
        self.auto_delete = auto_delete
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VirtualNetworkInterfacePrimaryIPPrototypeReservedIPPrototypeVirtualNetworkInterfacePrimaryIPContext':
        """Initialize a VirtualNetworkInterfacePrimaryIPPrototypeReservedIPPrototypeVirtualNetworkInterfacePrimaryIPContext object from a json dictionary."""
        args = {}
        if 'address' in _dict:
            args['address'] = _dict.get('address')
        if 'auto_delete' in _dict:
            args['auto_delete'] = _dict.get('auto_delete')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VirtualNetworkInterfacePrimaryIPPrototypeReservedIPPrototypeVirtualNetworkInterfacePrimaryIPContext object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'address') and self.address is not None:
            _dict['address'] = self.address
        if hasattr(self, 'auto_delete') and self.auto_delete is not None:
            _dict['auto_delete'] = self.auto_delete
        if hasattr(self, '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 VirtualNetworkInterfacePrimaryIPPrototypeReservedIPPrototypeVirtualNetworkInterfacePrimaryIPContext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VirtualNetworkInterfacePrimaryIPPrototypeReservedIPPrototypeVirtualNetworkInterfacePrimaryIPContext') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VirtualNetworkInterfacePrimaryIPPrototypeReservedIPPrototypeVirtualNetworkInterfacePrimaryIPContext') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VirtualNetworkInterfaceTargetShareMountTargetReference(VirtualNetworkInterfaceTarget):
    """
    VirtualNetworkInterfaceTargetShareMountTargetReference.

    :attr ShareMountTargetReferenceDeleted deleted: (optional) If present, this
          property indicates the referenced resource has been deleted, and provides
          some supplementary information.
    :attr str href: The URL for this share mount target.
    :attr str id: The unique identifier for this share mount target.
    :attr str name: The name for this share mount target. The name is unique across
          all mount targets for the file share.
    :attr str resource_type: The resource type.
    """

    def __init__(
        self,
        href: str,
        id: str,
        name: str,
        resource_type: str,
        *,
        deleted: 'ShareMountTargetReferenceDeleted' = None,
    ) -> None:
        """
        Initialize a VirtualNetworkInterfaceTargetShareMountTargetReference object.

        :param str href: The URL for this share mount target.
        :param str id: The unique identifier for this share mount target.
        :param str name: The name for this share mount target. The name is unique
               across all mount targets for the file share.
        :param str resource_type: The resource type.
        :param ShareMountTargetReferenceDeleted deleted: (optional) If present,
               this property indicates the referenced resource has been deleted, and
               provides
               some supplementary information.
        """
        # pylint: disable=super-init-not-called
        self.deleted = deleted
        self.href = href
        self.id = id
        self.name = name
        self.resource_type = resource_type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VirtualNetworkInterfaceTargetShareMountTargetReference':
        """Initialize a VirtualNetworkInterfaceTargetShareMountTargetReference object from a json dictionary."""
        args = {}
        if 'deleted' in _dict:
            args['deleted'] = ShareMountTargetReferenceDeleted.from_dict(_dict.get('deleted'))
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in VirtualNetworkInterfaceTargetShareMountTargetReference JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in VirtualNetworkInterfaceTargetShareMountTargetReference JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in VirtualNetworkInterfaceTargetShareMountTargetReference JSON')
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError('Required property \'resource_type\' not present in VirtualNetworkInterfaceTargetShareMountTargetReference JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VirtualNetworkInterfaceTargetShareMountTargetReference object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'deleted') and self.deleted is not None:
            if isinstance(self.deleted, dict):
                _dict['deleted'] = self.deleted
            else:
                _dict['deleted'] = self.deleted.to_dict()
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'resource_type') and self.resource_type is not None:
            _dict['resource_type'] = self.resource_type
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VirtualNetworkInterfaceTargetShareMountTargetReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VirtualNetworkInterfaceTargetShareMountTargetReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VirtualNetworkInterfaceTargetShareMountTargetReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        SHARE_MOUNT_TARGET = 'share_mount_target'



class VolumeAttachmentPrototypeVolumeVolumeIdentity(VolumeAttachmentPrototypeVolume):
    """
    Identifies a volume by a unique property.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a VolumeAttachmentPrototypeVolumeVolumeIdentity object.

        """
        # pylint: disable=super-init-not-called
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['VolumeAttachmentPrototypeVolumeVolumeIdentityVolumeIdentityById', 'VolumeAttachmentPrototypeVolumeVolumeIdentityVolumeIdentityByCRN', 'VolumeAttachmentPrototypeVolumeVolumeIdentityVolumeIdentityByHref'])
        )
        raise Exception(msg)


class VolumeAttachmentPrototypeVolumeVolumePrototypeInstanceContext(VolumeAttachmentPrototypeVolume):
    """
    VolumeAttachmentPrototypeVolumeVolumePrototypeInstanceContext.

    :attr int iops: (optional) The maximum I/O operations per second (IOPS) to use
          for this volume. Applicable only to volumes using a profile `family` of
          `custom`.
    :attr str name: (optional) The name for this volume. The name must not be used
          by another volume in the region. If unspecified, the name will be a hyphenated
          list of randomly-selected words.
    :attr VolumeProfileIdentity profile: The
          [profile](https://cloud.ibm.com/docs/vpc?topic=vpc-block-storage-profiles) to
          use for this volume.
    :attr ResourceGroupIdentity resource_group: (optional) The resource group to use
          for this volume. If unspecified, the instance's resource
          group will be used.
    :attr List[str] user_tags: (optional) The [user
          tags](https://cloud.ibm.com/apidocs/tagging#types-of-tags) associated with this
          volume.
    """

    def __init__(
        self,
        profile: 'VolumeProfileIdentity',
        *,
        iops: int = None,
        name: str = None,
        resource_group: 'ResourceGroupIdentity' = None,
        user_tags: List[str] = None,
    ) -> None:
        """
        Initialize a VolumeAttachmentPrototypeVolumeVolumePrototypeInstanceContext object.

        :param VolumeProfileIdentity profile: The
               [profile](https://cloud.ibm.com/docs/vpc?topic=vpc-block-storage-profiles)
               to
               use for this volume.
        :param int iops: (optional) The maximum I/O operations per second (IOPS) to
               use for this volume. Applicable only to volumes using a profile `family` of
               `custom`.
        :param str name: (optional) The name for this volume. The name must not be
               used by another volume in the region. If unspecified, the name will be a
               hyphenated list of randomly-selected words.
        :param ResourceGroupIdentity resource_group: (optional) The resource group
               to use for this volume. If unspecified, the instance's resource
               group will be used.
        :param List[str] user_tags: (optional) The [user
               tags](https://cloud.ibm.com/apidocs/tagging#types-of-tags) associated with
               this volume.
        """
        # pylint: disable=super-init-not-called
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['VolumeAttachmentPrototypeVolumeVolumePrototypeInstanceContextVolumePrototypeInstanceContextVolumeByCapacity', 'VolumeAttachmentPrototypeVolumeVolumePrototypeInstanceContextVolumePrototypeInstanceContextVolumeBySourceSnapshot'])
        )
        raise Exception(msg)


class VolumeIdentityByCRN(VolumeIdentity):
    """
    VolumeIdentityByCRN.

    :attr str crn: The CRN for this volume.
    """

    def __init__(
        self,
        crn: str,
    ) -> None:
        """
        Initialize a VolumeIdentityByCRN object.

        :param str crn: The CRN for this volume.
        """
        # pylint: disable=super-init-not-called
        self.crn = crn

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VolumeIdentityByCRN':
        """Initialize a VolumeIdentityByCRN object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError('Required property \'crn\' not present in VolumeIdentityByCRN JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VolumeIdentityByCRN object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VolumeIdentityByCRN object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VolumeIdentityByCRN') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VolumeIdentityByCRN') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VolumeIdentityByHref(VolumeIdentity):
    """
    VolumeIdentityByHref.

    :attr str href: The URL for this volume.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a VolumeIdentityByHref object.

        :param str href: The URL for this volume.
        """
        # pylint: disable=super-init-not-called
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VolumeIdentityByHref':
        """Initialize a VolumeIdentityByHref object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in VolumeIdentityByHref JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VolumeIdentityByHref object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VolumeIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VolumeIdentityByHref') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VolumeIdentityByHref') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VolumeIdentityById(VolumeIdentity):
    """
    VolumeIdentityById.

    :attr str id: The unique identifier for this volume.
    """

    def __init__(
        self,
        id: str,
    ) -> None:
        """
        Initialize a VolumeIdentityById object.

        :param str id: The unique identifier for this volume.
        """
        # pylint: disable=super-init-not-called
        self.id = id

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VolumeIdentityById':
        """Initialize a VolumeIdentityById object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in VolumeIdentityById JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VolumeIdentityById object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VolumeIdentityById object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VolumeIdentityById') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VolumeIdentityById') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VolumeProfileIdentityByHref(VolumeProfileIdentity):
    """
    VolumeProfileIdentityByHref.

    :attr str href: The URL for this volume profile.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a VolumeProfileIdentityByHref object.

        :param str href: The URL for this volume profile.
        """
        # pylint: disable=super-init-not-called
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VolumeProfileIdentityByHref':
        """Initialize a VolumeProfileIdentityByHref object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in VolumeProfileIdentityByHref JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VolumeProfileIdentityByHref object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VolumeProfileIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VolumeProfileIdentityByHref') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VolumeProfileIdentityByHref') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VolumeProfileIdentityByName(VolumeProfileIdentity):
    """
    VolumeProfileIdentityByName.

    :attr str name: The globally unique name for this volume profile.
    """

    def __init__(
        self,
        name: str,
    ) -> None:
        """
        Initialize a VolumeProfileIdentityByName object.

        :param str name: The globally unique name for this volume profile.
        """
        # pylint: disable=super-init-not-called
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VolumeProfileIdentityByName':
        """Initialize a VolumeProfileIdentityByName object from a json dictionary."""
        args = {}
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in VolumeProfileIdentityByName JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VolumeProfileIdentityByName object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VolumeProfileIdentityByName object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VolumeProfileIdentityByName') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VolumeProfileIdentityByName') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VolumePrototypeVolumeByCapacity(VolumePrototype):
    """
    VolumePrototypeVolumeByCapacity.

    :attr int iops: (optional) The maximum I/O operations per second (IOPS) to use
          for this volume. Applicable only to volumes using a profile `family` of
          `custom`.
    :attr str name: (optional) The name for this volume. The name must not be used
          by another volume in the region. If unspecified, the name will be a hyphenated
          list of randomly-selected words.
    :attr VolumeProfileIdentity profile: The
          [profile](https://cloud.ibm.com/docs/vpc?topic=vpc-block-storage-profiles) to
          use for this volume.
    :attr ResourceGroupIdentity resource_group: (optional)
    :attr List[str] user_tags: (optional) The [user
          tags](https://cloud.ibm.com/apidocs/tagging#types-of-tags) associated with this
          volume.
    :attr ZoneIdentity zone: The zone this volume will reside in.
    :attr int capacity: The capacity to use for 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 root key to use to
          wrap the data encryption key for the volume.
          If unspecified, the `encryption` type for the volume will be `provider_managed`.
    """

    def __init__(
        self,
        profile: 'VolumeProfileIdentity',
        zone: 'ZoneIdentity',
        capacity: int,
        *,
        iops: int = None,
        name: str = None,
        resource_group: 'ResourceGroupIdentity' = None,
        user_tags: List[str] = None,
        encryption_key: 'EncryptionKeyIdentity' = None,
    ) -> None:
        """
        Initialize a VolumePrototypeVolumeByCapacity object.

        :param VolumeProfileIdentity profile: The
               [profile](https://cloud.ibm.com/docs/vpc?topic=vpc-block-storage-profiles)
               to use for this volume.
        :param ZoneIdentity zone: The zone this volume will reside in.
        :param int capacity: The capacity to use for the volume (in gigabytes). The
               specified minimum and maximum capacity values for creating or updating
               volumes may expand in the future.
        :param int iops: (optional) The maximum I/O operations per second (IOPS) to
               use for this volume. Applicable only to volumes using a profile `family` of
               `custom`.
        :param str name: (optional) The name for this volume. The name must not be
               used by another volume in the region. If unspecified, the name will be a
               hyphenated list of randomly-selected words.
        :param ResourceGroupIdentity resource_group: (optional)
        :param List[str] user_tags: (optional) The [user
               tags](https://cloud.ibm.com/apidocs/tagging#types-of-tags) associated with
               this volume.
        :param EncryptionKeyIdentity encryption_key: (optional) The root key to use
               to wrap the data encryption key for the volume.
               If unspecified, the `encryption` type for the volume will be
               `provider_managed`.
        """
        # pylint: disable=super-init-not-called
        self.iops = iops
        self.name = name
        self.profile = profile
        self.resource_group = resource_group
        self.user_tags = user_tags
        self.zone = zone
        self.capacity = capacity
        self.encryption_key = encryption_key

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VolumePrototypeVolumeByCapacity':
        """Initialize a VolumePrototypeVolumeByCapacity object from a json dictionary."""
        args = {}
        if 'iops' in _dict:
            args['iops'] = _dict.get('iops')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        if 'profile' in _dict:
            args['profile'] = _dict.get('profile')
        else:
            raise ValueError('Required property \'profile\' not present in VolumePrototypeVolumeByCapacity JSON')
        if 'resource_group' in _dict:
            args['resource_group'] = _dict.get('resource_group')
        if 'user_tags' in _dict:
            args['user_tags'] = _dict.get('user_tags')
        if 'zone' in _dict:
            args['zone'] = _dict.get('zone')
        else:
            raise ValueError('Required property \'zone\' not present in VolumePrototypeVolumeByCapacity JSON')
        if 'capacity' in _dict:
            args['capacity'] = _dict.get('capacity')
        else:
            raise ValueError('Required property \'capacity\' not present in VolumePrototypeVolumeByCapacity JSON')
        if 'encryption_key' in _dict:
            args['encryption_key'] = _dict.get('encryption_key')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VolumePrototypeVolumeByCapacity object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'iops') and self.iops is not None:
            _dict['iops'] = self.iops
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'profile') and self.profile is not None:
            if isinstance(self.profile, dict):
                _dict['profile'] = self.profile
            else:
                _dict['profile'] = self.profile.to_dict()
        if hasattr(self, 'resource_group') and self.resource_group is not None:
            if isinstance(self.resource_group, dict):
                _dict['resource_group'] = self.resource_group
            else:
                _dict['resource_group'] = self.resource_group.to_dict()
        if hasattr(self, 'user_tags') and self.user_tags is not None:
            _dict['user_tags'] = self.user_tags
        if hasattr(self, 'zone') and self.zone is not None:
            if isinstance(self.zone, dict):
                _dict['zone'] = self.zone
            else:
                _dict['zone'] = self.zone.to_dict()
        if hasattr(self, 'capacity') and self.capacity is not None:
            _dict['capacity'] = self.capacity
        if hasattr(self, 'encryption_key') and self.encryption_key is not None:
            if isinstance(self.encryption_key, dict):
                _dict['encryption_key'] = self.encryption_key
            else:
                _dict['encryption_key'] = self.encryption_key.to_dict()
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VolumePrototypeVolumeByCapacity object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VolumePrototypeVolumeByCapacity') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VolumePrototypeVolumeByCapacity') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VolumePrototypeVolumeBySourceSnapshot(VolumePrototype):
    """
    VolumePrototypeVolumeBySourceSnapshot.

    :attr int iops: (optional) The maximum I/O operations per second (IOPS) to use
          for this volume. Applicable only to volumes using a profile `family` of
          `custom`.
    :attr str name: (optional) The name for this volume. The name must not be used
          by another volume in the region. If unspecified, the name will be a hyphenated
          list of randomly-selected words.
    :attr VolumeProfileIdentity profile: The
          [profile](https://cloud.ibm.com/docs/vpc?topic=vpc-block-storage-profiles) to
          use for this volume.
    :attr ResourceGroupIdentity resource_group: (optional)
    :attr List[str] user_tags: (optional) The [user
          tags](https://cloud.ibm.com/apidocs/tagging#types-of-tags) associated with this
          volume.
    :attr ZoneIdentity zone: The zone this volume will reside in.
    :attr int capacity: (optional) The capacity to use for the volume (in
          gigabytes). Must be at least the snapshot's
          `minimum_capacity`. The maximum value may increase in the future.
          If unspecified, the capacity will be the source snapshot's `minimum_capacity`.
    :attr EncryptionKeyIdentity encryption_key: (optional) The root key to use to
          wrap the data encryption key for the volume.
          If unspecified, the `encryption` type for the volume will be `provider_managed`.
    :attr SnapshotIdentity source_snapshot: The snapshot from which to clone the
          volume.
    """

    def __init__(
        self,
        profile: 'VolumeProfileIdentity',
        zone: 'ZoneIdentity',
        source_snapshot: 'SnapshotIdentity',
        *,
        iops: int = None,
        name: str = None,
        resource_group: 'ResourceGroupIdentity' = None,
        user_tags: List[str] = None,
        capacity: int = None,
        encryption_key: 'EncryptionKeyIdentity' = None,
    ) -> None:
        """
        Initialize a VolumePrototypeVolumeBySourceSnapshot object.

        :param VolumeProfileIdentity profile: The
               [profile](https://cloud.ibm.com/docs/vpc?topic=vpc-block-storage-profiles)
               to use for this volume.
        :param ZoneIdentity zone: The zone this volume will reside in.
        :param SnapshotIdentity source_snapshot: The snapshot from which to clone
               the volume.
        :param int iops: (optional) The maximum I/O operations per second (IOPS) to
               use for this volume. Applicable only to volumes using a profile `family` of
               `custom`.
        :param str name: (optional) The name for this volume. The name must not be
               used by another volume in the region. If unspecified, the name will be a
               hyphenated list of randomly-selected words.
        :param ResourceGroupIdentity resource_group: (optional)
        :param List[str] user_tags: (optional) The [user
               tags](https://cloud.ibm.com/apidocs/tagging#types-of-tags) associated with
               this volume.
        :param int capacity: (optional) The capacity to use for the volume (in
               gigabytes). Must be at least the snapshot's
               `minimum_capacity`. The maximum value may increase in the future.
               If unspecified, the capacity will be the source snapshot's
               `minimum_capacity`.
        :param EncryptionKeyIdentity encryption_key: (optional) The root key to use
               to wrap the data encryption key for the volume.
               If unspecified, the `encryption` type for the volume will be
               `provider_managed`.
        """
        # pylint: disable=super-init-not-called
        self.iops = iops
        self.name = name
        self.profile = profile
        self.resource_group = resource_group
        self.user_tags = user_tags
        self.zone = zone
        self.capacity = capacity
        self.encryption_key = encryption_key
        self.source_snapshot = source_snapshot

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VolumePrototypeVolumeBySourceSnapshot':
        """Initialize a VolumePrototypeVolumeBySourceSnapshot object from a json dictionary."""
        args = {}
        if 'iops' in _dict:
            args['iops'] = _dict.get('iops')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        if 'profile' in _dict:
            args['profile'] = _dict.get('profile')
        else:
            raise ValueError('Required property \'profile\' not present in VolumePrototypeVolumeBySourceSnapshot JSON')
        if 'resource_group' in _dict:
            args['resource_group'] = _dict.get('resource_group')
        if 'user_tags' in _dict:
            args['user_tags'] = _dict.get('user_tags')
        if 'zone' in _dict:
            args['zone'] = _dict.get('zone')
        else:
            raise ValueError('Required property \'zone\' not present in VolumePrototypeVolumeBySourceSnapshot JSON')
        if 'capacity' in _dict:
            args['capacity'] = _dict.get('capacity')
        if 'encryption_key' in _dict:
            args['encryption_key'] = _dict.get('encryption_key')
        if 'source_snapshot' in _dict:
            args['source_snapshot'] = _dict.get('source_snapshot')
        else:
            raise ValueError('Required property \'source_snapshot\' not present in VolumePrototypeVolumeBySourceSnapshot JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VolumePrototypeVolumeBySourceSnapshot object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'iops') and self.iops is not None:
            _dict['iops'] = self.iops
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'profile') and self.profile is not None:
            if isinstance(self.profile, dict):
                _dict['profile'] = self.profile
            else:
                _dict['profile'] = self.profile.to_dict()
        if hasattr(self, 'resource_group') and self.resource_group is not None:
            if isinstance(self.resource_group, dict):
                _dict['resource_group'] = self.resource_group
            else:
                _dict['resource_group'] = self.resource_group.to_dict()
        if hasattr(self, 'user_tags') and self.user_tags is not None:
            _dict['user_tags'] = self.user_tags
        if hasattr(self, 'zone') and self.zone is not None:
            if isinstance(self.zone, dict):
                _dict['zone'] = self.zone
            else:
                _dict['zone'] = self.zone.to_dict()
        if hasattr(self, 'capacity') and self.capacity is not None:
            _dict['capacity'] = self.capacity
        if hasattr(self, 'encryption_key') and self.encryption_key is not None:
            if isinstance(self.encryption_key, dict):
                _dict['encryption_key'] = self.encryption_key
            else:
                _dict['encryption_key'] = self.encryption_key.to_dict()
        if hasattr(self, 'source_snapshot') and self.source_snapshot is not None:
            if isinstance(self.source_snapshot, dict):
                _dict['source_snapshot'] = self.source_snapshot
            else:
                _dict['source_snapshot'] = self.source_snapshot.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 VolumePrototypeVolumeBySourceSnapshot object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VolumePrototypeVolumeBySourceSnapshot') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VolumePrototypeVolumeBySourceSnapshot') -> 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 BackupPolicyScopePrototypeEnterpriseIdentityEnterpriseIdentityByCRN(BackupPolicyScopePrototypeEnterpriseIdentity):
    """
    BackupPolicyScopePrototypeEnterpriseIdentityEnterpriseIdentityByCRN.

    :attr str crn: The CRN for this enterprise.
    """

    def __init__(
        self,
        crn: str,
    ) -> None:
        """
        Initialize a BackupPolicyScopePrototypeEnterpriseIdentityEnterpriseIdentityByCRN object.

        :param str crn: The CRN for this enterprise.
        """
        # pylint: disable=super-init-not-called
        self.crn = crn

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'BackupPolicyScopePrototypeEnterpriseIdentityEnterpriseIdentityByCRN':
        """Initialize a BackupPolicyScopePrototypeEnterpriseIdentityEnterpriseIdentityByCRN object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError('Required property \'crn\' not present in BackupPolicyScopePrototypeEnterpriseIdentityEnterpriseIdentityByCRN JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a BackupPolicyScopePrototypeEnterpriseIdentityEnterpriseIdentityByCRN object from 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 BackupPolicyScopePrototypeEnterpriseIdentityEnterpriseIdentityByCRN object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'BackupPolicyScopePrototypeEnterpriseIdentityEnterpriseIdentityByCRN') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'BackupPolicyScopePrototypeEnterpriseIdentityEnterpriseIdentityByCRN') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class EndpointGatewayReservedIPReservedIPIdentityByHref(EndpointGatewayReservedIPReservedIPIdentity):
    """
    EndpointGatewayReservedIPReservedIPIdentityByHref.

    :attr str href: The URL for this reserved IP.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a EndpointGatewayReservedIPReservedIPIdentityByHref object.

        :param str href: The URL for this reserved IP.
        """
        # pylint: disable=super-init-not-called
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'EndpointGatewayReservedIPReservedIPIdentityByHref':
        """Initialize a EndpointGatewayReservedIPReservedIPIdentityByHref object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in EndpointGatewayReservedIPReservedIPIdentityByHref JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a EndpointGatewayReservedIPReservedIPIdentityByHref object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(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 EndpointGatewayReservedIPReservedIPIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'EndpointGatewayReservedIPReservedIPIdentityByHref') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'EndpointGatewayReservedIPReservedIPIdentityByHref') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class EndpointGatewayReservedIPReservedIPIdentityById(EndpointGatewayReservedIPReservedIPIdentity):
    """
    EndpointGatewayReservedIPReservedIPIdentityById.

    :attr str id: The unique identifier for this reserved IP.
    """

    def __init__(
        self,
        id: str,
    ) -> None:
        """
        Initialize a EndpointGatewayReservedIPReservedIPIdentityById object.

        :param str id: The unique identifier for this reserved IP.
        """
        # pylint: disable=super-init-not-called
        self.id = id

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'EndpointGatewayReservedIPReservedIPIdentityById':
        """Initialize a EndpointGatewayReservedIPReservedIPIdentityById object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in EndpointGatewayReservedIPReservedIPIdentityById JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a EndpointGatewayReservedIPReservedIPIdentityById object from 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 EndpointGatewayReservedIPReservedIPIdentityById object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'EndpointGatewayReservedIPReservedIPIdentityById') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'EndpointGatewayReservedIPReservedIPIdentityById') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class EndpointGatewayTargetPrototypeProviderCloudServiceIdentityProviderCloudServiceIdentityByCRN(EndpointGatewayTargetPrototypeProviderCloudServiceIdentity):
    """
    EndpointGatewayTargetPrototypeProviderCloudServiceIdentityProviderCloudServiceIdentityByCRN.

    :attr str resource_type: The type of target for this endpoint gateway.
    :attr str crn: The CRN for this provider cloud service, or the CRN for the
          user's instance of a provider cloud service.
    """

    def __init__(
        self,
        resource_type: str,
        crn: str,
    ) -> None:
        """
        Initialize a EndpointGatewayTargetPrototypeProviderCloudServiceIdentityProviderCloudServiceIdentityByCRN object.

        :param str resource_type: The type of target for this endpoint gateway.
        :param str crn: The CRN for this provider cloud service, or the CRN for the
               user's instance of a provider cloud service.
        """
        # pylint: disable=super-init-not-called
        self.resource_type = resource_type
        self.crn = crn

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'EndpointGatewayTargetPrototypeProviderCloudServiceIdentityProviderCloudServiceIdentityByCRN':
        """Initialize a EndpointGatewayTargetPrototypeProviderCloudServiceIdentityProviderCloudServiceIdentityByCRN object from a json dictionary."""
        args = {}
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError('Required property \'resource_type\' not present in EndpointGatewayTargetPrototypeProviderCloudServiceIdentityProviderCloudServiceIdentityByCRN JSON')
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError('Required property \'crn\' not present in EndpointGatewayTargetPrototypeProviderCloudServiceIdentityProviderCloudServiceIdentityByCRN JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a EndpointGatewayTargetPrototypeProviderCloudServiceIdentityProviderCloudServiceIdentityByCRN object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'resource_type') and self.resource_type is not None:
            _dict['resource_type'] = self.resource_type
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this EndpointGatewayTargetPrototypeProviderCloudServiceIdentityProviderCloudServiceIdentityByCRN object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'EndpointGatewayTargetPrototypeProviderCloudServiceIdentityProviderCloudServiceIdentityByCRN') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'EndpointGatewayTargetPrototypeProviderCloudServiceIdentityProviderCloudServiceIdentityByCRN') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ResourceTypeEnum(str, Enum):
        """
        The type of target for this endpoint gateway.
        """

        PROVIDER_CLOUD_SERVICE = 'provider_cloud_service'
        PROVIDER_INFRASTRUCTURE_SERVICE = 'provider_infrastructure_service'



class EndpointGatewayTargetPrototypeProviderInfrastructureServiceIdentityProviderInfrastructureServiceIdentityByName(EndpointGatewayTargetPrototypeProviderInfrastructureServiceIdentity):
    """
    The name of this provider infrastructure service.

    :attr str resource_type: The type of target for this endpoint gateway.
    :attr str name: The name of a provider infrastructure service. Must be:
          - `ibm-ntp-server`: An NTP (Network Time Protocol) server provided by IBM.
    """

    def __init__(
        self,
        resource_type: str,
        name: str,
    ) -> None:
        """
        Initialize a EndpointGatewayTargetPrototypeProviderInfrastructureServiceIdentityProviderInfrastructureServiceIdentityByName object.

        :param str resource_type: The type of target for this endpoint gateway.
        :param str name: The name of a provider infrastructure service. Must be:
               - `ibm-ntp-server`: An NTP (Network Time Protocol) server provided by IBM.
        """
        # pylint: disable=super-init-not-called
        self.resource_type = resource_type
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'EndpointGatewayTargetPrototypeProviderInfrastructureServiceIdentityProviderInfrastructureServiceIdentityByName':
        """Initialize a EndpointGatewayTargetPrototypeProviderInfrastructureServiceIdentityProviderInfrastructureServiceIdentityByName object from a json dictionary."""
        args = {}
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError('Required property \'resource_type\' not present in EndpointGatewayTargetPrototypeProviderInfrastructureServiceIdentityProviderInfrastructureServiceIdentityByName JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in EndpointGatewayTargetPrototypeProviderInfrastructureServiceIdentityProviderInfrastructureServiceIdentityByName JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a EndpointGatewayTargetPrototypeProviderInfrastructureServiceIdentityProviderInfrastructureServiceIdentityByName object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'resource_type') and self.resource_type is not None:
            _dict['resource_type'] = self.resource_type
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this EndpointGatewayTargetPrototypeProviderInfrastructureServiceIdentityProviderInfrastructureServiceIdentityByName object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'EndpointGatewayTargetPrototypeProviderInfrastructureServiceIdentityProviderInfrastructureServiceIdentityByName') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'EndpointGatewayTargetPrototypeProviderInfrastructureServiceIdentityProviderInfrastructureServiceIdentityByName') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ResourceTypeEnum(str, Enum):
        """
        The type of target for this endpoint gateway.
        """

        PROVIDER_CLOUD_SERVICE = 'provider_cloud_service'
        PROVIDER_INFRASTRUCTURE_SERVICE = 'provider_infrastructure_service'



class FloatingIPTargetPatchBareMetalServerNetworkInterfaceIdentityBareMetalServerNetworkInterfaceIdentityByHref(FloatingIPTargetPatchBareMetalServerNetworkInterfaceIdentity):
    """
    FloatingIPTargetPatchBareMetalServerNetworkInterfaceIdentityBareMetalServerNetworkInterfaceIdentityByHref.

    :attr str href: The URL for this bare metal server network interface.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a FloatingIPTargetPatchBareMetalServerNetworkInterfaceIdentityBareMetalServerNetworkInterfaceIdentityByHref object.

        :param str href: The URL for this bare metal server network interface.
        """
        # pylint: disable=super-init-not-called
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'FloatingIPTargetPatchBareMetalServerNetworkInterfaceIdentityBareMetalServerNetworkInterfaceIdentityByHref':
        """Initialize a FloatingIPTargetPatchBareMetalServerNetworkInterfaceIdentityBareMetalServerNetworkInterfaceIdentityByHref object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in FloatingIPTargetPatchBareMetalServerNetworkInterfaceIdentityBareMetalServerNetworkInterfaceIdentityByHref JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a FloatingIPTargetPatchBareMetalServerNetworkInterfaceIdentityBareMetalServerNetworkInterfaceIdentityByHref object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(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 FloatingIPTargetPatchBareMetalServerNetworkInterfaceIdentityBareMetalServerNetworkInterfaceIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'FloatingIPTargetPatchBareMetalServerNetworkInterfaceIdentityBareMetalServerNetworkInterfaceIdentityByHref') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'FloatingIPTargetPatchBareMetalServerNetworkInterfaceIdentityBareMetalServerNetworkInterfaceIdentityByHref') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class FloatingIPTargetPatchBareMetalServerNetworkInterfaceIdentityBareMetalServerNetworkInterfaceIdentityById(FloatingIPTargetPatchBareMetalServerNetworkInterfaceIdentity):
    """
    FloatingIPTargetPatchBareMetalServerNetworkInterfaceIdentityBareMetalServerNetworkInterfaceIdentityById.

    :attr str id: The unique identifier for this bare metal server network
          interface.
    """

    def __init__(
        self,
        id: str,
    ) -> None:
        """
        Initialize a FloatingIPTargetPatchBareMetalServerNetworkInterfaceIdentityBareMetalServerNetworkInterfaceIdentityById object.

        :param str id: The unique identifier for this bare metal server network
               interface.
        """
        # pylint: disable=super-init-not-called
        self.id = id

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'FloatingIPTargetPatchBareMetalServerNetworkInterfaceIdentityBareMetalServerNetworkInterfaceIdentityById':
        """Initialize a FloatingIPTargetPatchBareMetalServerNetworkInterfaceIdentityBareMetalServerNetworkInterfaceIdentityById object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in FloatingIPTargetPatchBareMetalServerNetworkInterfaceIdentityBareMetalServerNetworkInterfaceIdentityById JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a FloatingIPTargetPatchBareMetalServerNetworkInterfaceIdentityBareMetalServerNetworkInterfaceIdentityById object from 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 FloatingIPTargetPatchBareMetalServerNetworkInterfaceIdentityBareMetalServerNetworkInterfaceIdentityById object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'FloatingIPTargetPatchBareMetalServerNetworkInterfaceIdentityBareMetalServerNetworkInterfaceIdentityById') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'FloatingIPTargetPatchBareMetalServerNetworkInterfaceIdentityBareMetalServerNetworkInterfaceIdentityById') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class FloatingIPTargetPatchNetworkInterfaceIdentityNetworkInterfaceIdentityByHref(FloatingIPTargetPatchNetworkInterfaceIdentity):
    """
    FloatingIPTargetPatchNetworkInterfaceIdentityNetworkInterfaceIdentityByHref.

    :attr str href: The URL for this instance network interface.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a FloatingIPTargetPatchNetworkInterfaceIdentityNetworkInterfaceIdentityByHref object.

        :param str href: The URL for this instance network interface.
        """
        # pylint: disable=super-init-not-called
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'FloatingIPTargetPatchNetworkInterfaceIdentityNetworkInterfaceIdentityByHref':
        """Initialize a FloatingIPTargetPatchNetworkInterfaceIdentityNetworkInterfaceIdentityByHref object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in FloatingIPTargetPatchNetworkInterfaceIdentityNetworkInterfaceIdentityByHref JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a FloatingIPTargetPatchNetworkInterfaceIdentityNetworkInterfaceIdentityByHref object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(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 FloatingIPTargetPatchNetworkInterfaceIdentityNetworkInterfaceIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'FloatingIPTargetPatchNetworkInterfaceIdentityNetworkInterfaceIdentityByHref') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'FloatingIPTargetPatchNetworkInterfaceIdentityNetworkInterfaceIdentityByHref') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class FloatingIPTargetPatchNetworkInterfaceIdentityNetworkInterfaceIdentityById(FloatingIPTargetPatchNetworkInterfaceIdentity):
    """
    FloatingIPTargetPatchNetworkInterfaceIdentityNetworkInterfaceIdentityById.

    :attr str id: The unique identifier for this instance network interface.
    """

    def __init__(
        self,
        id: str,
    ) -> None:
        """
        Initialize a FloatingIPTargetPatchNetworkInterfaceIdentityNetworkInterfaceIdentityById object.

        :param str id: The unique identifier for this instance network interface.
        """
        # pylint: disable=super-init-not-called
        self.id = id

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'FloatingIPTargetPatchNetworkInterfaceIdentityNetworkInterfaceIdentityById':
        """Initialize a FloatingIPTargetPatchNetworkInterfaceIdentityNetworkInterfaceIdentityById object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in FloatingIPTargetPatchNetworkInterfaceIdentityNetworkInterfaceIdentityById JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a FloatingIPTargetPatchNetworkInterfaceIdentityNetworkInterfaceIdentityById object from 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 FloatingIPTargetPatchNetworkInterfaceIdentityNetworkInterfaceIdentityById object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'FloatingIPTargetPatchNetworkInterfaceIdentityNetworkInterfaceIdentityById') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'FloatingIPTargetPatchNetworkInterfaceIdentityNetworkInterfaceIdentityById') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class FloatingIPTargetPrototypeBareMetalServerNetworkInterfaceIdentityBareMetalServerNetworkInterfaceIdentityByHref(FloatingIPTargetPrototypeBareMetalServerNetworkInterfaceIdentity):
    """
    FloatingIPTargetPrototypeBareMetalServerNetworkInterfaceIdentityBareMetalServerNetworkInterfaceIdentityByHref.

    :attr str href: The URL for this bare metal server network interface.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a FloatingIPTargetPrototypeBareMetalServerNetworkInterfaceIdentityBareMetalServerNetworkInterfaceIdentityByHref object.

        :param str href: The URL for this bare metal server network interface.
        """
        # pylint: disable=super-init-not-called
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'FloatingIPTargetPrototypeBareMetalServerNetworkInterfaceIdentityBareMetalServerNetworkInterfaceIdentityByHref':
        """Initialize a FloatingIPTargetPrototypeBareMetalServerNetworkInterfaceIdentityBareMetalServerNetworkInterfaceIdentityByHref object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in FloatingIPTargetPrototypeBareMetalServerNetworkInterfaceIdentityBareMetalServerNetworkInterfaceIdentityByHref JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a FloatingIPTargetPrototypeBareMetalServerNetworkInterfaceIdentityBareMetalServerNetworkInterfaceIdentityByHref object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(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 FloatingIPTargetPrototypeBareMetalServerNetworkInterfaceIdentityBareMetalServerNetworkInterfaceIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'FloatingIPTargetPrototypeBareMetalServerNetworkInterfaceIdentityBareMetalServerNetworkInterfaceIdentityByHref') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'FloatingIPTargetPrototypeBareMetalServerNetworkInterfaceIdentityBareMetalServerNetworkInterfaceIdentityByHref') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class FloatingIPTargetPrototypeBareMetalServerNetworkInterfaceIdentityBareMetalServerNetworkInterfaceIdentityById(FloatingIPTargetPrototypeBareMetalServerNetworkInterfaceIdentity):
    """
    FloatingIPTargetPrototypeBareMetalServerNetworkInterfaceIdentityBareMetalServerNetworkInterfaceIdentityById.

    :attr str id: The unique identifier for this bare metal server network
          interface.
    """

    def __init__(
        self,
        id: str,
    ) -> None:
        """
        Initialize a FloatingIPTargetPrototypeBareMetalServerNetworkInterfaceIdentityBareMetalServerNetworkInterfaceIdentityById object.

        :param str id: The unique identifier for this bare metal server network
               interface.
        """
        # pylint: disable=super-init-not-called
        self.id = id

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'FloatingIPTargetPrototypeBareMetalServerNetworkInterfaceIdentityBareMetalServerNetworkInterfaceIdentityById':
        """Initialize a FloatingIPTargetPrototypeBareMetalServerNetworkInterfaceIdentityBareMetalServerNetworkInterfaceIdentityById object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in FloatingIPTargetPrototypeBareMetalServerNetworkInterfaceIdentityBareMetalServerNetworkInterfaceIdentityById JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a FloatingIPTargetPrototypeBareMetalServerNetworkInterfaceIdentityBareMetalServerNetworkInterfaceIdentityById object from 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 FloatingIPTargetPrototypeBareMetalServerNetworkInterfaceIdentityBareMetalServerNetworkInterfaceIdentityById object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'FloatingIPTargetPrototypeBareMetalServerNetworkInterfaceIdentityBareMetalServerNetworkInterfaceIdentityById') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'FloatingIPTargetPrototypeBareMetalServerNetworkInterfaceIdentityBareMetalServerNetworkInterfaceIdentityById') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class FloatingIPTargetPrototypeNetworkInterfaceIdentityNetworkInterfaceIdentityByHref(FloatingIPTargetPrototypeNetworkInterfaceIdentity):
    """
    FloatingIPTargetPrototypeNetworkInterfaceIdentityNetworkInterfaceIdentityByHref.

    :attr str href: The URL for this instance network interface.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a FloatingIPTargetPrototypeNetworkInterfaceIdentityNetworkInterfaceIdentityByHref object.

        :param str href: The URL for this instance network interface.
        """
        # pylint: disable=super-init-not-called
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'FloatingIPTargetPrototypeNetworkInterfaceIdentityNetworkInterfaceIdentityByHref':
        """Initialize a FloatingIPTargetPrototypeNetworkInterfaceIdentityNetworkInterfaceIdentityByHref object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in FloatingIPTargetPrototypeNetworkInterfaceIdentityNetworkInterfaceIdentityByHref JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a FloatingIPTargetPrototypeNetworkInterfaceIdentityNetworkInterfaceIdentityByHref object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(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 FloatingIPTargetPrototypeNetworkInterfaceIdentityNetworkInterfaceIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'FloatingIPTargetPrototypeNetworkInterfaceIdentityNetworkInterfaceIdentityByHref') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'FloatingIPTargetPrototypeNetworkInterfaceIdentityNetworkInterfaceIdentityByHref') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class FloatingIPTargetPrototypeNetworkInterfaceIdentityNetworkInterfaceIdentityById(FloatingIPTargetPrototypeNetworkInterfaceIdentity):
    """
    FloatingIPTargetPrototypeNetworkInterfaceIdentityNetworkInterfaceIdentityById.

    :attr str id: The unique identifier for this instance network interface.
    """

    def __init__(
        self,
        id: str,
    ) -> None:
        """
        Initialize a FloatingIPTargetPrototypeNetworkInterfaceIdentityNetworkInterfaceIdentityById object.

        :param str id: The unique identifier for this instance network interface.
        """
        # pylint: disable=super-init-not-called
        self.id = id

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'FloatingIPTargetPrototypeNetworkInterfaceIdentityNetworkInterfaceIdentityById':
        """Initialize a FloatingIPTargetPrototypeNetworkInterfaceIdentityNetworkInterfaceIdentityById object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in FloatingIPTargetPrototypeNetworkInterfaceIdentityNetworkInterfaceIdentityById JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a FloatingIPTargetPrototypeNetworkInterfaceIdentityNetworkInterfaceIdentityById object from 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 FloatingIPTargetPrototypeNetworkInterfaceIdentityNetworkInterfaceIdentityById object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'FloatingIPTargetPrototypeNetworkInterfaceIdentityNetworkInterfaceIdentityById') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'FloatingIPTargetPrototypeNetworkInterfaceIdentityNetworkInterfaceIdentityById') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class FlowLogCollectorTargetPrototypeInstanceIdentityInstanceIdentityByCRN(FlowLogCollectorTargetPrototypeInstanceIdentity):
    """
    FlowLogCollectorTargetPrototypeInstanceIdentityInstanceIdentityByCRN.

    :attr str crn: The CRN for this virtual server instance.
    """

    def __init__(
        self,
        crn: str,
    ) -> None:
        """
        Initialize a FlowLogCollectorTargetPrototypeInstanceIdentityInstanceIdentityByCRN object.

        :param str crn: The CRN for this virtual server instance.
        """
        # pylint: disable=super-init-not-called
        self.crn = crn

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'FlowLogCollectorTargetPrototypeInstanceIdentityInstanceIdentityByCRN':
        """Initialize a FlowLogCollectorTargetPrototypeInstanceIdentityInstanceIdentityByCRN object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError('Required property \'crn\' not present in FlowLogCollectorTargetPrototypeInstanceIdentityInstanceIdentityByCRN JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a FlowLogCollectorTargetPrototypeInstanceIdentityInstanceIdentityByCRN object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this FlowLogCollectorTargetPrototypeInstanceIdentityInstanceIdentityByCRN object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'FlowLogCollectorTargetPrototypeInstanceIdentityInstanceIdentityByCRN') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'FlowLogCollectorTargetPrototypeInstanceIdentityInstanceIdentityByCRN') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class FlowLogCollectorTargetPrototypeInstanceIdentityInstanceIdentityByHref(FlowLogCollectorTargetPrototypeInstanceIdentity):
    """
    FlowLogCollectorTargetPrototypeInstanceIdentityInstanceIdentityByHref.

    :attr str href: The URL for this virtual server instance.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a FlowLogCollectorTargetPrototypeInstanceIdentityInstanceIdentityByHref object.

        :param str href: The URL for this virtual server instance.
        """
        # pylint: disable=super-init-not-called
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'FlowLogCollectorTargetPrototypeInstanceIdentityInstanceIdentityByHref':
        """Initialize a FlowLogCollectorTargetPrototypeInstanceIdentityInstanceIdentityByHref object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in FlowLogCollectorTargetPrototypeInstanceIdentityInstanceIdentityByHref JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a FlowLogCollectorTargetPrototypeInstanceIdentityInstanceIdentityByHref object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this FlowLogCollectorTargetPrototypeInstanceIdentityInstanceIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'FlowLogCollectorTargetPrototypeInstanceIdentityInstanceIdentityByHref') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'FlowLogCollectorTargetPrototypeInstanceIdentityInstanceIdentityByHref') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class FlowLogCollectorTargetPrototypeInstanceIdentityInstanceIdentityById(FlowLogCollectorTargetPrototypeInstanceIdentity):
    """
    FlowLogCollectorTargetPrototypeInstanceIdentityInstanceIdentityById.

    :attr str id: The unique identifier for this virtual server instance.
    """

    def __init__(
        self,
        id: str,
    ) -> None:
        """
        Initialize a FlowLogCollectorTargetPrototypeInstanceIdentityInstanceIdentityById object.

        :param str id: The unique identifier for this virtual server instance.
        """
        # pylint: disable=super-init-not-called
        self.id = id

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'FlowLogCollectorTargetPrototypeInstanceIdentityInstanceIdentityById':
        """Initialize a FlowLogCollectorTargetPrototypeInstanceIdentityInstanceIdentityById object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in FlowLogCollectorTargetPrototypeInstanceIdentityInstanceIdentityById JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a FlowLogCollectorTargetPrototypeInstanceIdentityInstanceIdentityById object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this FlowLogCollectorTargetPrototypeInstanceIdentityInstanceIdentityById object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'FlowLogCollectorTargetPrototypeInstanceIdentityInstanceIdentityById') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'FlowLogCollectorTargetPrototypeInstanceIdentityInstanceIdentityById') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class FlowLogCollectorTargetPrototypeNetworkInterfaceIdentityNetworkInterfaceIdentityByHref(FlowLogCollectorTargetPrototypeNetworkInterfaceIdentity):
    """
    FlowLogCollectorTargetPrototypeNetworkInterfaceIdentityNetworkInterfaceIdentityByHref.

    :attr str href: The URL for this instance network interface.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a FlowLogCollectorTargetPrototypeNetworkInterfaceIdentityNetworkInterfaceIdentityByHref object.

        :param str href: The URL for this instance network interface.
        """
        # pylint: disable=super-init-not-called
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'FlowLogCollectorTargetPrototypeNetworkInterfaceIdentityNetworkInterfaceIdentityByHref':
        """Initialize a FlowLogCollectorTargetPrototypeNetworkInterfaceIdentityNetworkInterfaceIdentityByHref object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in FlowLogCollectorTargetPrototypeNetworkInterfaceIdentityNetworkInterfaceIdentityByHref JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a FlowLogCollectorTargetPrototypeNetworkInterfaceIdentityNetworkInterfaceIdentityByHref object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(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 FlowLogCollectorTargetPrototypeNetworkInterfaceIdentityNetworkInterfaceIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'FlowLogCollectorTargetPrototypeNetworkInterfaceIdentityNetworkInterfaceIdentityByHref') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'FlowLogCollectorTargetPrototypeNetworkInterfaceIdentityNetworkInterfaceIdentityByHref') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class FlowLogCollectorTargetPrototypeNetworkInterfaceIdentityNetworkInterfaceIdentityById(FlowLogCollectorTargetPrototypeNetworkInterfaceIdentity):
    """
    FlowLogCollectorTargetPrototypeNetworkInterfaceIdentityNetworkInterfaceIdentityById.

    :attr str id: The unique identifier for this instance network interface.
    """

    def __init__(
        self,
        id: str,
    ) -> None:
        """
        Initialize a FlowLogCollectorTargetPrototypeNetworkInterfaceIdentityNetworkInterfaceIdentityById object.

        :param str id: The unique identifier for this instance network interface.
        """
        # pylint: disable=super-init-not-called
        self.id = id

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'FlowLogCollectorTargetPrototypeNetworkInterfaceIdentityNetworkInterfaceIdentityById':
        """Initialize a FlowLogCollectorTargetPrototypeNetworkInterfaceIdentityNetworkInterfaceIdentityById object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in FlowLogCollectorTargetPrototypeNetworkInterfaceIdentityNetworkInterfaceIdentityById JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a FlowLogCollectorTargetPrototypeNetworkInterfaceIdentityNetworkInterfaceIdentityById object from 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 FlowLogCollectorTargetPrototypeNetworkInterfaceIdentityNetworkInterfaceIdentityById object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'FlowLogCollectorTargetPrototypeNetworkInterfaceIdentityNetworkInterfaceIdentityById') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'FlowLogCollectorTargetPrototypeNetworkInterfaceIdentityNetworkInterfaceIdentityById') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class FlowLogCollectorTargetPrototypeSubnetIdentitySubnetIdentityByCRN(FlowLogCollectorTargetPrototypeSubnetIdentity):
    """
    FlowLogCollectorTargetPrototypeSubnetIdentitySubnetIdentityByCRN.

    :attr str crn: The CRN for this subnet.
    """

    def __init__(
        self,
        crn: str,
    ) -> None:
        """
        Initialize a FlowLogCollectorTargetPrototypeSubnetIdentitySubnetIdentityByCRN object.

        :param str crn: The CRN for this subnet.
        """
        # pylint: disable=super-init-not-called
        self.crn = crn

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'FlowLogCollectorTargetPrototypeSubnetIdentitySubnetIdentityByCRN':
        """Initialize a FlowLogCollectorTargetPrototypeSubnetIdentitySubnetIdentityByCRN object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError('Required property \'crn\' not present in FlowLogCollectorTargetPrototypeSubnetIdentitySubnetIdentityByCRN JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a FlowLogCollectorTargetPrototypeSubnetIdentitySubnetIdentityByCRN object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this FlowLogCollectorTargetPrototypeSubnetIdentitySubnetIdentityByCRN object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'FlowLogCollectorTargetPrototypeSubnetIdentitySubnetIdentityByCRN') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'FlowLogCollectorTargetPrototypeSubnetIdentitySubnetIdentityByCRN') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class FlowLogCollectorTargetPrototypeSubnetIdentitySubnetIdentityByHref(FlowLogCollectorTargetPrototypeSubnetIdentity):
    """
    FlowLogCollectorTargetPrototypeSubnetIdentitySubnetIdentityByHref.

    :attr str href: The URL for this subnet.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a FlowLogCollectorTargetPrototypeSubnetIdentitySubnetIdentityByHref object.

        :param str href: The URL for this subnet.
        """
        # pylint: disable=super-init-not-called
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'FlowLogCollectorTargetPrototypeSubnetIdentitySubnetIdentityByHref':
        """Initialize a FlowLogCollectorTargetPrototypeSubnetIdentitySubnetIdentityByHref object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in FlowLogCollectorTargetPrototypeSubnetIdentitySubnetIdentityByHref JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a FlowLogCollectorTargetPrototypeSubnetIdentitySubnetIdentityByHref object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this FlowLogCollectorTargetPrototypeSubnetIdentitySubnetIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'FlowLogCollectorTargetPrototypeSubnetIdentitySubnetIdentityByHref') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'FlowLogCollectorTargetPrototypeSubnetIdentitySubnetIdentityByHref') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class FlowLogCollectorTargetPrototypeSubnetIdentitySubnetIdentityById(FlowLogCollectorTargetPrototypeSubnetIdentity):
    """
    FlowLogCollectorTargetPrototypeSubnetIdentitySubnetIdentityById.

    :attr str id: The unique identifier for this subnet.
    """

    def __init__(
        self,
        id: str,
    ) -> None:
        """
        Initialize a FlowLogCollectorTargetPrototypeSubnetIdentitySubnetIdentityById object.

        :param str id: The unique identifier for this subnet.
        """
        # pylint: disable=super-init-not-called
        self.id = id

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'FlowLogCollectorTargetPrototypeSubnetIdentitySubnetIdentityById':
        """Initialize a FlowLogCollectorTargetPrototypeSubnetIdentitySubnetIdentityById object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in FlowLogCollectorTargetPrototypeSubnetIdentitySubnetIdentityById JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a FlowLogCollectorTargetPrototypeSubnetIdentitySubnetIdentityById object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this FlowLogCollectorTargetPrototypeSubnetIdentitySubnetIdentityById object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'FlowLogCollectorTargetPrototypeSubnetIdentitySubnetIdentityById') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'FlowLogCollectorTargetPrototypeSubnetIdentitySubnetIdentityById') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class FlowLogCollectorTargetPrototypeVPCIdentityVPCIdentityByCRN(FlowLogCollectorTargetPrototypeVPCIdentity):
    """
    FlowLogCollectorTargetPrototypeVPCIdentityVPCIdentityByCRN.

    :attr str crn: The CRN for this VPC.
    """

    def __init__(
        self,
        crn: str,
    ) -> None:
        """
        Initialize a FlowLogCollectorTargetPrototypeVPCIdentityVPCIdentityByCRN object.

        :param str crn: The CRN for this VPC.
        """
        # pylint: disable=super-init-not-called
        self.crn = crn

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'FlowLogCollectorTargetPrototypeVPCIdentityVPCIdentityByCRN':
        """Initialize a FlowLogCollectorTargetPrototypeVPCIdentityVPCIdentityByCRN object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError('Required property \'crn\' not present in FlowLogCollectorTargetPrototypeVPCIdentityVPCIdentityByCRN JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a FlowLogCollectorTargetPrototypeVPCIdentityVPCIdentityByCRN object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this FlowLogCollectorTargetPrototypeVPCIdentityVPCIdentityByCRN object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'FlowLogCollectorTargetPrototypeVPCIdentityVPCIdentityByCRN') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'FlowLogCollectorTargetPrototypeVPCIdentityVPCIdentityByCRN') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class FlowLogCollectorTargetPrototypeVPCIdentityVPCIdentityByHref(FlowLogCollectorTargetPrototypeVPCIdentity):
    """
    FlowLogCollectorTargetPrototypeVPCIdentityVPCIdentityByHref.

    :attr str href: The URL for this VPC.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a FlowLogCollectorTargetPrototypeVPCIdentityVPCIdentityByHref object.

        :param str href: The URL for this VPC.
        """
        # pylint: disable=super-init-not-called
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'FlowLogCollectorTargetPrototypeVPCIdentityVPCIdentityByHref':
        """Initialize a FlowLogCollectorTargetPrototypeVPCIdentityVPCIdentityByHref object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in FlowLogCollectorTargetPrototypeVPCIdentityVPCIdentityByHref JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a FlowLogCollectorTargetPrototypeVPCIdentityVPCIdentityByHref object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this FlowLogCollectorTargetPrototypeVPCIdentityVPCIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'FlowLogCollectorTargetPrototypeVPCIdentityVPCIdentityByHref') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'FlowLogCollectorTargetPrototypeVPCIdentityVPCIdentityByHref') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class FlowLogCollectorTargetPrototypeVPCIdentityVPCIdentityById(FlowLogCollectorTargetPrototypeVPCIdentity):
    """
    FlowLogCollectorTargetPrototypeVPCIdentityVPCIdentityById.

    :attr str id: The unique identifier for this VPC.
    """

    def __init__(
        self,
        id: str,
    ) -> None:
        """
        Initialize a FlowLogCollectorTargetPrototypeVPCIdentityVPCIdentityById object.

        :param str id: The unique identifier for this VPC.
        """
        # pylint: disable=super-init-not-called
        self.id = id

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'FlowLogCollectorTargetPrototypeVPCIdentityVPCIdentityById':
        """Initialize a FlowLogCollectorTargetPrototypeVPCIdentityVPCIdentityById object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in FlowLogCollectorTargetPrototypeVPCIdentityVPCIdentityById JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a FlowLogCollectorTargetPrototypeVPCIdentityVPCIdentityById object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this FlowLogCollectorTargetPrototypeVPCIdentityVPCIdentityById object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'FlowLogCollectorTargetPrototypeVPCIdentityVPCIdentityById') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'FlowLogCollectorTargetPrototypeVPCIdentityVPCIdentityById') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceGroupManagerActionPrototypeScheduledActionPrototypeByCronSpec(InstanceGroupManagerActionPrototypeScheduledActionPrototype):
    """
    InstanceGroupManagerActionPrototypeScheduledActionPrototypeByCronSpec.

    :attr str name: (optional) The name for this instance group manager action. The
          name must not be used by another action for the instance group manager. If
          unspecified, the name will be a hyphenated list of randomly-selected words.
    :attr str cron_spec: (optional) The cron specification for a recurring scheduled
          action. Actions can be applied a maximum of one time within a 5 min period.
    """

    def __init__(
        self,
        *,
        name: str = None,
        cron_spec: str = None,
    ) -> None:
        """
        Initialize a InstanceGroupManagerActionPrototypeScheduledActionPrototypeByCronSpec object.

        :param str name: (optional) The name for this instance group manager
               action. The name must not be used by another action for the instance group
               manager. If unspecified, the name will be a hyphenated list of
               randomly-selected words.
        :param str cron_spec: (optional) The cron specification for a recurring
               scheduled action. Actions can be applied a maximum of one time within a 5
               min period.
        """
        # pylint: disable=super-init-not-called
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['InstanceGroupManagerActionPrototypeScheduledActionPrototypeByCronSpecByGroup', 'InstanceGroupManagerActionPrototypeScheduledActionPrototypeByCronSpecByManager'])
        )
        raise Exception(msg)


class InstanceGroupManagerActionPrototypeScheduledActionPrototypeByRunAt(InstanceGroupManagerActionPrototypeScheduledActionPrototype):
    """
    InstanceGroupManagerActionPrototypeScheduledActionPrototypeByRunAt.

    :attr str name: (optional) The name for this instance group manager action. The
          name must not be used by another action for the instance group manager. If
          unspecified, the name will be a hyphenated list of randomly-selected words.
    :attr datetime run_at: (optional) The date and time the scheduled action will
          run.
    """

    def __init__(
        self,
        *,
        name: str = None,
        run_at: datetime = None,
    ) -> None:
        """
        Initialize a InstanceGroupManagerActionPrototypeScheduledActionPrototypeByRunAt object.

        :param str name: (optional) The name for this instance group manager
               action. The name must not be used by another action for the instance group
               manager. If unspecified, the name will be a hyphenated list of
               randomly-selected words.
        :param datetime run_at: (optional) The date and time the scheduled action
               will run.
        """
        # pylint: disable=super-init-not-called
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['InstanceGroupManagerActionPrototypeScheduledActionPrototypeByRunAtByGroup', 'InstanceGroupManagerActionPrototypeScheduledActionPrototypeByRunAtByManager'])
        )
        raise Exception(msg)


class InstanceGroupManagerActionScheduledActionGroupTarget(InstanceGroupManagerActionScheduledAction):
    """
    InstanceGroupManagerActionScheduledActionGroupTarget.

    :attr bool auto_delete: Indicates whether this scheduled action will be
          automatically deleted after it has completed and `auto_delete_timeout` hours
          have passed. At present, this is always
          `true`, but may be modifiable in the future.
    :attr int auto_delete_timeout: If `auto_delete` is `true`, and this scheduled
          action has finished, the hours after which it will be automatically deleted. If
          the value is `0`, the action will be deleted once it has finished. This value
          may be modifiable in the future.
    :attr datetime created_at: The date and time that the instance group manager
          action was created.
    :attr str href: The URL for this instance group manager action.
    :attr str id: The unique identifier for this instance group manager action.
    :attr str name: The name for this instance group manager action. The name is
          unique across all actions for the instance group manager.
    :attr str resource_type: The resource type.
    :attr str status: The status of the instance group action
          - `active`: Action is ready to be run
          - `completed`: Action was completed successfully
          - `failed`: Action could not be completed successfully
          - `incompatible`: Action parameters are not compatible with the group or manager
          - `omitted`: Action was not applied because this action's manager was disabled.
    :attr datetime updated_at: The date and time that the instance group manager
          action was updated.
    :attr str action_type: The type of action for the instance group.
    :attr str cron_spec: (optional) The cron specification for a recurring scheduled
          action. Actions can be applied a maximum of one time within a 5 min period.
    :attr datetime last_applied_at: (optional) The date and time the scheduled
          action was last applied. If absent, the action has never been applied.
    :attr datetime next_run_at: (optional) The date and time the scheduled action
          will next run. If absent, the system is currently calculating the next run time.
    :attr InstanceGroupManagerScheduledActionGroup group:
    """

    def __init__(
        self,
        auto_delete: bool,
        auto_delete_timeout: int,
        created_at: datetime,
        href: str,
        id: str,
        name: str,
        resource_type: str,
        status: str,
        updated_at: datetime,
        action_type: str,
        group: 'InstanceGroupManagerScheduledActionGroup',
        *,
        cron_spec: str = None,
        last_applied_at: datetime = None,
        next_run_at: datetime = None,
    ) -> None:
        """
        Initialize a InstanceGroupManagerActionScheduledActionGroupTarget object.

        :param bool auto_delete: Indicates whether this scheduled action will be
               automatically deleted after it has completed and `auto_delete_timeout`
               hours have passed. At present, this is always
               `true`, but may be modifiable in the future.
        :param int auto_delete_timeout: If `auto_delete` is `true`, and this
               scheduled action has finished, the hours after which it will be
               automatically deleted. If the value is `0`, the action will be deleted once
               it has finished. This value may be modifiable in the future.
        :param datetime created_at: The date and time that the instance group
               manager action was created.
        :param str href: The URL for this instance group manager action.
        :param str id: The unique identifier for this instance group manager
               action.
        :param str name: The name for this instance group manager action. The name
               is unique across all actions for the instance group manager.
        :param str resource_type: The resource type.
        :param str status: The status of the instance group action
               - `active`: Action is ready to be run
               - `completed`: Action was completed successfully
               - `failed`: Action could not be completed successfully
               - `incompatible`: Action parameters are not compatible with the group or
               manager
               - `omitted`: Action was not applied because this action's manager was
               disabled.
        :param datetime updated_at: The date and time that the instance group
               manager action was updated.
        :param str action_type: The type of action for the instance group.
        :param InstanceGroupManagerScheduledActionGroup group:
        :param str cron_spec: (optional) The cron specification for a recurring
               scheduled action. Actions can be applied a maximum of one time within a 5
               min period.
        :param datetime last_applied_at: (optional) The date and time the scheduled
               action was last applied. If absent, the action has never been applied.
        :param datetime next_run_at: (optional) The date and time the scheduled
               action will next run. If absent, the system is currently calculating the
               next run time.
        """
        # pylint: disable=super-init-not-called
        self.auto_delete = auto_delete
        self.auto_delete_timeout = auto_delete_timeout
        self.created_at = created_at
        self.href = href
        self.id = id
        self.name = name
        self.resource_type = resource_type
        self.status = status
        self.updated_at = updated_at
        self.action_type = action_type
        self.cron_spec = cron_spec
        self.last_applied_at = last_applied_at
        self.next_run_at = next_run_at
        self.group = group

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceGroupManagerActionScheduledActionGroupTarget':
        """Initialize a InstanceGroupManagerActionScheduledActionGroupTarget object from a json dictionary."""
        args = {}
        if 'auto_delete' in _dict:
            args['auto_delete'] = _dict.get('auto_delete')
        else:
            raise ValueError('Required property \'auto_delete\' not present in InstanceGroupManagerActionScheduledActionGroupTarget JSON')
        if 'auto_delete_timeout' in _dict:
            args['auto_delete_timeout'] = _dict.get('auto_delete_timeout')
        else:
            raise ValueError('Required property \'auto_delete_timeout\' not present in InstanceGroupManagerActionScheduledActionGroupTarget 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 InstanceGroupManagerActionScheduledActionGroupTarget JSON')
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in InstanceGroupManagerActionScheduledActionGroupTarget JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in InstanceGroupManagerActionScheduledActionGroupTarget JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in InstanceGroupManagerActionScheduledActionGroupTarget JSON')
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError('Required property \'resource_type\' not present in InstanceGroupManagerActionScheduledActionGroupTarget JSON')
        if 'status' in _dict:
            args['status'] = _dict.get('status')
        else:
            raise ValueError('Required property \'status\' not present in InstanceGroupManagerActionScheduledActionGroupTarget JSON')
        if 'updated_at' in _dict:
            args['updated_at'] = string_to_datetime(_dict.get('updated_at'))
        else:
            raise ValueError('Required property \'updated_at\' not present in InstanceGroupManagerActionScheduledActionGroupTarget JSON')
        if 'action_type' in _dict:
            args['action_type'] = _dict.get('action_type')
        else:
            raise ValueError('Required property \'action_type\' not present in InstanceGroupManagerActionScheduledActionGroupTarget JSON')
        if 'cron_spec' in _dict:
            args['cron_spec'] = _dict.get('cron_spec')
        if 'last_applied_at' in _dict:
            args['last_applied_at'] = string_to_datetime(_dict.get('last_applied_at'))
        if 'next_run_at' in _dict:
            args['next_run_at'] = string_to_datetime(_dict.get('next_run_at'))
        if 'group' in _dict:
            args['group'] = InstanceGroupManagerScheduledActionGroup.from_dict(_dict.get('group'))
        else:
            raise ValueError('Required property \'group\' not present in InstanceGroupManagerActionScheduledActionGroupTarget JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceGroupManagerActionScheduledActionGroupTarget object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'auto_delete') and self.auto_delete is not None:
            _dict['auto_delete'] = self.auto_delete
        if hasattr(self, 'auto_delete_timeout') and self.auto_delete_timeout is not None:
            _dict['auto_delete_timeout'] = self.auto_delete_timeout
        if hasattr(self, 'created_at') and self.created_at is not None:
            _dict['created_at'] = datetime_to_string(self.created_at)
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'resource_type') and self.resource_type is not None:
            _dict['resource_type'] = self.resource_type
        if hasattr(self, 'status') and self.status is not None:
            _dict['status'] = self.status
        if hasattr(self, 'updated_at') and self.updated_at is not None:
            _dict['updated_at'] = datetime_to_string(self.updated_at)
        if hasattr(self, 'action_type') and self.action_type is not None:
            _dict['action_type'] = self.action_type
        if hasattr(self, 'cron_spec') and self.cron_spec is not None:
            _dict['cron_spec'] = self.cron_spec
        if hasattr(self, 'last_applied_at') and self.last_applied_at is not None:
            _dict['last_applied_at'] = datetime_to_string(self.last_applied_at)
        if hasattr(self, 'next_run_at') and self.next_run_at is not None:
            _dict['next_run_at'] = datetime_to_string(self.next_run_at)
        if hasattr(self, 'group') and self.group is not None:
            if isinstance(self.group, dict):
                _dict['group'] = self.group
            else:
                _dict['group'] = self.group.to_dict()
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceGroupManagerActionScheduledActionGroupTarget object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceGroupManagerActionScheduledActionGroupTarget') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceGroupManagerActionScheduledActionGroupTarget') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        INSTANCE_GROUP_MANAGER_ACTION = 'instance_group_manager_action'


    class StatusEnum(str, Enum):
        """
        The status of the instance group action
        - `active`: Action is ready to be run
        - `completed`: Action was completed successfully
        - `failed`: Action could not be completed successfully
        - `incompatible`: Action parameters are not compatible with the group or manager
        - `omitted`: Action was not applied because this action's manager was disabled.
        """

        ACTIVE = 'active'
        COMPLETED = 'completed'
        FAILED = 'failed'
        INCOMPATIBLE = 'incompatible'
        OMITTED = 'omitted'


    class ActionTypeEnum(str, Enum):
        """
        The type of action for the instance group.
        """

        SCHEDULED = 'scheduled'



class InstanceGroupManagerActionScheduledActionManagerTarget(InstanceGroupManagerActionScheduledAction):
    """
    InstanceGroupManagerActionScheduledActionManagerTarget.

    :attr bool auto_delete: Indicates whether this scheduled action will be
          automatically deleted after it has completed and `auto_delete_timeout` hours
          have passed. At present, this is always
          `true`, but may be modifiable in the future.
    :attr int auto_delete_timeout: If `auto_delete` is `true`, and this scheduled
          action has finished, the hours after which it will be automatically deleted. If
          the value is `0`, the action will be deleted once it has finished. This value
          may be modifiable in the future.
    :attr datetime created_at: The date and time that the instance group manager
          action was created.
    :attr str href: The URL for this instance group manager action.
    :attr str id: The unique identifier for this instance group manager action.
    :attr str name: The name for this instance group manager action. The name is
          unique across all actions for the instance group manager.
    :attr str resource_type: The resource type.
    :attr str status: The status of the instance group action
          - `active`: Action is ready to be run
          - `completed`: Action was completed successfully
          - `failed`: Action could not be completed successfully
          - `incompatible`: Action parameters are not compatible with the group or manager
          - `omitted`: Action was not applied because this action's manager was disabled.
    :attr datetime updated_at: The date and time that the instance group manager
          action was updated.
    :attr str action_type: The type of action for the instance group.
    :attr str cron_spec: (optional) The cron specification for a recurring scheduled
          action. Actions can be applied a maximum of one time within a 5 min period.
    :attr datetime last_applied_at: (optional) The date and time the scheduled
          action was last applied. If absent, the action has never been applied.
    :attr datetime next_run_at: (optional) The date and time the scheduled action
          will next run. If absent, the system is currently calculating the next run time.
    :attr InstanceGroupManagerScheduledActionManager manager:
    """

    def __init__(
        self,
        auto_delete: bool,
        auto_delete_timeout: int,
        created_at: datetime,
        href: str,
        id: str,
        name: str,
        resource_type: str,
        status: str,
        updated_at: datetime,
        action_type: str,
        manager: 'InstanceGroupManagerScheduledActionManager',
        *,
        cron_spec: str = None,
        last_applied_at: datetime = None,
        next_run_at: datetime = None,
    ) -> None:
        """
        Initialize a InstanceGroupManagerActionScheduledActionManagerTarget object.

        :param bool auto_delete: Indicates whether this scheduled action will be
               automatically deleted after it has completed and `auto_delete_timeout`
               hours have passed. At present, this is always
               `true`, but may be modifiable in the future.
        :param int auto_delete_timeout: If `auto_delete` is `true`, and this
               scheduled action has finished, the hours after which it will be
               automatically deleted. If the value is `0`, the action will be deleted once
               it has finished. This value may be modifiable in the future.
        :param datetime created_at: The date and time that the instance group
               manager action was created.
        :param str href: The URL for this instance group manager action.
        :param str id: The unique identifier for this instance group manager
               action.
        :param str name: The name for this instance group manager action. The name
               is unique across all actions for the instance group manager.
        :param str resource_type: The resource type.
        :param str status: The status of the instance group action
               - `active`: Action is ready to be run
               - `completed`: Action was completed successfully
               - `failed`: Action could not be completed successfully
               - `incompatible`: Action parameters are not compatible with the group or
               manager
               - `omitted`: Action was not applied because this action's manager was
               disabled.
        :param datetime updated_at: The date and time that the instance group
               manager action was updated.
        :param str action_type: The type of action for the instance group.
        :param InstanceGroupManagerScheduledActionManager manager:
        :param str cron_spec: (optional) The cron specification for a recurring
               scheduled action. Actions can be applied a maximum of one time within a 5
               min period.
        :param datetime last_applied_at: (optional) The date and time the scheduled
               action was last applied. If absent, the action has never been applied.
        :param datetime next_run_at: (optional) The date and time the scheduled
               action will next run. If absent, the system is currently calculating the
               next run time.
        """
        # pylint: disable=super-init-not-called
        self.auto_delete = auto_delete
        self.auto_delete_timeout = auto_delete_timeout
        self.created_at = created_at
        self.href = href
        self.id = id
        self.name = name
        self.resource_type = resource_type
        self.status = status
        self.updated_at = updated_at
        self.action_type = action_type
        self.cron_spec = cron_spec
        self.last_applied_at = last_applied_at
        self.next_run_at = next_run_at
        self.manager = manager

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceGroupManagerActionScheduledActionManagerTarget':
        """Initialize a InstanceGroupManagerActionScheduledActionManagerTarget object from a json dictionary."""
        args = {}
        if 'auto_delete' in _dict:
            args['auto_delete'] = _dict.get('auto_delete')
        else:
            raise ValueError('Required property \'auto_delete\' not present in InstanceGroupManagerActionScheduledActionManagerTarget JSON')
        if 'auto_delete_timeout' in _dict:
            args['auto_delete_timeout'] = _dict.get('auto_delete_timeout')
        else:
            raise ValueError('Required property \'auto_delete_timeout\' not present in InstanceGroupManagerActionScheduledActionManagerTarget 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 InstanceGroupManagerActionScheduledActionManagerTarget JSON')
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in InstanceGroupManagerActionScheduledActionManagerTarget JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in InstanceGroupManagerActionScheduledActionManagerTarget JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in InstanceGroupManagerActionScheduledActionManagerTarget JSON')
        if 'resource_type' in _dict:
            args['resource_type'] = _dict.get('resource_type')
        else:
            raise ValueError('Required property \'resource_type\' not present in InstanceGroupManagerActionScheduledActionManagerTarget JSON')
        if 'status' in _dict:
            args['status'] = _dict.get('status')
        else:
            raise ValueError('Required property \'status\' not present in InstanceGroupManagerActionScheduledActionManagerTarget JSON')
        if 'updated_at' in _dict:
            args['updated_at'] = string_to_datetime(_dict.get('updated_at'))
        else:
            raise ValueError('Required property \'updated_at\' not present in InstanceGroupManagerActionScheduledActionManagerTarget JSON')
        if 'action_type' in _dict:
            args['action_type'] = _dict.get('action_type')
        else:
            raise ValueError('Required property \'action_type\' not present in InstanceGroupManagerActionScheduledActionManagerTarget JSON')
        if 'cron_spec' in _dict:
            args['cron_spec'] = _dict.get('cron_spec')
        if 'last_applied_at' in _dict:
            args['last_applied_at'] = string_to_datetime(_dict.get('last_applied_at'))
        if 'next_run_at' in _dict:
            args['next_run_at'] = string_to_datetime(_dict.get('next_run_at'))
        if 'manager' in _dict:
            args['manager'] = _dict.get('manager')
        else:
            raise ValueError('Required property \'manager\' not present in InstanceGroupManagerActionScheduledActionManagerTarget JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceGroupManagerActionScheduledActionManagerTarget object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'auto_delete') and self.auto_delete is not None:
            _dict['auto_delete'] = self.auto_delete
        if hasattr(self, 'auto_delete_timeout') and self.auto_delete_timeout is not None:
            _dict['auto_delete_timeout'] = self.auto_delete_timeout
        if hasattr(self, 'created_at') and self.created_at is not None:
            _dict['created_at'] = datetime_to_string(self.created_at)
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'resource_type') and self.resource_type is not None:
            _dict['resource_type'] = self.resource_type
        if hasattr(self, 'status') and self.status is not None:
            _dict['status'] = self.status
        if hasattr(self, 'updated_at') and self.updated_at is not None:
            _dict['updated_at'] = datetime_to_string(self.updated_at)
        if hasattr(self, 'action_type') and self.action_type is not None:
            _dict['action_type'] = self.action_type
        if hasattr(self, 'cron_spec') and self.cron_spec is not None:
            _dict['cron_spec'] = self.cron_spec
        if hasattr(self, 'last_applied_at') and self.last_applied_at is not None:
            _dict['last_applied_at'] = datetime_to_string(self.last_applied_at)
        if hasattr(self, 'next_run_at') and self.next_run_at is not None:
            _dict['next_run_at'] = datetime_to_string(self.next_run_at)
        if hasattr(self, 'manager') and self.manager is not None:
            if isinstance(self.manager, dict):
                _dict['manager'] = self.manager
            else:
                _dict['manager'] = self.manager.to_dict()
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceGroupManagerActionScheduledActionManagerTarget object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceGroupManagerActionScheduledActionManagerTarget') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceGroupManagerActionScheduledActionManagerTarget') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        INSTANCE_GROUP_MANAGER_ACTION = 'instance_group_manager_action'


    class StatusEnum(str, Enum):
        """
        The status of the instance group action
        - `active`: Action is ready to be run
        - `completed`: Action was completed successfully
        - `failed`: Action could not be completed successfully
        - `incompatible`: Action parameters are not compatible with the group or manager
        - `omitted`: Action was not applied because this action's manager was disabled.
        """

        ACTIVE = 'active'
        COMPLETED = 'completed'
        FAILED = 'failed'
        INCOMPATIBLE = 'incompatible'
        OMITTED = 'omitted'


    class ActionTypeEnum(str, Enum):
        """
        The type of action for the instance group.
        """

        SCHEDULED = 'scheduled'



class InstanceGroupManagerScheduledActionManagerPrototypeAutoScalePrototypeByHref(InstanceGroupManagerScheduledActionManagerPrototypeAutoScalePrototype):
    """
    InstanceGroupManagerScheduledActionManagerPrototypeAutoScalePrototypeByHref.

    :attr int max_membership_count: (optional) The desired maximum number of
          instance group members at the scheduled time.
    :attr int min_membership_count: (optional) The desired minimum number of
          instance group members at the scheduled time.
    :attr str href: The URL for this instance group manager.
    """

    def __init__(
        self,
        href: str,
        *,
        max_membership_count: int = None,
        min_membership_count: int = None,
    ) -> None:
        """
        Initialize a InstanceGroupManagerScheduledActionManagerPrototypeAutoScalePrototypeByHref object.

        :param str href: The URL for this instance group manager.
        :param int max_membership_count: (optional) The desired maximum number of
               instance group members at the scheduled time.
        :param int min_membership_count: (optional) The desired minimum number of
               instance group members at the scheduled time.
        """
        # pylint: disable=super-init-not-called
        self.max_membership_count = max_membership_count
        self.min_membership_count = min_membership_count
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceGroupManagerScheduledActionManagerPrototypeAutoScalePrototypeByHref':
        """Initialize a InstanceGroupManagerScheduledActionManagerPrototypeAutoScalePrototypeByHref object from a json dictionary."""
        args = {}
        if 'max_membership_count' in _dict:
            args['max_membership_count'] = _dict.get('max_membership_count')
        if 'min_membership_count' in _dict:
            args['min_membership_count'] = _dict.get('min_membership_count')
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in InstanceGroupManagerScheduledActionManagerPrototypeAutoScalePrototypeByHref JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceGroupManagerScheduledActionManagerPrototypeAutoScalePrototypeByHref object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'max_membership_count') and self.max_membership_count is not None:
            _dict['max_membership_count'] = self.max_membership_count
        if hasattr(self, 'min_membership_count') and self.min_membership_count is not None:
            _dict['min_membership_count'] = self.min_membership_count
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceGroupManagerScheduledActionManagerPrototypeAutoScalePrototypeByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceGroupManagerScheduledActionManagerPrototypeAutoScalePrototypeByHref') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceGroupManagerScheduledActionManagerPrototypeAutoScalePrototypeByHref') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceGroupManagerScheduledActionManagerPrototypeAutoScalePrototypeById(InstanceGroupManagerScheduledActionManagerPrototypeAutoScalePrototype):
    """
    InstanceGroupManagerScheduledActionManagerPrototypeAutoScalePrototypeById.

    :attr int max_membership_count: (optional) The desired maximum number of
          instance group members at the scheduled time.
    :attr int min_membership_count: (optional) The desired minimum number of
          instance group members at the scheduled time.
    :attr str id: The unique identifier for this instance group manager.
    """

    def __init__(
        self,
        id: str,
        *,
        max_membership_count: int = None,
        min_membership_count: int = None,
    ) -> None:
        """
        Initialize a InstanceGroupManagerScheduledActionManagerPrototypeAutoScalePrototypeById object.

        :param str id: The unique identifier for this instance group manager.
        :param int max_membership_count: (optional) The desired maximum number of
               instance group members at the scheduled time.
        :param int min_membership_count: (optional) The desired minimum number of
               instance group members at the scheduled time.
        """
        # pylint: disable=super-init-not-called
        self.max_membership_count = max_membership_count
        self.min_membership_count = min_membership_count
        self.id = id

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceGroupManagerScheduledActionManagerPrototypeAutoScalePrototypeById':
        """Initialize a InstanceGroupManagerScheduledActionManagerPrototypeAutoScalePrototypeById object from a json dictionary."""
        args = {}
        if 'max_membership_count' in _dict:
            args['max_membership_count'] = _dict.get('max_membership_count')
        if 'min_membership_count' in _dict:
            args['min_membership_count'] = _dict.get('min_membership_count')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in InstanceGroupManagerScheduledActionManagerPrototypeAutoScalePrototypeById JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceGroupManagerScheduledActionManagerPrototypeAutoScalePrototypeById object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'max_membership_count') and self.max_membership_count is not None:
            _dict['max_membership_count'] = self.max_membership_count
        if hasattr(self, 'min_membership_count') and self.min_membership_count is not None:
            _dict['min_membership_count'] = self.min_membership_count
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceGroupManagerScheduledActionManagerPrototypeAutoScalePrototypeById object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceGroupManagerScheduledActionManagerPrototypeAutoScalePrototypeById') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceGroupManagerScheduledActionManagerPrototypeAutoScalePrototypeById') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstancePlacementTargetPatchDedicatedHostGroupIdentityDedicatedHostGroupIdentityByCRN(InstancePlacementTargetPatchDedicatedHostGroupIdentity):
    """
    InstancePlacementTargetPatchDedicatedHostGroupIdentityDedicatedHostGroupIdentityByCRN.

    :attr str crn: The CRN for this dedicated host group.
    """

    def __init__(
        self,
        crn: str,
    ) -> None:
        """
        Initialize a InstancePlacementTargetPatchDedicatedHostGroupIdentityDedicatedHostGroupIdentityByCRN object.

        :param str crn: The CRN for this dedicated host group.
        """
        # pylint: disable=super-init-not-called
        self.crn = crn

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstancePlacementTargetPatchDedicatedHostGroupIdentityDedicatedHostGroupIdentityByCRN':
        """Initialize a InstancePlacementTargetPatchDedicatedHostGroupIdentityDedicatedHostGroupIdentityByCRN object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError('Required property \'crn\' not present in InstancePlacementTargetPatchDedicatedHostGroupIdentityDedicatedHostGroupIdentityByCRN JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstancePlacementTargetPatchDedicatedHostGroupIdentityDedicatedHostGroupIdentityByCRN object from 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 InstancePlacementTargetPatchDedicatedHostGroupIdentityDedicatedHostGroupIdentityByCRN object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstancePlacementTargetPatchDedicatedHostGroupIdentityDedicatedHostGroupIdentityByCRN') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstancePlacementTargetPatchDedicatedHostGroupIdentityDedicatedHostGroupIdentityByCRN') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstancePlacementTargetPatchDedicatedHostGroupIdentityDedicatedHostGroupIdentityByHref(InstancePlacementTargetPatchDedicatedHostGroupIdentity):
    """
    InstancePlacementTargetPatchDedicatedHostGroupIdentityDedicatedHostGroupIdentityByHref.

    :attr str href: The URL for this dedicated host group.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a InstancePlacementTargetPatchDedicatedHostGroupIdentityDedicatedHostGroupIdentityByHref object.

        :param str href: The URL for this dedicated host group.
        """
        # pylint: disable=super-init-not-called
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstancePlacementTargetPatchDedicatedHostGroupIdentityDedicatedHostGroupIdentityByHref':
        """Initialize a InstancePlacementTargetPatchDedicatedHostGroupIdentityDedicatedHostGroupIdentityByHref object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in InstancePlacementTargetPatchDedicatedHostGroupIdentityDedicatedHostGroupIdentityByHref JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstancePlacementTargetPatchDedicatedHostGroupIdentityDedicatedHostGroupIdentityByHref object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(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 InstancePlacementTargetPatchDedicatedHostGroupIdentityDedicatedHostGroupIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstancePlacementTargetPatchDedicatedHostGroupIdentityDedicatedHostGroupIdentityByHref') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstancePlacementTargetPatchDedicatedHostGroupIdentityDedicatedHostGroupIdentityByHref') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstancePlacementTargetPatchDedicatedHostGroupIdentityDedicatedHostGroupIdentityById(InstancePlacementTargetPatchDedicatedHostGroupIdentity):
    """
    InstancePlacementTargetPatchDedicatedHostGroupIdentityDedicatedHostGroupIdentityById.

    :attr str id: The unique identifier for this dedicated host group.
    """

    def __init__(
        self,
        id: str,
    ) -> None:
        """
        Initialize a InstancePlacementTargetPatchDedicatedHostGroupIdentityDedicatedHostGroupIdentityById object.

        :param str id: The unique identifier for this dedicated host group.
        """
        # pylint: disable=super-init-not-called
        self.id = id

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstancePlacementTargetPatchDedicatedHostGroupIdentityDedicatedHostGroupIdentityById':
        """Initialize a InstancePlacementTargetPatchDedicatedHostGroupIdentityDedicatedHostGroupIdentityById object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in InstancePlacementTargetPatchDedicatedHostGroupIdentityDedicatedHostGroupIdentityById JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstancePlacementTargetPatchDedicatedHostGroupIdentityDedicatedHostGroupIdentityById object from 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 InstancePlacementTargetPatchDedicatedHostGroupIdentityDedicatedHostGroupIdentityById object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstancePlacementTargetPatchDedicatedHostGroupIdentityDedicatedHostGroupIdentityById') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstancePlacementTargetPatchDedicatedHostGroupIdentityDedicatedHostGroupIdentityById') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstancePlacementTargetPatchDedicatedHostIdentityDedicatedHostIdentityByCRN(InstancePlacementTargetPatchDedicatedHostIdentity):
    """
    InstancePlacementTargetPatchDedicatedHostIdentityDedicatedHostIdentityByCRN.

    :attr str crn: The CRN for this dedicated host.
    """

    def __init__(
        self,
        crn: str,
    ) -> None:
        """
        Initialize a InstancePlacementTargetPatchDedicatedHostIdentityDedicatedHostIdentityByCRN object.

        :param str crn: The CRN for this dedicated host.
        """
        # pylint: disable=super-init-not-called
        self.crn = crn

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstancePlacementTargetPatchDedicatedHostIdentityDedicatedHostIdentityByCRN':
        """Initialize a InstancePlacementTargetPatchDedicatedHostIdentityDedicatedHostIdentityByCRN object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError('Required property \'crn\' not present in InstancePlacementTargetPatchDedicatedHostIdentityDedicatedHostIdentityByCRN JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstancePlacementTargetPatchDedicatedHostIdentityDedicatedHostIdentityByCRN object from 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 InstancePlacementTargetPatchDedicatedHostIdentityDedicatedHostIdentityByCRN object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstancePlacementTargetPatchDedicatedHostIdentityDedicatedHostIdentityByCRN') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstancePlacementTargetPatchDedicatedHostIdentityDedicatedHostIdentityByCRN') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstancePlacementTargetPatchDedicatedHostIdentityDedicatedHostIdentityByHref(InstancePlacementTargetPatchDedicatedHostIdentity):
    """
    InstancePlacementTargetPatchDedicatedHostIdentityDedicatedHostIdentityByHref.

    :attr str href: The URL for this dedicated host.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a InstancePlacementTargetPatchDedicatedHostIdentityDedicatedHostIdentityByHref object.

        :param str href: The URL for this dedicated host.
        """
        # pylint: disable=super-init-not-called
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstancePlacementTargetPatchDedicatedHostIdentityDedicatedHostIdentityByHref':
        """Initialize a InstancePlacementTargetPatchDedicatedHostIdentityDedicatedHostIdentityByHref object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in InstancePlacementTargetPatchDedicatedHostIdentityDedicatedHostIdentityByHref JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstancePlacementTargetPatchDedicatedHostIdentityDedicatedHostIdentityByHref object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(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 InstancePlacementTargetPatchDedicatedHostIdentityDedicatedHostIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstancePlacementTargetPatchDedicatedHostIdentityDedicatedHostIdentityByHref') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstancePlacementTargetPatchDedicatedHostIdentityDedicatedHostIdentityByHref') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstancePlacementTargetPatchDedicatedHostIdentityDedicatedHostIdentityById(InstancePlacementTargetPatchDedicatedHostIdentity):
    """
    InstancePlacementTargetPatchDedicatedHostIdentityDedicatedHostIdentityById.

    :attr str id: The unique identifier for this dedicated host.
    """

    def __init__(
        self,
        id: str,
    ) -> None:
        """
        Initialize a InstancePlacementTargetPatchDedicatedHostIdentityDedicatedHostIdentityById object.

        :param str id: The unique identifier for this dedicated host.
        """
        # pylint: disable=super-init-not-called
        self.id = id

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstancePlacementTargetPatchDedicatedHostIdentityDedicatedHostIdentityById':
        """Initialize a InstancePlacementTargetPatchDedicatedHostIdentityDedicatedHostIdentityById object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in InstancePlacementTargetPatchDedicatedHostIdentityDedicatedHostIdentityById JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstancePlacementTargetPatchDedicatedHostIdentityDedicatedHostIdentityById object from 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 InstancePlacementTargetPatchDedicatedHostIdentityDedicatedHostIdentityById object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstancePlacementTargetPatchDedicatedHostIdentityDedicatedHostIdentityById') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstancePlacementTargetPatchDedicatedHostIdentityDedicatedHostIdentityById') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstancePlacementTargetPrototypeDedicatedHostGroupIdentityDedicatedHostGroupIdentityByCRN(InstancePlacementTargetPrototypeDedicatedHostGroupIdentity):
    """
    InstancePlacementTargetPrototypeDedicatedHostGroupIdentityDedicatedHostGroupIdentityByCRN.

    :attr str crn: The CRN for this dedicated host group.
    """

    def __init__(
        self,
        crn: str,
    ) -> None:
        """
        Initialize a InstancePlacementTargetPrototypeDedicatedHostGroupIdentityDedicatedHostGroupIdentityByCRN object.

        :param str crn: The CRN for this dedicated host group.
        """
        # pylint: disable=super-init-not-called
        self.crn = crn

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstancePlacementTargetPrototypeDedicatedHostGroupIdentityDedicatedHostGroupIdentityByCRN':
        """Initialize a InstancePlacementTargetPrototypeDedicatedHostGroupIdentityDedicatedHostGroupIdentityByCRN object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError('Required property \'crn\' not present in InstancePlacementTargetPrototypeDedicatedHostGroupIdentityDedicatedHostGroupIdentityByCRN JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstancePlacementTargetPrototypeDedicatedHostGroupIdentityDedicatedHostGroupIdentityByCRN object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstancePlacementTargetPrototypeDedicatedHostGroupIdentityDedicatedHostGroupIdentityByCRN object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstancePlacementTargetPrototypeDedicatedHostGroupIdentityDedicatedHostGroupIdentityByCRN') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstancePlacementTargetPrototypeDedicatedHostGroupIdentityDedicatedHostGroupIdentityByCRN') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstancePlacementTargetPrototypeDedicatedHostGroupIdentityDedicatedHostGroupIdentityByHref(InstancePlacementTargetPrototypeDedicatedHostGroupIdentity):
    """
    InstancePlacementTargetPrototypeDedicatedHostGroupIdentityDedicatedHostGroupIdentityByHref.

    :attr str href: The URL for this dedicated host group.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a InstancePlacementTargetPrototypeDedicatedHostGroupIdentityDedicatedHostGroupIdentityByHref object.

        :param str href: The URL for this dedicated host group.
        """
        # pylint: disable=super-init-not-called
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstancePlacementTargetPrototypeDedicatedHostGroupIdentityDedicatedHostGroupIdentityByHref':
        """Initialize a InstancePlacementTargetPrototypeDedicatedHostGroupIdentityDedicatedHostGroupIdentityByHref object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in InstancePlacementTargetPrototypeDedicatedHostGroupIdentityDedicatedHostGroupIdentityByHref JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstancePlacementTargetPrototypeDedicatedHostGroupIdentityDedicatedHostGroupIdentityByHref object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstancePlacementTargetPrototypeDedicatedHostGroupIdentityDedicatedHostGroupIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstancePlacementTargetPrototypeDedicatedHostGroupIdentityDedicatedHostGroupIdentityByHref') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstancePlacementTargetPrototypeDedicatedHostGroupIdentityDedicatedHostGroupIdentityByHref') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstancePlacementTargetPrototypeDedicatedHostGroupIdentityDedicatedHostGroupIdentityById(InstancePlacementTargetPrototypeDedicatedHostGroupIdentity):
    """
    InstancePlacementTargetPrototypeDedicatedHostGroupIdentityDedicatedHostGroupIdentityById.

    :attr str id: The unique identifier for this dedicated host group.
    """

    def __init__(
        self,
        id: str,
    ) -> None:
        """
        Initialize a InstancePlacementTargetPrototypeDedicatedHostGroupIdentityDedicatedHostGroupIdentityById object.

        :param str id: The unique identifier for this dedicated host group.
        """
        # pylint: disable=super-init-not-called
        self.id = id

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstancePlacementTargetPrototypeDedicatedHostGroupIdentityDedicatedHostGroupIdentityById':
        """Initialize a InstancePlacementTargetPrototypeDedicatedHostGroupIdentityDedicatedHostGroupIdentityById object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in InstancePlacementTargetPrototypeDedicatedHostGroupIdentityDedicatedHostGroupIdentityById JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstancePlacementTargetPrototypeDedicatedHostGroupIdentityDedicatedHostGroupIdentityById object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstancePlacementTargetPrototypeDedicatedHostGroupIdentityDedicatedHostGroupIdentityById object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstancePlacementTargetPrototypeDedicatedHostGroupIdentityDedicatedHostGroupIdentityById') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstancePlacementTargetPrototypeDedicatedHostGroupIdentityDedicatedHostGroupIdentityById') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstancePlacementTargetPrototypeDedicatedHostIdentityDedicatedHostIdentityByCRN(InstancePlacementTargetPrototypeDedicatedHostIdentity):
    """
    InstancePlacementTargetPrototypeDedicatedHostIdentityDedicatedHostIdentityByCRN.

    :attr str crn: The CRN for this dedicated host.
    """

    def __init__(
        self,
        crn: str,
    ) -> None:
        """
        Initialize a InstancePlacementTargetPrototypeDedicatedHostIdentityDedicatedHostIdentityByCRN object.

        :param str crn: The CRN for this dedicated host.
        """
        # pylint: disable=super-init-not-called
        self.crn = crn

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstancePlacementTargetPrototypeDedicatedHostIdentityDedicatedHostIdentityByCRN':
        """Initialize a InstancePlacementTargetPrototypeDedicatedHostIdentityDedicatedHostIdentityByCRN object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError('Required property \'crn\' not present in InstancePlacementTargetPrototypeDedicatedHostIdentityDedicatedHostIdentityByCRN JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstancePlacementTargetPrototypeDedicatedHostIdentityDedicatedHostIdentityByCRN object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstancePlacementTargetPrototypeDedicatedHostIdentityDedicatedHostIdentityByCRN object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstancePlacementTargetPrototypeDedicatedHostIdentityDedicatedHostIdentityByCRN') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstancePlacementTargetPrototypeDedicatedHostIdentityDedicatedHostIdentityByCRN') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstancePlacementTargetPrototypeDedicatedHostIdentityDedicatedHostIdentityByHref(InstancePlacementTargetPrototypeDedicatedHostIdentity):
    """
    InstancePlacementTargetPrototypeDedicatedHostIdentityDedicatedHostIdentityByHref.

    :attr str href: The URL for this dedicated host.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a InstancePlacementTargetPrototypeDedicatedHostIdentityDedicatedHostIdentityByHref object.

        :param str href: The URL for this dedicated host.
        """
        # pylint: disable=super-init-not-called
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstancePlacementTargetPrototypeDedicatedHostIdentityDedicatedHostIdentityByHref':
        """Initialize a InstancePlacementTargetPrototypeDedicatedHostIdentityDedicatedHostIdentityByHref object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in InstancePlacementTargetPrototypeDedicatedHostIdentityDedicatedHostIdentityByHref JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstancePlacementTargetPrototypeDedicatedHostIdentityDedicatedHostIdentityByHref object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstancePlacementTargetPrototypeDedicatedHostIdentityDedicatedHostIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstancePlacementTargetPrototypeDedicatedHostIdentityDedicatedHostIdentityByHref') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstancePlacementTargetPrototypeDedicatedHostIdentityDedicatedHostIdentityByHref') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstancePlacementTargetPrototypeDedicatedHostIdentityDedicatedHostIdentityById(InstancePlacementTargetPrototypeDedicatedHostIdentity):
    """
    InstancePlacementTargetPrototypeDedicatedHostIdentityDedicatedHostIdentityById.

    :attr str id: The unique identifier for this dedicated host.
    """

    def __init__(
        self,
        id: str,
    ) -> None:
        """
        Initialize a InstancePlacementTargetPrototypeDedicatedHostIdentityDedicatedHostIdentityById object.

        :param str id: The unique identifier for this dedicated host.
        """
        # pylint: disable=super-init-not-called
        self.id = id

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstancePlacementTargetPrototypeDedicatedHostIdentityDedicatedHostIdentityById':
        """Initialize a InstancePlacementTargetPrototypeDedicatedHostIdentityDedicatedHostIdentityById object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in InstancePlacementTargetPrototypeDedicatedHostIdentityDedicatedHostIdentityById JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstancePlacementTargetPrototypeDedicatedHostIdentityDedicatedHostIdentityById object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstancePlacementTargetPrototypeDedicatedHostIdentityDedicatedHostIdentityById object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstancePlacementTargetPrototypeDedicatedHostIdentityDedicatedHostIdentityById') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstancePlacementTargetPrototypeDedicatedHostIdentityDedicatedHostIdentityById') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstancePlacementTargetPrototypePlacementGroupIdentityPlacementGroupIdentityByCRN(InstancePlacementTargetPrototypePlacementGroupIdentity):
    """
    InstancePlacementTargetPrototypePlacementGroupIdentityPlacementGroupIdentityByCRN.

    :attr str crn: The CRN for this placement group.
    """

    def __init__(
        self,
        crn: str,
    ) -> None:
        """
        Initialize a InstancePlacementTargetPrototypePlacementGroupIdentityPlacementGroupIdentityByCRN object.

        :param str crn: The CRN for this placement group.
        """
        # pylint: disable=super-init-not-called
        self.crn = crn

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstancePlacementTargetPrototypePlacementGroupIdentityPlacementGroupIdentityByCRN':
        """Initialize a InstancePlacementTargetPrototypePlacementGroupIdentityPlacementGroupIdentityByCRN object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError('Required property \'crn\' not present in InstancePlacementTargetPrototypePlacementGroupIdentityPlacementGroupIdentityByCRN JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstancePlacementTargetPrototypePlacementGroupIdentityPlacementGroupIdentityByCRN object from 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 InstancePlacementTargetPrototypePlacementGroupIdentityPlacementGroupIdentityByCRN object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstancePlacementTargetPrototypePlacementGroupIdentityPlacementGroupIdentityByCRN') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstancePlacementTargetPrototypePlacementGroupIdentityPlacementGroupIdentityByCRN') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstancePlacementTargetPrototypePlacementGroupIdentityPlacementGroupIdentityByHref(InstancePlacementTargetPrototypePlacementGroupIdentity):
    """
    InstancePlacementTargetPrototypePlacementGroupIdentityPlacementGroupIdentityByHref.

    :attr str href: The URL for this placement group.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a InstancePlacementTargetPrototypePlacementGroupIdentityPlacementGroupIdentityByHref object.

        :param str href: The URL for this placement group.
        """
        # pylint: disable=super-init-not-called
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstancePlacementTargetPrototypePlacementGroupIdentityPlacementGroupIdentityByHref':
        """Initialize a InstancePlacementTargetPrototypePlacementGroupIdentityPlacementGroupIdentityByHref object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in InstancePlacementTargetPrototypePlacementGroupIdentityPlacementGroupIdentityByHref JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstancePlacementTargetPrototypePlacementGroupIdentityPlacementGroupIdentityByHref object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(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 InstancePlacementTargetPrototypePlacementGroupIdentityPlacementGroupIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstancePlacementTargetPrototypePlacementGroupIdentityPlacementGroupIdentityByHref') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstancePlacementTargetPrototypePlacementGroupIdentityPlacementGroupIdentityByHref') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstancePlacementTargetPrototypePlacementGroupIdentityPlacementGroupIdentityById(InstancePlacementTargetPrototypePlacementGroupIdentity):
    """
    InstancePlacementTargetPrototypePlacementGroupIdentityPlacementGroupIdentityById.

    :attr str id: The unique identifier for this placement group.
    """

    def __init__(
        self,
        id: str,
    ) -> None:
        """
        Initialize a InstancePlacementTargetPrototypePlacementGroupIdentityPlacementGroupIdentityById object.

        :param str id: The unique identifier for this placement group.
        """
        # pylint: disable=super-init-not-called
        self.id = id

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstancePlacementTargetPrototypePlacementGroupIdentityPlacementGroupIdentityById':
        """Initialize a InstancePlacementTargetPrototypePlacementGroupIdentityPlacementGroupIdentityById object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in InstancePlacementTargetPrototypePlacementGroupIdentityPlacementGroupIdentityById JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstancePlacementTargetPrototypePlacementGroupIdentityPlacementGroupIdentityById object from 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 InstancePlacementTargetPrototypePlacementGroupIdentityPlacementGroupIdentityById object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstancePlacementTargetPrototypePlacementGroupIdentityPlacementGroupIdentityById') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstancePlacementTargetPrototypePlacementGroupIdentityPlacementGroupIdentityById') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class LoadBalancerListenerPolicyTargetPatchLoadBalancerPoolIdentityLoadBalancerPoolIdentityByHref(LoadBalancerListenerPolicyTargetPatchLoadBalancerPoolIdentity):
    """
    LoadBalancerListenerPolicyTargetPatchLoadBalancerPoolIdentityLoadBalancerPoolIdentityByHref.

    :attr str href: The pool's canonical URL.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a LoadBalancerListenerPolicyTargetPatchLoadBalancerPoolIdentityLoadBalancerPoolIdentityByHref object.

        :param str href: The pool's canonical URL.
        """
        # pylint: disable=super-init-not-called
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerListenerPolicyTargetPatchLoadBalancerPoolIdentityLoadBalancerPoolIdentityByHref':
        """Initialize a LoadBalancerListenerPolicyTargetPatchLoadBalancerPoolIdentityLoadBalancerPoolIdentityByHref object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in LoadBalancerListenerPolicyTargetPatchLoadBalancerPoolIdentityLoadBalancerPoolIdentityByHref JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerListenerPolicyTargetPatchLoadBalancerPoolIdentityLoadBalancerPoolIdentityByHref object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancerListenerPolicyTargetPatchLoadBalancerPoolIdentityLoadBalancerPoolIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerListenerPolicyTargetPatchLoadBalancerPoolIdentityLoadBalancerPoolIdentityByHref') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerListenerPolicyTargetPatchLoadBalancerPoolIdentityLoadBalancerPoolIdentityByHref') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class LoadBalancerListenerPolicyTargetPatchLoadBalancerPoolIdentityLoadBalancerPoolIdentityById(LoadBalancerListenerPolicyTargetPatchLoadBalancerPoolIdentity):
    """
    LoadBalancerListenerPolicyTargetPatchLoadBalancerPoolIdentityLoadBalancerPoolIdentityById.

    :attr str id: The unique identifier for this load balancer pool.
    """

    def __init__(
        self,
        id: str,
    ) -> None:
        """
        Initialize a LoadBalancerListenerPolicyTargetPatchLoadBalancerPoolIdentityLoadBalancerPoolIdentityById object.

        :param str id: The unique identifier for this load balancer pool.
        """
        # pylint: disable=super-init-not-called
        self.id = id

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerListenerPolicyTargetPatchLoadBalancerPoolIdentityLoadBalancerPoolIdentityById':
        """Initialize a LoadBalancerListenerPolicyTargetPatchLoadBalancerPoolIdentityLoadBalancerPoolIdentityById object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in LoadBalancerListenerPolicyTargetPatchLoadBalancerPoolIdentityLoadBalancerPoolIdentityById JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerListenerPolicyTargetPatchLoadBalancerPoolIdentityLoadBalancerPoolIdentityById object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancerListenerPolicyTargetPatchLoadBalancerPoolIdentityLoadBalancerPoolIdentityById object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerListenerPolicyTargetPatchLoadBalancerPoolIdentityLoadBalancerPoolIdentityById') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerListenerPolicyTargetPatchLoadBalancerPoolIdentityLoadBalancerPoolIdentityById') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class LoadBalancerListenerPolicyTargetPrototypeLoadBalancerPoolIdentityLoadBalancerPoolIdentityByHref(LoadBalancerListenerPolicyTargetPrototypeLoadBalancerPoolIdentity):
    """
    LoadBalancerListenerPolicyTargetPrototypeLoadBalancerPoolIdentityLoadBalancerPoolIdentityByHref.

    :attr str href: The pool's canonical URL.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a LoadBalancerListenerPolicyTargetPrototypeLoadBalancerPoolIdentityLoadBalancerPoolIdentityByHref object.

        :param str href: The pool's canonical URL.
        """
        # pylint: disable=super-init-not-called
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerListenerPolicyTargetPrototypeLoadBalancerPoolIdentityLoadBalancerPoolIdentityByHref':
        """Initialize a LoadBalancerListenerPolicyTargetPrototypeLoadBalancerPoolIdentityLoadBalancerPoolIdentityByHref object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in LoadBalancerListenerPolicyTargetPrototypeLoadBalancerPoolIdentityLoadBalancerPoolIdentityByHref JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerListenerPolicyTargetPrototypeLoadBalancerPoolIdentityLoadBalancerPoolIdentityByHref object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancerListenerPolicyTargetPrototypeLoadBalancerPoolIdentityLoadBalancerPoolIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerListenerPolicyTargetPrototypeLoadBalancerPoolIdentityLoadBalancerPoolIdentityByHref') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerListenerPolicyTargetPrototypeLoadBalancerPoolIdentityLoadBalancerPoolIdentityByHref') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class LoadBalancerListenerPolicyTargetPrototypeLoadBalancerPoolIdentityLoadBalancerPoolIdentityById(LoadBalancerListenerPolicyTargetPrototypeLoadBalancerPoolIdentity):
    """
    LoadBalancerListenerPolicyTargetPrototypeLoadBalancerPoolIdentityLoadBalancerPoolIdentityById.

    :attr str id: The unique identifier for this load balancer pool.
    """

    def __init__(
        self,
        id: str,
    ) -> None:
        """
        Initialize a LoadBalancerListenerPolicyTargetPrototypeLoadBalancerPoolIdentityLoadBalancerPoolIdentityById object.

        :param str id: The unique identifier for this load balancer pool.
        """
        # pylint: disable=super-init-not-called
        self.id = id

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerListenerPolicyTargetPrototypeLoadBalancerPoolIdentityLoadBalancerPoolIdentityById':
        """Initialize a LoadBalancerListenerPolicyTargetPrototypeLoadBalancerPoolIdentityLoadBalancerPoolIdentityById object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in LoadBalancerListenerPolicyTargetPrototypeLoadBalancerPoolIdentityLoadBalancerPoolIdentityById JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerListenerPolicyTargetPrototypeLoadBalancerPoolIdentityLoadBalancerPoolIdentityById object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancerListenerPolicyTargetPrototypeLoadBalancerPoolIdentityLoadBalancerPoolIdentityById object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerListenerPolicyTargetPrototypeLoadBalancerPoolIdentityLoadBalancerPoolIdentityById') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerListenerPolicyTargetPrototypeLoadBalancerPoolIdentityLoadBalancerPoolIdentityById') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class LoadBalancerPoolMemberTargetPrototypeInstanceIdentityInstanceIdentityByCRN(LoadBalancerPoolMemberTargetPrototypeInstanceIdentity):
    """
    LoadBalancerPoolMemberTargetPrototypeInstanceIdentityInstanceIdentityByCRN.

    :attr str crn: The CRN for this virtual server instance.
    """

    def __init__(
        self,
        crn: str,
    ) -> None:
        """
        Initialize a LoadBalancerPoolMemberTargetPrototypeInstanceIdentityInstanceIdentityByCRN object.

        :param str crn: The CRN for this virtual server instance.
        """
        # pylint: disable=super-init-not-called
        self.crn = crn

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerPoolMemberTargetPrototypeInstanceIdentityInstanceIdentityByCRN':
        """Initialize a LoadBalancerPoolMemberTargetPrototypeInstanceIdentityInstanceIdentityByCRN object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError('Required property \'crn\' not present in LoadBalancerPoolMemberTargetPrototypeInstanceIdentityInstanceIdentityByCRN JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerPoolMemberTargetPrototypeInstanceIdentityInstanceIdentityByCRN object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancerPoolMemberTargetPrototypeInstanceIdentityInstanceIdentityByCRN object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerPoolMemberTargetPrototypeInstanceIdentityInstanceIdentityByCRN') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerPoolMemberTargetPrototypeInstanceIdentityInstanceIdentityByCRN') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class LoadBalancerPoolMemberTargetPrototypeInstanceIdentityInstanceIdentityByHref(LoadBalancerPoolMemberTargetPrototypeInstanceIdentity):
    """
    LoadBalancerPoolMemberTargetPrototypeInstanceIdentityInstanceIdentityByHref.

    :attr str href: The URL for this virtual server instance.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a LoadBalancerPoolMemberTargetPrototypeInstanceIdentityInstanceIdentityByHref object.

        :param str href: The URL for this virtual server instance.
        """
        # pylint: disable=super-init-not-called
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerPoolMemberTargetPrototypeInstanceIdentityInstanceIdentityByHref':
        """Initialize a LoadBalancerPoolMemberTargetPrototypeInstanceIdentityInstanceIdentityByHref object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in LoadBalancerPoolMemberTargetPrototypeInstanceIdentityInstanceIdentityByHref JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerPoolMemberTargetPrototypeInstanceIdentityInstanceIdentityByHref object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancerPoolMemberTargetPrototypeInstanceIdentityInstanceIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerPoolMemberTargetPrototypeInstanceIdentityInstanceIdentityByHref') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerPoolMemberTargetPrototypeInstanceIdentityInstanceIdentityByHref') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class LoadBalancerPoolMemberTargetPrototypeInstanceIdentityInstanceIdentityById(LoadBalancerPoolMemberTargetPrototypeInstanceIdentity):
    """
    LoadBalancerPoolMemberTargetPrototypeInstanceIdentityInstanceIdentityById.

    :attr str id: The unique identifier for this virtual server instance.
    """

    def __init__(
        self,
        id: str,
    ) -> None:
        """
        Initialize a LoadBalancerPoolMemberTargetPrototypeInstanceIdentityInstanceIdentityById object.

        :param str id: The unique identifier for this virtual server instance.
        """
        # pylint: disable=super-init-not-called
        self.id = id

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerPoolMemberTargetPrototypeInstanceIdentityInstanceIdentityById':
        """Initialize a LoadBalancerPoolMemberTargetPrototypeInstanceIdentityInstanceIdentityById object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in LoadBalancerPoolMemberTargetPrototypeInstanceIdentityInstanceIdentityById JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerPoolMemberTargetPrototypeInstanceIdentityInstanceIdentityById object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancerPoolMemberTargetPrototypeInstanceIdentityInstanceIdentityById object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerPoolMemberTargetPrototypeInstanceIdentityInstanceIdentityById') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerPoolMemberTargetPrototypeInstanceIdentityInstanceIdentityById') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class NetworkInterfaceIPPrototypeReservedIPIdentityByHref(NetworkInterfaceIPPrototypeReservedIPIdentity):
    """
    NetworkInterfaceIPPrototypeReservedIPIdentityByHref.

    :attr str href: The URL for this reserved IP.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a NetworkInterfaceIPPrototypeReservedIPIdentityByHref object.

        :param str href: The URL for this reserved IP.
        """
        # pylint: disable=super-init-not-called
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'NetworkInterfaceIPPrototypeReservedIPIdentityByHref':
        """Initialize a NetworkInterfaceIPPrototypeReservedIPIdentityByHref object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in NetworkInterfaceIPPrototypeReservedIPIdentityByHref JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a NetworkInterfaceIPPrototypeReservedIPIdentityByHref object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(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 NetworkInterfaceIPPrototypeReservedIPIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'NetworkInterfaceIPPrototypeReservedIPIdentityByHref') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'NetworkInterfaceIPPrototypeReservedIPIdentityByHref') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class NetworkInterfaceIPPrototypeReservedIPIdentityById(NetworkInterfaceIPPrototypeReservedIPIdentity):
    """
    NetworkInterfaceIPPrototypeReservedIPIdentityById.

    :attr str id: The unique identifier for this reserved IP.
    """

    def __init__(
        self,
        id: str,
    ) -> None:
        """
        Initialize a NetworkInterfaceIPPrototypeReservedIPIdentityById object.

        :param str id: The unique identifier for this reserved IP.
        """
        # pylint: disable=super-init-not-called
        self.id = id

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'NetworkInterfaceIPPrototypeReservedIPIdentityById':
        """Initialize a NetworkInterfaceIPPrototypeReservedIPIdentityById object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in NetworkInterfaceIPPrototypeReservedIPIdentityById JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a NetworkInterfaceIPPrototypeReservedIPIdentityById object from 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 NetworkInterfaceIPPrototypeReservedIPIdentityById object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'NetworkInterfaceIPPrototypeReservedIPIdentityById') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'NetworkInterfaceIPPrototypeReservedIPIdentityById') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class PublicGatewayFloatingIPPrototypeFloatingIPIdentityFloatingIPIdentityByAddress(PublicGatewayFloatingIPPrototypeFloatingIPIdentity):
    """
    PublicGatewayFloatingIPPrototypeFloatingIPIdentityFloatingIPIdentityByAddress.

    :attr str address: The globally unique IP address.
    """

    def __init__(
        self,
        address: str,
    ) -> None:
        """
        Initialize a PublicGatewayFloatingIPPrototypeFloatingIPIdentityFloatingIPIdentityByAddress object.

        :param str address: The globally unique IP address.
        """
        # pylint: disable=super-init-not-called
        self.address = address

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'PublicGatewayFloatingIPPrototypeFloatingIPIdentityFloatingIPIdentityByAddress':
        """Initialize a PublicGatewayFloatingIPPrototypeFloatingIPIdentityFloatingIPIdentityByAddress object from a json dictionary."""
        args = {}
        if 'address' in _dict:
            args['address'] = _dict.get('address')
        else:
            raise ValueError('Required property \'address\' not present in PublicGatewayFloatingIPPrototypeFloatingIPIdentityFloatingIPIdentityByAddress JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a PublicGatewayFloatingIPPrototypeFloatingIPIdentityFloatingIPIdentityByAddress object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'address') and self.address is not None:
            _dict['address'] = self.address
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this PublicGatewayFloatingIPPrototypeFloatingIPIdentityFloatingIPIdentityByAddress object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'PublicGatewayFloatingIPPrototypeFloatingIPIdentityFloatingIPIdentityByAddress') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'PublicGatewayFloatingIPPrototypeFloatingIPIdentityFloatingIPIdentityByAddress') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class PublicGatewayFloatingIPPrototypeFloatingIPIdentityFloatingIPIdentityByCRN(PublicGatewayFloatingIPPrototypeFloatingIPIdentity):
    """
    PublicGatewayFloatingIPPrototypeFloatingIPIdentityFloatingIPIdentityByCRN.

    :attr str crn: The CRN for this floating IP.
    """

    def __init__(
        self,
        crn: str,
    ) -> None:
        """
        Initialize a PublicGatewayFloatingIPPrototypeFloatingIPIdentityFloatingIPIdentityByCRN object.

        :param str crn: The CRN for this floating IP.
        """
        # pylint: disable=super-init-not-called
        self.crn = crn

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'PublicGatewayFloatingIPPrototypeFloatingIPIdentityFloatingIPIdentityByCRN':
        """Initialize a PublicGatewayFloatingIPPrototypeFloatingIPIdentityFloatingIPIdentityByCRN object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError('Required property \'crn\' not present in PublicGatewayFloatingIPPrototypeFloatingIPIdentityFloatingIPIdentityByCRN JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a PublicGatewayFloatingIPPrototypeFloatingIPIdentityFloatingIPIdentityByCRN object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this PublicGatewayFloatingIPPrototypeFloatingIPIdentityFloatingIPIdentityByCRN object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'PublicGatewayFloatingIPPrototypeFloatingIPIdentityFloatingIPIdentityByCRN') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'PublicGatewayFloatingIPPrototypeFloatingIPIdentityFloatingIPIdentityByCRN') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class PublicGatewayFloatingIPPrototypeFloatingIPIdentityFloatingIPIdentityByHref(PublicGatewayFloatingIPPrototypeFloatingIPIdentity):
    """
    PublicGatewayFloatingIPPrototypeFloatingIPIdentityFloatingIPIdentityByHref.

    :attr str href: The URL for this floating IP.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a PublicGatewayFloatingIPPrototypeFloatingIPIdentityFloatingIPIdentityByHref object.

        :param str href: The URL for this floating IP.
        """
        # pylint: disable=super-init-not-called
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'PublicGatewayFloatingIPPrototypeFloatingIPIdentityFloatingIPIdentityByHref':
        """Initialize a PublicGatewayFloatingIPPrototypeFloatingIPIdentityFloatingIPIdentityByHref object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in PublicGatewayFloatingIPPrototypeFloatingIPIdentityFloatingIPIdentityByHref JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a PublicGatewayFloatingIPPrototypeFloatingIPIdentityFloatingIPIdentityByHref object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this PublicGatewayFloatingIPPrototypeFloatingIPIdentityFloatingIPIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'PublicGatewayFloatingIPPrototypeFloatingIPIdentityFloatingIPIdentityByHref') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'PublicGatewayFloatingIPPrototypeFloatingIPIdentityFloatingIPIdentityByHref') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class PublicGatewayFloatingIPPrototypeFloatingIPIdentityFloatingIPIdentityById(PublicGatewayFloatingIPPrototypeFloatingIPIdentity):
    """
    PublicGatewayFloatingIPPrototypeFloatingIPIdentityFloatingIPIdentityById.

    :attr str id: The unique identifier for this floating IP.
    """

    def __init__(
        self,
        id: str,
    ) -> None:
        """
        Initialize a PublicGatewayFloatingIPPrototypeFloatingIPIdentityFloatingIPIdentityById object.

        :param str id: The unique identifier for this floating IP.
        """
        # pylint: disable=super-init-not-called
        self.id = id

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'PublicGatewayFloatingIPPrototypeFloatingIPIdentityFloatingIPIdentityById':
        """Initialize a PublicGatewayFloatingIPPrototypeFloatingIPIdentityFloatingIPIdentityById object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in PublicGatewayFloatingIPPrototypeFloatingIPIdentityFloatingIPIdentityById JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a PublicGatewayFloatingIPPrototypeFloatingIPIdentityFloatingIPIdentityById object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this PublicGatewayFloatingIPPrototypeFloatingIPIdentityFloatingIPIdentityById object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'PublicGatewayFloatingIPPrototypeFloatingIPIdentityFloatingIPIdentityById') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'PublicGatewayFloatingIPPrototypeFloatingIPIdentityFloatingIPIdentityById') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class ReservedIPTargetPrototypeEndpointGatewayIdentityEndpointGatewayIdentityByCRN(ReservedIPTargetPrototypeEndpointGatewayIdentity):
    """
    ReservedIPTargetPrototypeEndpointGatewayIdentityEndpointGatewayIdentityByCRN.

    :attr str crn: The CRN for this endpoint gateway.
    """

    def __init__(
        self,
        crn: str,
    ) -> None:
        """
        Initialize a ReservedIPTargetPrototypeEndpointGatewayIdentityEndpointGatewayIdentityByCRN object.

        :param str crn: The CRN for this endpoint gateway.
        """
        # pylint: disable=super-init-not-called
        self.crn = crn

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ReservedIPTargetPrototypeEndpointGatewayIdentityEndpointGatewayIdentityByCRN':
        """Initialize a ReservedIPTargetPrototypeEndpointGatewayIdentityEndpointGatewayIdentityByCRN object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError('Required property \'crn\' not present in ReservedIPTargetPrototypeEndpointGatewayIdentityEndpointGatewayIdentityByCRN JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ReservedIPTargetPrototypeEndpointGatewayIdentityEndpointGatewayIdentityByCRN object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this ReservedIPTargetPrototypeEndpointGatewayIdentityEndpointGatewayIdentityByCRN object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ReservedIPTargetPrototypeEndpointGatewayIdentityEndpointGatewayIdentityByCRN') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ReservedIPTargetPrototypeEndpointGatewayIdentityEndpointGatewayIdentityByCRN') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class ReservedIPTargetPrototypeEndpointGatewayIdentityEndpointGatewayIdentityByHref(ReservedIPTargetPrototypeEndpointGatewayIdentity):
    """
    ReservedIPTargetPrototypeEndpointGatewayIdentityEndpointGatewayIdentityByHref.

    :attr str href: The URL for this endpoint gateway.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a ReservedIPTargetPrototypeEndpointGatewayIdentityEndpointGatewayIdentityByHref object.

        :param str href: The URL for this endpoint gateway.
        """
        # pylint: disable=super-init-not-called
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ReservedIPTargetPrototypeEndpointGatewayIdentityEndpointGatewayIdentityByHref':
        """Initialize a ReservedIPTargetPrototypeEndpointGatewayIdentityEndpointGatewayIdentityByHref object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in ReservedIPTargetPrototypeEndpointGatewayIdentityEndpointGatewayIdentityByHref JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ReservedIPTargetPrototypeEndpointGatewayIdentityEndpointGatewayIdentityByHref object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this ReservedIPTargetPrototypeEndpointGatewayIdentityEndpointGatewayIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ReservedIPTargetPrototypeEndpointGatewayIdentityEndpointGatewayIdentityByHref') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ReservedIPTargetPrototypeEndpointGatewayIdentityEndpointGatewayIdentityByHref') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class ReservedIPTargetPrototypeEndpointGatewayIdentityEndpointGatewayIdentityById(ReservedIPTargetPrototypeEndpointGatewayIdentity):
    """
    ReservedIPTargetPrototypeEndpointGatewayIdentityEndpointGatewayIdentityById.

    :attr str id: The unique identifier for this endpoint gateway.
    """

    def __init__(
        self,
        id: str,
    ) -> None:
        """
        Initialize a ReservedIPTargetPrototypeEndpointGatewayIdentityEndpointGatewayIdentityById object.

        :param str id: The unique identifier for this endpoint gateway.
        """
        # pylint: disable=super-init-not-called
        self.id = id

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ReservedIPTargetPrototypeEndpointGatewayIdentityEndpointGatewayIdentityById':
        """Initialize a ReservedIPTargetPrototypeEndpointGatewayIdentityEndpointGatewayIdentityById object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in ReservedIPTargetPrototypeEndpointGatewayIdentityEndpointGatewayIdentityById JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ReservedIPTargetPrototypeEndpointGatewayIdentityEndpointGatewayIdentityById object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this ReservedIPTargetPrototypeEndpointGatewayIdentityEndpointGatewayIdentityById object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ReservedIPTargetPrototypeEndpointGatewayIdentityEndpointGatewayIdentityById') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ReservedIPTargetPrototypeEndpointGatewayIdentityEndpointGatewayIdentityById') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class RouteNextHopPatchRouteNextHopIPRouteNextHopIPSentinelIP(RouteNextHopPatchRouteNextHopIP):
    """
    RouteNextHopPatchRouteNextHopIPRouteNextHopIPSentinelIP.

    :attr str address: The sentinel IP address (`0.0.0.0`).
          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 RouteNextHopPatchRouteNextHopIPRouteNextHopIPSentinelIP object.

        :param str address: The sentinel IP address (`0.0.0.0`).
               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) -> 'RouteNextHopPatchRouteNextHopIPRouteNextHopIPSentinelIP':
        """Initialize a RouteNextHopPatchRouteNextHopIPRouteNextHopIPSentinelIP object from a json dictionary."""
        args = {}
        if 'address' in _dict:
            args['address'] = _dict.get('address')
        else:
            raise ValueError('Required property \'address\' not present in RouteNextHopPatchRouteNextHopIPRouteNextHopIPSentinelIP JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a RouteNextHopPatchRouteNextHopIPRouteNextHopIPSentinelIP object from 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 RouteNextHopPatchRouteNextHopIPRouteNextHopIPSentinelIP object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'RouteNextHopPatchRouteNextHopIPRouteNextHopIPSentinelIP') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'RouteNextHopPatchRouteNextHopIPRouteNextHopIPSentinelIP') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class RouteNextHopPatchRouteNextHopIPRouteNextHopIPUnicastIP(RouteNextHopPatchRouteNextHopIP):
    """
    RouteNextHopPatchRouteNextHopIPRouteNextHopIPUnicastIP.

    :attr str address: A unicast IP address, which must not be any of the following
          values:
          - `0.0.0.0` (the sentinel IP address)
          - `224.0.0.0` to `239.255.255.255` (multicast IP addresses)
          - `255.255.255.255` (the broadcast 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 RouteNextHopPatchRouteNextHopIPRouteNextHopIPUnicastIP object.

        :param str address: A unicast IP address, which must not be any of the
               following values:
               - `0.0.0.0` (the sentinel IP address)
               - `224.0.0.0` to `239.255.255.255` (multicast IP addresses)
               - `255.255.255.255` (the broadcast 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) -> 'RouteNextHopPatchRouteNextHopIPRouteNextHopIPUnicastIP':
        """Initialize a RouteNextHopPatchRouteNextHopIPRouteNextHopIPUnicastIP object from a json dictionary."""
        args = {}
        if 'address' in _dict:
            args['address'] = _dict.get('address')
        else:
            raise ValueError('Required property \'address\' not present in RouteNextHopPatchRouteNextHopIPRouteNextHopIPUnicastIP JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a RouteNextHopPatchRouteNextHopIPRouteNextHopIPUnicastIP object from 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 RouteNextHopPatchRouteNextHopIPRouteNextHopIPUnicastIP object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'RouteNextHopPatchRouteNextHopIPRouteNextHopIPUnicastIP') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'RouteNextHopPatchRouteNextHopIPRouteNextHopIPUnicastIP') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class RouteNextHopPatchVPNGatewayConnectionIdentityVPNGatewayConnectionIdentityByHref(RouteNextHopPatchVPNGatewayConnectionIdentity):
    """
    RouteNextHopPatchVPNGatewayConnectionIdentityVPNGatewayConnectionIdentityByHref.

    :attr str href: The VPN connection's canonical URL.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a RouteNextHopPatchVPNGatewayConnectionIdentityVPNGatewayConnectionIdentityByHref object.

        :param str href: The VPN connection's canonical URL.
        """
        # pylint: disable=super-init-not-called
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'RouteNextHopPatchVPNGatewayConnectionIdentityVPNGatewayConnectionIdentityByHref':
        """Initialize a RouteNextHopPatchVPNGatewayConnectionIdentityVPNGatewayConnectionIdentityByHref object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in RouteNextHopPatchVPNGatewayConnectionIdentityVPNGatewayConnectionIdentityByHref JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a RouteNextHopPatchVPNGatewayConnectionIdentityVPNGatewayConnectionIdentityByHref object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(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 RouteNextHopPatchVPNGatewayConnectionIdentityVPNGatewayConnectionIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'RouteNextHopPatchVPNGatewayConnectionIdentityVPNGatewayConnectionIdentityByHref') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'RouteNextHopPatchVPNGatewayConnectionIdentityVPNGatewayConnectionIdentityByHref') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class RouteNextHopPatchVPNGatewayConnectionIdentityVPNGatewayConnectionIdentityById(RouteNextHopPatchVPNGatewayConnectionIdentity):
    """
    RouteNextHopPatchVPNGatewayConnectionIdentityVPNGatewayConnectionIdentityById.

    :attr str id: The unique identifier for this VPN gateway connection.
    """

    def __init__(
        self,
        id: str,
    ) -> None:
        """
        Initialize a RouteNextHopPatchVPNGatewayConnectionIdentityVPNGatewayConnectionIdentityById object.

        :param str id: The unique identifier for this VPN gateway connection.
        """
        # pylint: disable=super-init-not-called
        self.id = id

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'RouteNextHopPatchVPNGatewayConnectionIdentityVPNGatewayConnectionIdentityById':
        """Initialize a RouteNextHopPatchVPNGatewayConnectionIdentityVPNGatewayConnectionIdentityById object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in RouteNextHopPatchVPNGatewayConnectionIdentityVPNGatewayConnectionIdentityById JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a RouteNextHopPatchVPNGatewayConnectionIdentityVPNGatewayConnectionIdentityById object from 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 RouteNextHopPatchVPNGatewayConnectionIdentityVPNGatewayConnectionIdentityById object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'RouteNextHopPatchVPNGatewayConnectionIdentityVPNGatewayConnectionIdentityById') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'RouteNextHopPatchVPNGatewayConnectionIdentityVPNGatewayConnectionIdentityById') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class RoutePrototypeNextHopRouteNextHopPrototypeRouteNextHopIPRouteNextHopPrototypeRouteNextHopIPRouteNextHopIPSentinelIP(RoutePrototypeNextHopRouteNextHopPrototypeRouteNextHopIP):
    """
    RoutePrototypeNextHopRouteNextHopPrototypeRouteNextHopIPRouteNextHopPrototypeRouteNextHopIPRouteNextHopIPSentinelIP.

    :attr str address: The sentinel IP address (`0.0.0.0`).
          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 RoutePrototypeNextHopRouteNextHopPrototypeRouteNextHopIPRouteNextHopPrototypeRouteNextHopIPRouteNextHopIPSentinelIP object.

        :param str address: The sentinel IP address (`0.0.0.0`).
               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) -> 'RoutePrototypeNextHopRouteNextHopPrototypeRouteNextHopIPRouteNextHopPrototypeRouteNextHopIPRouteNextHopIPSentinelIP':
        """Initialize a RoutePrototypeNextHopRouteNextHopPrototypeRouteNextHopIPRouteNextHopPrototypeRouteNextHopIPRouteNextHopIPSentinelIP object from a json dictionary."""
        args = {}
        if 'address' in _dict:
            args['address'] = _dict.get('address')
        else:
            raise ValueError('Required property \'address\' not present in RoutePrototypeNextHopRouteNextHopPrototypeRouteNextHopIPRouteNextHopPrototypeRouteNextHopIPRouteNextHopIPSentinelIP JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a RoutePrototypeNextHopRouteNextHopPrototypeRouteNextHopIPRouteNextHopPrototypeRouteNextHopIPRouteNextHopIPSentinelIP object from 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 RoutePrototypeNextHopRouteNextHopPrototypeRouteNextHopIPRouteNextHopPrototypeRouteNextHopIPRouteNextHopIPSentinelIP object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'RoutePrototypeNextHopRouteNextHopPrototypeRouteNextHopIPRouteNextHopPrototypeRouteNextHopIPRouteNextHopIPSentinelIP') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'RoutePrototypeNextHopRouteNextHopPrototypeRouteNextHopIPRouteNextHopPrototypeRouteNextHopIPRouteNextHopIPSentinelIP') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class RoutePrototypeNextHopRouteNextHopPrototypeRouteNextHopIPRouteNextHopPrototypeRouteNextHopIPRouteNextHopIPUnicastIP(RoutePrototypeNextHopRouteNextHopPrototypeRouteNextHopIP):
    """
    RoutePrototypeNextHopRouteNextHopPrototypeRouteNextHopIPRouteNextHopPrototypeRouteNextHopIPRouteNextHopIPUnicastIP.

    :attr str address: A unicast IP address, which must not be any of the following
          values:
          - `0.0.0.0` (the sentinel IP address)
          - `224.0.0.0` to `239.255.255.255` (multicast IP addresses)
          - `255.255.255.255` (the broadcast 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 RoutePrototypeNextHopRouteNextHopPrototypeRouteNextHopIPRouteNextHopPrototypeRouteNextHopIPRouteNextHopIPUnicastIP object.

        :param str address: A unicast IP address, which must not be any of the
               following values:
               - `0.0.0.0` (the sentinel IP address)
               - `224.0.0.0` to `239.255.255.255` (multicast IP addresses)
               - `255.255.255.255` (the broadcast 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) -> 'RoutePrototypeNextHopRouteNextHopPrototypeRouteNextHopIPRouteNextHopPrototypeRouteNextHopIPRouteNextHopIPUnicastIP':
        """Initialize a RoutePrototypeNextHopRouteNextHopPrototypeRouteNextHopIPRouteNextHopPrototypeRouteNextHopIPRouteNextHopIPUnicastIP object from a json dictionary."""
        args = {}
        if 'address' in _dict:
            args['address'] = _dict.get('address')
        else:
            raise ValueError('Required property \'address\' not present in RoutePrototypeNextHopRouteNextHopPrototypeRouteNextHopIPRouteNextHopPrototypeRouteNextHopIPRouteNextHopIPUnicastIP JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a RoutePrototypeNextHopRouteNextHopPrototypeRouteNextHopIPRouteNextHopPrototypeRouteNextHopIPRouteNextHopIPUnicastIP object from 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 RoutePrototypeNextHopRouteNextHopPrototypeRouteNextHopIPRouteNextHopPrototypeRouteNextHopIPRouteNextHopIPUnicastIP object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'RoutePrototypeNextHopRouteNextHopPrototypeRouteNextHopIPRouteNextHopPrototypeRouteNextHopIPRouteNextHopIPUnicastIP') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'RoutePrototypeNextHopRouteNextHopPrototypeRouteNextHopIPRouteNextHopPrototypeRouteNextHopIPRouteNextHopIPUnicastIP') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class RoutePrototypeNextHopRouteNextHopPrototypeVPNGatewayConnectionIdentityRouteNextHopPrototypeVPNGatewayConnectionIdentityVPNGatewayConnectionIdentityByHref(RoutePrototypeNextHopRouteNextHopPrototypeVPNGatewayConnectionIdentity):
    """
    RoutePrototypeNextHopRouteNextHopPrototypeVPNGatewayConnectionIdentityRouteNextHopPrototypeVPNGatewayConnectionIdentityVPNGatewayConnectionIdentityByHref.

    :attr str href: The VPN connection's canonical URL.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a RoutePrototypeNextHopRouteNextHopPrototypeVPNGatewayConnectionIdentityRouteNextHopPrototypeVPNGatewayConnectionIdentityVPNGatewayConnectionIdentityByHref object.

        :param str href: The VPN connection's canonical URL.
        """
        # pylint: disable=super-init-not-called
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'RoutePrototypeNextHopRouteNextHopPrototypeVPNGatewayConnectionIdentityRouteNextHopPrototypeVPNGatewayConnectionIdentityVPNGatewayConnectionIdentityByHref':
        """Initialize a RoutePrototypeNextHopRouteNextHopPrototypeVPNGatewayConnectionIdentityRouteNextHopPrototypeVPNGatewayConnectionIdentityVPNGatewayConnectionIdentityByHref object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in RoutePrototypeNextHopRouteNextHopPrototypeVPNGatewayConnectionIdentityRouteNextHopPrototypeVPNGatewayConnectionIdentityVPNGatewayConnectionIdentityByHref JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a RoutePrototypeNextHopRouteNextHopPrototypeVPNGatewayConnectionIdentityRouteNextHopPrototypeVPNGatewayConnectionIdentityVPNGatewayConnectionIdentityByHref object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(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 RoutePrototypeNextHopRouteNextHopPrototypeVPNGatewayConnectionIdentityRouteNextHopPrototypeVPNGatewayConnectionIdentityVPNGatewayConnectionIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'RoutePrototypeNextHopRouteNextHopPrototypeVPNGatewayConnectionIdentityRouteNextHopPrototypeVPNGatewayConnectionIdentityVPNGatewayConnectionIdentityByHref') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'RoutePrototypeNextHopRouteNextHopPrototypeVPNGatewayConnectionIdentityRouteNextHopPrototypeVPNGatewayConnectionIdentityVPNGatewayConnectionIdentityByHref') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class RoutePrototypeNextHopRouteNextHopPrototypeVPNGatewayConnectionIdentityRouteNextHopPrototypeVPNGatewayConnectionIdentityVPNGatewayConnectionIdentityById(RoutePrototypeNextHopRouteNextHopPrototypeVPNGatewayConnectionIdentity):
    """
    RoutePrototypeNextHopRouteNextHopPrototypeVPNGatewayConnectionIdentityRouteNextHopPrototypeVPNGatewayConnectionIdentityVPNGatewayConnectionIdentityById.

    :attr str id: The unique identifier for this VPN gateway connection.
    """

    def __init__(
        self,
        id: str,
    ) -> None:
        """
        Initialize a RoutePrototypeNextHopRouteNextHopPrototypeVPNGatewayConnectionIdentityRouteNextHopPrototypeVPNGatewayConnectionIdentityVPNGatewayConnectionIdentityById object.

        :param str id: The unique identifier for this VPN gateway connection.
        """
        # pylint: disable=super-init-not-called
        self.id = id

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'RoutePrototypeNextHopRouteNextHopPrototypeVPNGatewayConnectionIdentityRouteNextHopPrototypeVPNGatewayConnectionIdentityVPNGatewayConnectionIdentityById':
        """Initialize a RoutePrototypeNextHopRouteNextHopPrototypeVPNGatewayConnectionIdentityRouteNextHopPrototypeVPNGatewayConnectionIdentityVPNGatewayConnectionIdentityById object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in RoutePrototypeNextHopRouteNextHopPrototypeVPNGatewayConnectionIdentityRouteNextHopPrototypeVPNGatewayConnectionIdentityVPNGatewayConnectionIdentityById JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a RoutePrototypeNextHopRouteNextHopPrototypeVPNGatewayConnectionIdentityRouteNextHopPrototypeVPNGatewayConnectionIdentityVPNGatewayConnectionIdentityById object from 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 RoutePrototypeNextHopRouteNextHopPrototypeVPNGatewayConnectionIdentityRouteNextHopPrototypeVPNGatewayConnectionIdentityVPNGatewayConnectionIdentityById object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'RoutePrototypeNextHopRouteNextHopPrototypeVPNGatewayConnectionIdentityRouteNextHopPrototypeVPNGatewayConnectionIdentityVPNGatewayConnectionIdentityById') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'RoutePrototypeNextHopRouteNextHopPrototypeVPNGatewayConnectionIdentityRouteNextHopPrototypeVPNGatewayConnectionIdentityVPNGatewayConnectionIdentityById') -> 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 VirtualNetworkInterfacePrimaryIPPrototypeReservedIPIdentityVirtualNetworkInterfacePrimaryIPContextByHref(VirtualNetworkInterfacePrimaryIPPrototypeReservedIPIdentityVirtualNetworkInterfacePrimaryIPContext):
    """
    VirtualNetworkInterfacePrimaryIPPrototypeReservedIPIdentityVirtualNetworkInterfacePrimaryIPContextByHref.

    :attr str href: The URL for this reserved IP.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a VirtualNetworkInterfacePrimaryIPPrototypeReservedIPIdentityVirtualNetworkInterfacePrimaryIPContextByHref object.

        :param str href: The URL for this reserved IP.
        """
        # pylint: disable=super-init-not-called
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VirtualNetworkInterfacePrimaryIPPrototypeReservedIPIdentityVirtualNetworkInterfacePrimaryIPContextByHref':
        """Initialize a VirtualNetworkInterfacePrimaryIPPrototypeReservedIPIdentityVirtualNetworkInterfacePrimaryIPContextByHref object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in VirtualNetworkInterfacePrimaryIPPrototypeReservedIPIdentityVirtualNetworkInterfacePrimaryIPContextByHref JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VirtualNetworkInterfacePrimaryIPPrototypeReservedIPIdentityVirtualNetworkInterfacePrimaryIPContextByHref object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(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 VirtualNetworkInterfacePrimaryIPPrototypeReservedIPIdentityVirtualNetworkInterfacePrimaryIPContextByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VirtualNetworkInterfacePrimaryIPPrototypeReservedIPIdentityVirtualNetworkInterfacePrimaryIPContextByHref') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VirtualNetworkInterfacePrimaryIPPrototypeReservedIPIdentityVirtualNetworkInterfacePrimaryIPContextByHref') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VirtualNetworkInterfacePrimaryIPPrototypeReservedIPIdentityVirtualNetworkInterfacePrimaryIPContextById(VirtualNetworkInterfacePrimaryIPPrototypeReservedIPIdentityVirtualNetworkInterfacePrimaryIPContext):
    """
    VirtualNetworkInterfacePrimaryIPPrototypeReservedIPIdentityVirtualNetworkInterfacePrimaryIPContextById.

    :attr str id: The unique identifier for this reserved IP.
    """

    def __init__(
        self,
        id: str,
    ) -> None:
        """
        Initialize a VirtualNetworkInterfacePrimaryIPPrototypeReservedIPIdentityVirtualNetworkInterfacePrimaryIPContextById object.

        :param str id: The unique identifier for this reserved IP.
        """
        # pylint: disable=super-init-not-called
        self.id = id

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VirtualNetworkInterfacePrimaryIPPrototypeReservedIPIdentityVirtualNetworkInterfacePrimaryIPContextById':
        """Initialize a VirtualNetworkInterfacePrimaryIPPrototypeReservedIPIdentityVirtualNetworkInterfacePrimaryIPContextById object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in VirtualNetworkInterfacePrimaryIPPrototypeReservedIPIdentityVirtualNetworkInterfacePrimaryIPContextById JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VirtualNetworkInterfacePrimaryIPPrototypeReservedIPIdentityVirtualNetworkInterfacePrimaryIPContextById object from 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 VirtualNetworkInterfacePrimaryIPPrototypeReservedIPIdentityVirtualNetworkInterfacePrimaryIPContextById object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VirtualNetworkInterfacePrimaryIPPrototypeReservedIPIdentityVirtualNetworkInterfacePrimaryIPContextById') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VirtualNetworkInterfacePrimaryIPPrototypeReservedIPIdentityVirtualNetworkInterfacePrimaryIPContextById') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VolumeAttachmentPrototypeVolumeVolumeIdentityVolumeIdentityByCRN(VolumeAttachmentPrototypeVolumeVolumeIdentity):
    """
    VolumeAttachmentPrototypeVolumeVolumeIdentityVolumeIdentityByCRN.

    :attr str crn: The CRN for this volume.
    """

    def __init__(
        self,
        crn: str,
    ) -> None:
        """
        Initialize a VolumeAttachmentPrototypeVolumeVolumeIdentityVolumeIdentityByCRN 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) -> 'VolumeAttachmentPrototypeVolumeVolumeIdentityVolumeIdentityByCRN':
        """Initialize a VolumeAttachmentPrototypeVolumeVolumeIdentityVolumeIdentityByCRN object from a json dictionary."""
        args = {}
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        else:
            raise ValueError('Required property \'crn\' not present in VolumeAttachmentPrototypeVolumeVolumeIdentityVolumeIdentityByCRN JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VolumeAttachmentPrototypeVolumeVolumeIdentityVolumeIdentityByCRN object from 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 VolumeAttachmentPrototypeVolumeVolumeIdentityVolumeIdentityByCRN object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VolumeAttachmentPrototypeVolumeVolumeIdentityVolumeIdentityByCRN') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VolumeAttachmentPrototypeVolumeVolumeIdentityVolumeIdentityByCRN') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VolumeAttachmentPrototypeVolumeVolumeIdentityVolumeIdentityByHref(VolumeAttachmentPrototypeVolumeVolumeIdentity):
    """
    VolumeAttachmentPrototypeVolumeVolumeIdentityVolumeIdentityByHref.

    :attr str href: The URL for this volume.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a VolumeAttachmentPrototypeVolumeVolumeIdentityVolumeIdentityByHref 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) -> 'VolumeAttachmentPrototypeVolumeVolumeIdentityVolumeIdentityByHref':
        """Initialize a VolumeAttachmentPrototypeVolumeVolumeIdentityVolumeIdentityByHref object from a json dictionary."""
        args = {}
        if 'href' in _dict:
            args['href'] = _dict.get('href')
        else:
            raise ValueError('Required property \'href\' not present in VolumeAttachmentPrototypeVolumeVolumeIdentityVolumeIdentityByHref JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VolumeAttachmentPrototypeVolumeVolumeIdentityVolumeIdentityByHref object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(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 VolumeAttachmentPrototypeVolumeVolumeIdentityVolumeIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VolumeAttachmentPrototypeVolumeVolumeIdentityVolumeIdentityByHref') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VolumeAttachmentPrototypeVolumeVolumeIdentityVolumeIdentityByHref') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VolumeAttachmentPrototypeVolumeVolumeIdentityVolumeIdentityById(VolumeAttachmentPrototypeVolumeVolumeIdentity):
    """
    VolumeAttachmentPrototypeVolumeVolumeIdentityVolumeIdentityById.

    :attr str id: The unique identifier for this volume.
    """

    def __init__(
        self,
        id: str,
    ) -> None:
        """
        Initialize a VolumeAttachmentPrototypeVolumeVolumeIdentityVolumeIdentityById 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) -> 'VolumeAttachmentPrototypeVolumeVolumeIdentityVolumeIdentityById':
        """Initialize a VolumeAttachmentPrototypeVolumeVolumeIdentityVolumeIdentityById object from a json dictionary."""
        args = {}
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in VolumeAttachmentPrototypeVolumeVolumeIdentityVolumeIdentityById JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VolumeAttachmentPrototypeVolumeVolumeIdentityVolumeIdentityById object from 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 VolumeAttachmentPrototypeVolumeVolumeIdentityVolumeIdentityById object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VolumeAttachmentPrototypeVolumeVolumeIdentityVolumeIdentityById') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VolumeAttachmentPrototypeVolumeVolumeIdentityVolumeIdentityById') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VolumeAttachmentPrototypeVolumeVolumePrototypeInstanceContextVolumePrototypeInstanceContextVolumeByCapacity(VolumeAttachmentPrototypeVolumeVolumePrototypeInstanceContext):
    """
    VolumeAttachmentPrototypeVolumeVolumePrototypeInstanceContextVolumePrototypeInstanceContextVolumeByCapacity.

    :attr int iops: (optional) The maximum I/O operations per second (IOPS) to use
          for this volume. Applicable only to volumes using a profile `family` of
          `custom`.
    :attr str name: (optional) The name for this volume. The name must not be used
          by another volume in the region. If unspecified, the name will be a hyphenated
          list of randomly-selected words.
    :attr VolumeProfileIdentity profile: The
          [profile](https://cloud.ibm.com/docs/vpc?topic=vpc-block-storage-profiles) to
          use for this volume.
    :attr ResourceGroupIdentity resource_group: (optional) The resource group to use
          for this volume. If unspecified, the instance's resource group will be used.
    :attr List[str] user_tags: (optional) The [user
          tags](https://cloud.ibm.com/apidocs/tagging#types-of-tags) associated with this
          volume.
    :attr int capacity: The capacity to use for 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 root key to use to
          wrap the data encryption key for the volume.
          If unspecified, the `encryption` type for the volume will be `provider_managed`.
    """

    def __init__(
        self,
        profile: 'VolumeProfileIdentity',
        capacity: int,
        *,
        iops: int = None,
        name: str = None,
        resource_group: 'ResourceGroupIdentity' = None,
        user_tags: List[str] = None,
        encryption_key: 'EncryptionKeyIdentity' = None,
    ) -> None:
        """
        Initialize a VolumeAttachmentPrototypeVolumeVolumePrototypeInstanceContextVolumePrototypeInstanceContextVolumeByCapacity object.

        :param VolumeProfileIdentity profile: The
               [profile](https://cloud.ibm.com/docs/vpc?topic=vpc-block-storage-profiles)
               to use for this volume.
        :param int capacity: The capacity to use for the volume (in gigabytes). The
               specified minimum and maximum capacity values for creating or updating
               volumes may expand in the future.
        :param int iops: (optional) The maximum I/O operations per second (IOPS) to
               use for this volume. Applicable only to volumes using a profile `family` of
               `custom`.
        :param str name: (optional) The name for this volume. The name must not be
               used by another volume in the region. If unspecified, the name will be a
               hyphenated list of randomly-selected words.
        :param ResourceGroupIdentity resource_group: (optional) The resource group
               to use for this volume. If unspecified, the instance's resource group will
               be used.
        :param List[str] user_tags: (optional) The [user
               tags](https://cloud.ibm.com/apidocs/tagging#types-of-tags) associated with
               this volume.
        :param EncryptionKeyIdentity encryption_key: (optional) The root key to use
               to wrap the data encryption key for the volume.
               If unspecified, the `encryption` type for the volume will be
               `provider_managed`.
        """
        # pylint: disable=super-init-not-called
        self.iops = iops
        self.name = name
        self.profile = profile
        self.resource_group = resource_group
        self.user_tags = user_tags
        self.capacity = capacity
        self.encryption_key = encryption_key

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VolumeAttachmentPrototypeVolumeVolumePrototypeInstanceContextVolumePrototypeInstanceContextVolumeByCapacity':
        """Initialize a VolumeAttachmentPrototypeVolumeVolumePrototypeInstanceContextVolumePrototypeInstanceContextVolumeByCapacity object from a json dictionary."""
        args = {}
        if 'iops' in _dict:
            args['iops'] = _dict.get('iops')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        if 'profile' in _dict:
            args['profile'] = _dict.get('profile')
        else:
            raise ValueError('Required property \'profile\' not present in VolumeAttachmentPrototypeVolumeVolumePrototypeInstanceContextVolumePrototypeInstanceContextVolumeByCapacity JSON')
        if 'resource_group' in _dict:
            args['resource_group'] = _dict.get('resource_group')
        if 'user_tags' in _dict:
            args['user_tags'] = _dict.get('user_tags')
        if 'capacity' in _dict:
            args['capacity'] = _dict.get('capacity')
        else:
            raise ValueError('Required property \'capacity\' not present in VolumeAttachmentPrototypeVolumeVolumePrototypeInstanceContextVolumePrototypeInstanceContextVolumeByCapacity JSON')
        if 'encryption_key' in _dict:
            args['encryption_key'] = _dict.get('encryption_key')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VolumeAttachmentPrototypeVolumeVolumePrototypeInstanceContextVolumePrototypeInstanceContextVolumeByCapacity object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'iops') and self.iops is not None:
            _dict['iops'] = self.iops
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'profile') and self.profile is not None:
            if isinstance(self.profile, dict):
                _dict['profile'] = self.profile
            else:
                _dict['profile'] = self.profile.to_dict()
        if hasattr(self, 'resource_group') and self.resource_group is not None:
            if isinstance(self.resource_group, dict):
                _dict['resource_group'] = self.resource_group
            else:
                _dict['resource_group'] = self.resource_group.to_dict()
        if hasattr(self, 'user_tags') and self.user_tags is not None:
            _dict['user_tags'] = self.user_tags
        if hasattr(self, 'capacity') and self.capacity is not None:
            _dict['capacity'] = self.capacity
        if hasattr(self, 'encryption_key') and self.encryption_key is not None:
            if isinstance(self.encryption_key, dict):
                _dict['encryption_key'] = self.encryption_key
            else:
                _dict['encryption_key'] = self.encryption_key.to_dict()
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VolumeAttachmentPrototypeVolumeVolumePrototypeInstanceContextVolumePrototypeInstanceContextVolumeByCapacity object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VolumeAttachmentPrototypeVolumeVolumePrototypeInstanceContextVolumePrototypeInstanceContextVolumeByCapacity') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VolumeAttachmentPrototypeVolumeVolumePrototypeInstanceContextVolumePrototypeInstanceContextVolumeByCapacity') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VolumeAttachmentPrototypeVolumeVolumePrototypeInstanceContextVolumePrototypeInstanceContextVolumeBySourceSnapshot(VolumeAttachmentPrototypeVolumeVolumePrototypeInstanceContext):
    """
    VolumeAttachmentPrototypeVolumeVolumePrototypeInstanceContextVolumePrototypeInstanceContextVolumeBySourceSnapshot.

    :attr int iops: (optional) The maximum I/O operations per second (IOPS) to use
          for this volume. Applicable only to volumes using a profile `family` of
          `custom`.
    :attr str name: (optional) The name for this volume. The name must not be used
          by another volume in the region. If unspecified, the name will be a hyphenated
          list of randomly-selected words.
    :attr VolumeProfileIdentity profile: The
          [profile](https://cloud.ibm.com/docs/vpc?topic=vpc-block-storage-profiles) to
          use for this volume.
    :attr ResourceGroupIdentity resource_group: (optional) The resource group to use
          for this volume. If unspecified, the instance's resource group will be used.
    :attr List[str] user_tags: (optional) The [user
          tags](https://cloud.ibm.com/apidocs/tagging#types-of-tags) associated with this
          volume.
    :attr int capacity: (optional) The capacity to use for the volume (in
          gigabytes). Must be at least the snapshot's
          `minimum_capacity`. The maximum value may increase in the future.
          If unspecified, the capacity will be the source snapshot's `minimum_capacity`.
    :attr EncryptionKeyIdentity encryption_key: (optional) The root key to use to
          wrap the data encryption key for the volume.
          If unspecified, the `encryption` type for the volume will be `provider_managed`.
    :attr SnapshotIdentity source_snapshot: The snapshot from which to clone the
          volume.
    """

    def __init__(
        self,
        profile: 'VolumeProfileIdentity',
        source_snapshot: 'SnapshotIdentity',
        *,
        iops: int = None,
        name: str = None,
        resource_group: 'ResourceGroupIdentity' = None,
        user_tags: List[str] = None,
        capacity: int = None,
        encryption_key: 'EncryptionKeyIdentity' = None,
    ) -> None:
        """
        Initialize a VolumeAttachmentPrototypeVolumeVolumePrototypeInstanceContextVolumePrototypeInstanceContextVolumeBySourceSnapshot object.

        :param VolumeProfileIdentity profile: The
               [profile](https://cloud.ibm.com/docs/vpc?topic=vpc-block-storage-profiles)
               to use for this volume.
        :param SnapshotIdentity source_snapshot: The snapshot from which to clone
               the volume.
        :param int iops: (optional) The maximum I/O operations per second (IOPS) to
               use for this volume. Applicable only to volumes using a profile `family` of
               `custom`.
        :param str name: (optional) The name for this volume. The name must not be
               used by another volume in the region. If unspecified, the name will be a
               hyphenated list of randomly-selected words.
        :param ResourceGroupIdentity resource_group: (optional) The resource group
               to use for this volume. If unspecified, the instance's resource group will
               be used.
        :param List[str] user_tags: (optional) The [user
               tags](https://cloud.ibm.com/apidocs/tagging#types-of-tags) associated with
               this volume.
        :param int capacity: (optional) The capacity to use for the volume (in
               gigabytes). Must be at least the snapshot's
               `minimum_capacity`. The maximum value may increase in the future.
               If unspecified, the capacity will be the source snapshot's
               `minimum_capacity`.
        :param EncryptionKeyIdentity encryption_key: (optional) The root key to use
               to wrap the data encryption key for the volume.
               If unspecified, the `encryption` type for the volume will be
               `provider_managed`.
        """
        # pylint: disable=super-init-not-called
        self.iops = iops
        self.name = name
        self.profile = profile
        self.resource_group = resource_group
        self.user_tags = user_tags
        self.capacity = capacity
        self.encryption_key = encryption_key
        self.source_snapshot = source_snapshot

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VolumeAttachmentPrototypeVolumeVolumePrototypeInstanceContextVolumePrototypeInstanceContextVolumeBySourceSnapshot':
        """Initialize a VolumeAttachmentPrototypeVolumeVolumePrototypeInstanceContextVolumePrototypeInstanceContextVolumeBySourceSnapshot object from a json dictionary."""
        args = {}
        if 'iops' in _dict:
            args['iops'] = _dict.get('iops')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        if 'profile' in _dict:
            args['profile'] = _dict.get('profile')
        else:
            raise ValueError('Required property \'profile\' not present in VolumeAttachmentPrototypeVolumeVolumePrototypeInstanceContextVolumePrototypeInstanceContextVolumeBySourceSnapshot JSON')
        if 'resource_group' in _dict:
            args['resource_group'] = _dict.get('resource_group')
        if 'user_tags' in _dict:
            args['user_tags'] = _dict.get('user_tags')
        if 'capacity' in _dict:
            args['capacity'] = _dict.get('capacity')
        if 'encryption_key' in _dict:
            args['encryption_key'] = _dict.get('encryption_key')
        if 'source_snapshot' in _dict:
            args['source_snapshot'] = _dict.get('source_snapshot')
        else:
            raise ValueError('Required property \'source_snapshot\' not present in VolumeAttachmentPrototypeVolumeVolumePrototypeInstanceContextVolumePrototypeInstanceContextVolumeBySourceSnapshot JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VolumeAttachmentPrototypeVolumeVolumePrototypeInstanceContextVolumePrototypeInstanceContextVolumeBySourceSnapshot object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'iops') and self.iops is not None:
            _dict['iops'] = self.iops
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'profile') and self.profile is not None:
            if isinstance(self.profile, dict):
                _dict['profile'] = self.profile
            else:
                _dict['profile'] = self.profile.to_dict()
        if hasattr(self, 'resource_group') and self.resource_group is not None:
            if isinstance(self.resource_group, dict):
                _dict['resource_group'] = self.resource_group
            else:
                _dict['resource_group'] = self.resource_group.to_dict()
        if hasattr(self, 'user_tags') and self.user_tags is not None:
            _dict['user_tags'] = self.user_tags
        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, 'source_snapshot') and self.source_snapshot is not None:
            if isinstance(self.source_snapshot, dict):
                _dict['source_snapshot'] = self.source_snapshot
            else:
                _dict['source_snapshot'] = self.source_snapshot.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 VolumeAttachmentPrototypeVolumeVolumePrototypeInstanceContextVolumePrototypeInstanceContextVolumeBySourceSnapshot object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VolumeAttachmentPrototypeVolumeVolumePrototypeInstanceContextVolumePrototypeInstanceContextVolumeBySourceSnapshot') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VolumeAttachmentPrototypeVolumeVolumePrototypeInstanceContextVolumePrototypeInstanceContextVolumeBySourceSnapshot') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceGroupManagerActionPrototypeScheduledActionPrototypeByCronSpecByGroup(InstanceGroupManagerActionPrototypeScheduledActionPrototypeByCronSpec):
    """
    InstanceGroupManagerActionPrototypeScheduledActionPrototypeByCronSpecByGroup.

    :attr str name: (optional) The name for this instance group manager action. The
          name must not be used by another action for the instance group manager. If
          unspecified, the name will be a hyphenated list of randomly-selected words.
    :attr str cron_spec: (optional) The cron specification for a recurring scheduled
          action. Actions can be applied a maximum of one time within a 5 min period.
    :attr InstanceGroupManagerScheduledActionGroupPrototype group:
    """

    def __init__(
        self,
        group: 'InstanceGroupManagerScheduledActionGroupPrototype',
        *,
        name: str = None,
        cron_spec: str = None,
    ) -> None:
        """
        Initialize a InstanceGroupManagerActionPrototypeScheduledActionPrototypeByCronSpecByGroup object.

        :param InstanceGroupManagerScheduledActionGroupPrototype group:
        :param str name: (optional) The name for this instance group manager
               action. The name must not be used by another action for the instance group
               manager. If unspecified, the name will be a hyphenated list of
               randomly-selected words.
        :param str cron_spec: (optional) The cron specification for a recurring
               scheduled action. Actions can be applied a maximum of one time within a 5
               min period.
        """
        # pylint: disable=super-init-not-called
        self.name = name
        self.cron_spec = cron_spec
        self.group = group

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceGroupManagerActionPrototypeScheduledActionPrototypeByCronSpecByGroup':
        """Initialize a InstanceGroupManagerActionPrototypeScheduledActionPrototypeByCronSpecByGroup object from a json dictionary."""
        args = {}
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        if 'cron_spec' in _dict:
            args['cron_spec'] = _dict.get('cron_spec')
        if 'group' in _dict:
            args['group'] = InstanceGroupManagerScheduledActionGroupPrototype.from_dict(_dict.get('group'))
        else:
            raise ValueError('Required property \'group\' not present in InstanceGroupManagerActionPrototypeScheduledActionPrototypeByCronSpecByGroup JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceGroupManagerActionPrototypeScheduledActionPrototypeByCronSpecByGroup object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'cron_spec') and self.cron_spec is not None:
            _dict['cron_spec'] = self.cron_spec
        if hasattr(self, 'group') and self.group is not None:
            if isinstance(self.group, dict):
                _dict['group'] = self.group
            else:
                _dict['group'] = self.group.to_dict()
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceGroupManagerActionPrototypeScheduledActionPrototypeByCronSpecByGroup object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceGroupManagerActionPrototypeScheduledActionPrototypeByCronSpecByGroup') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceGroupManagerActionPrototypeScheduledActionPrototypeByCronSpecByGroup') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceGroupManagerActionPrototypeScheduledActionPrototypeByCronSpecByManager(InstanceGroupManagerActionPrototypeScheduledActionPrototypeByCronSpec):
    """
    InstanceGroupManagerActionPrototypeScheduledActionPrototypeByCronSpecByManager.

    :attr str name: (optional) The name for this instance group manager action. The
          name must not be used by another action for the instance group manager. If
          unspecified, the name will be a hyphenated list of randomly-selected words.
    :attr str cron_spec: (optional) The cron specification for a recurring scheduled
          action. Actions can be applied a maximum of one time within a 5 min period.
    :attr InstanceGroupManagerScheduledActionManagerPrototype manager:
    """

    def __init__(
        self,
        manager: 'InstanceGroupManagerScheduledActionManagerPrototype',
        *,
        name: str = None,
        cron_spec: str = None,
    ) -> None:
        """
        Initialize a InstanceGroupManagerActionPrototypeScheduledActionPrototypeByCronSpecByManager object.

        :param InstanceGroupManagerScheduledActionManagerPrototype manager:
        :param str name: (optional) The name for this instance group manager
               action. The name must not be used by another action for the instance group
               manager. If unspecified, the name will be a hyphenated list of
               randomly-selected words.
        :param str cron_spec: (optional) The cron specification for a recurring
               scheduled action. Actions can be applied a maximum of one time within a 5
               min period.
        """
        # pylint: disable=super-init-not-called
        self.name = name
        self.cron_spec = cron_spec
        self.manager = manager

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceGroupManagerActionPrototypeScheduledActionPrototypeByCronSpecByManager':
        """Initialize a InstanceGroupManagerActionPrototypeScheduledActionPrototypeByCronSpecByManager object from a json dictionary."""
        args = {}
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        if 'cron_spec' in _dict:
            args['cron_spec'] = _dict.get('cron_spec')
        if 'manager' in _dict:
            args['manager'] = _dict.get('manager')
        else:
            raise ValueError('Required property \'manager\' not present in InstanceGroupManagerActionPrototypeScheduledActionPrototypeByCronSpecByManager JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceGroupManagerActionPrototypeScheduledActionPrototypeByCronSpecByManager object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'cron_spec') and self.cron_spec is not None:
            _dict['cron_spec'] = self.cron_spec
        if hasattr(self, 'manager') and self.manager is not None:
            if isinstance(self.manager, dict):
                _dict['manager'] = self.manager
            else:
                _dict['manager'] = self.manager.to_dict()
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceGroupManagerActionPrototypeScheduledActionPrototypeByCronSpecByManager object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceGroupManagerActionPrototypeScheduledActionPrototypeByCronSpecByManager') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceGroupManagerActionPrototypeScheduledActionPrototypeByCronSpecByManager') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceGroupManagerActionPrototypeScheduledActionPrototypeByRunAtByGroup(InstanceGroupManagerActionPrototypeScheduledActionPrototypeByRunAt):
    """
    InstanceGroupManagerActionPrototypeScheduledActionPrototypeByRunAtByGroup.

    :attr str name: (optional) The name for this instance group manager action. The
          name must not be used by another action for the instance group manager. If
          unspecified, the name will be a hyphenated list of randomly-selected words.
    :attr datetime run_at: (optional) The date and time the scheduled action will
          run.
    :attr InstanceGroupManagerScheduledActionGroupPrototype group:
    """

    def __init__(
        self,
        group: 'InstanceGroupManagerScheduledActionGroupPrototype',
        *,
        name: str = None,
        run_at: datetime = None,
    ) -> None:
        """
        Initialize a InstanceGroupManagerActionPrototypeScheduledActionPrototypeByRunAtByGroup object.

        :param InstanceGroupManagerScheduledActionGroupPrototype group:
        :param str name: (optional) The name for this instance group manager
               action. The name must not be used by another action for the instance group
               manager. If unspecified, the name will be a hyphenated list of
               randomly-selected words.
        :param datetime run_at: (optional) The date and time the scheduled action
               will run.
        """
        # pylint: disable=super-init-not-called
        self.name = name
        self.run_at = run_at
        self.group = group

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceGroupManagerActionPrototypeScheduledActionPrototypeByRunAtByGroup':
        """Initialize a InstanceGroupManagerActionPrototypeScheduledActionPrototypeByRunAtByGroup object from a json dictionary."""
        args = {}
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        if 'run_at' in _dict:
            args['run_at'] = string_to_datetime(_dict.get('run_at'))
        if 'group' in _dict:
            args['group'] = InstanceGroupManagerScheduledActionGroupPrototype.from_dict(_dict.get('group'))
        else:
            raise ValueError('Required property \'group\' not present in InstanceGroupManagerActionPrototypeScheduledActionPrototypeByRunAtByGroup JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceGroupManagerActionPrototypeScheduledActionPrototypeByRunAtByGroup object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'run_at') and self.run_at is not None:
            _dict['run_at'] = datetime_to_string(self.run_at)
        if hasattr(self, 'group') and self.group is not None:
            if isinstance(self.group, dict):
                _dict['group'] = self.group
            else:
                _dict['group'] = self.group.to_dict()
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceGroupManagerActionPrototypeScheduledActionPrototypeByRunAtByGroup object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceGroupManagerActionPrototypeScheduledActionPrototypeByRunAtByGroup') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceGroupManagerActionPrototypeScheduledActionPrototypeByRunAtByGroup') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceGroupManagerActionPrototypeScheduledActionPrototypeByRunAtByManager(InstanceGroupManagerActionPrototypeScheduledActionPrototypeByRunAt):
    """
    InstanceGroupManagerActionPrototypeScheduledActionPrototypeByRunAtByManager.

    :attr str name: (optional) The name for this instance group manager action. The
          name must not be used by another action for the instance group manager. If
          unspecified, the name will be a hyphenated list of randomly-selected words.
    :attr datetime run_at: (optional) The date and time the scheduled action will
          run.
    :attr InstanceGroupManagerScheduledActionManagerPrototype manager:
    """

    def __init__(
        self,
        manager: 'InstanceGroupManagerScheduledActionManagerPrototype',
        *,
        name: str = None,
        run_at: datetime = None,
    ) -> None:
        """
        Initialize a InstanceGroupManagerActionPrototypeScheduledActionPrototypeByRunAtByManager object.

        :param InstanceGroupManagerScheduledActionManagerPrototype manager:
        :param str name: (optional) The name for this instance group manager
               action. The name must not be used by another action for the instance group
               manager. If unspecified, the name will be a hyphenated list of
               randomly-selected words.
        :param datetime run_at: (optional) The date and time the scheduled action
               will run.
        """
        # pylint: disable=super-init-not-called
        self.name = name
        self.run_at = run_at
        self.manager = manager

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceGroupManagerActionPrototypeScheduledActionPrototypeByRunAtByManager':
        """Initialize a InstanceGroupManagerActionPrototypeScheduledActionPrototypeByRunAtByManager object from a json dictionary."""
        args = {}
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        if 'run_at' in _dict:
            args['run_at'] = string_to_datetime(_dict.get('run_at'))
        if 'manager' in _dict:
            args['manager'] = _dict.get('manager')
        else:
            raise ValueError('Required property \'manager\' not present in InstanceGroupManagerActionPrototypeScheduledActionPrototypeByRunAtByManager JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceGroupManagerActionPrototypeScheduledActionPrototypeByRunAtByManager object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'run_at') and self.run_at is not None:
            _dict['run_at'] = datetime_to_string(self.run_at)
        if hasattr(self, 'manager') and self.manager is not None:
            if isinstance(self.manager, dict):
                _dict['manager'] = self.manager
            else:
                _dict['manager'] = self.manager.to_dict()
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceGroupManagerActionPrototypeScheduledActionPrototypeByRunAtByManager object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceGroupManagerActionPrototypeScheduledActionPrototypeByRunAtByManager') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceGroupManagerActionPrototypeScheduledActionPrototypeByRunAtByManager') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

##############################################################################
# Pagers
##############################################################################


class VpcsPager:
    """
    VpcsPager can be used to simplify the use of the "list_vpcs" method.
    """

    def __init__(
        self,
        *,
        client: VpcV1,
        limit: int = None,
        resource_group_id: str = None,
        classic_access: bool = None,
    ) -> None:
        """
        Initialize a VpcsPager object.
        :param int limit: (optional) The number of resources to return on a page.
        :param str resource_group_id: (optional) Filters the collection to
               resources with a `resource_group.id` property matching the specified
               identifier.
        :param bool classic_access: (optional) Filters the collection to VPCs with
               a `classic_access` property matching the specified value.
        """
        self._has_next = True
        self._client = client
        self._page_context = {'next': None}
        self._limit = limit
        self._resource_group_id = resource_group_id
        self._classic_access = classic_access

    def has_next(self) -> bool:
        """
        Returns true if there are potentially more results to be retrieved.
        """
        return self._has_next

    def get_next(self) -> List[dict]:
        """
        Returns the next page of results.
        :return: A List[dict], where each element is a dict that represents an instance of VPC.
        :rtype: List[dict]
        """
        if not self.has_next():
            raise StopIteration(message='No more results available')

        result = self._client.list_vpcs(
            limit=self._limit,
            resource_group_id=self._resource_group_id,
            classic_access=self._classic_access,
            start=self._page_context.get('next'),
        ).get_result()

        next = None
        next_page_link = result.get('next')
        if next_page_link is not None:
            next = get_query_param(next_page_link.get('href'), 'start')
        self._page_context['next'] = next
        if next is None:
            self._has_next = False

        return result.get('vpcs')

    def get_all(self) -> List[dict]:
        """
        Returns all results by invoking get_next() repeatedly
        until all pages of results have been retrieved.
        :return: A List[dict], where each element is a dict that represents an instance of VPC.
        :rtype: List[dict]
        """
        results = []
        while self.has_next():
            next_page = self.get_next()
            results.extend(next_page)
        return results


class VpcAddressPrefixesPager:
    """
    VpcAddressPrefixesPager can be used to simplify the use of the "list_vpc_address_prefixes" method.
    """

    def __init__(
        self,
        *,
        client: VpcV1,
        vpc_id: str,
        limit: int = None,
    ) -> None:
        """
        Initialize a VpcAddressPrefixesPager object.
        :param str vpc_id: The VPC identifier.
        :param int limit: (optional) The number of resources to return on a page.
        """
        self._has_next = True
        self._client = client
        self._page_context = {'next': None}
        self._vpc_id = vpc_id
        self._limit = limit

    def has_next(self) -> bool:
        """
        Returns true if there are potentially more results to be retrieved.
        """
        return self._has_next

    def get_next(self) -> List[dict]:
        """
        Returns the next page of results.
        :return: A List[dict], where each element is a dict that represents an instance of AddressPrefix.
        :rtype: List[dict]
        """
        if not self.has_next():
            raise StopIteration(message='No more results available')

        result = self._client.list_vpc_address_prefixes(
            vpc_id=self._vpc_id,
            limit=self._limit,
            start=self._page_context.get('next'),
        ).get_result()

        next = None
        next_page_link = result.get('next')
        if next_page_link is not None:
            next = get_query_param(next_page_link.get('href'), 'start')
        self._page_context['next'] = next
        if next is None:
            self._has_next = False

        return result.get('address_prefixes')

    def get_all(self) -> List[dict]:
        """
        Returns all results by invoking get_next() repeatedly
        until all pages of results have been retrieved.
        :return: A List[dict], where each element is a dict that represents an instance of AddressPrefix.
        :rtype: List[dict]
        """
        results = []
        while self.has_next():
            next_page = self.get_next()
            results.extend(next_page)
        return results


class VpcDnsResolutionBindingsPager:
    """
    VpcDnsResolutionBindingsPager can be used to simplify the use of the "list_vpc_dns_resolution_bindings" method.
    """

    def __init__(
        self,
        *,
        client: VpcV1,
        vpc_id: str,
        sort: str = None,
        limit: int = None,
        name: str = None,
        vpc_crn: str = None,
        vpc_name: str = None,
        account_id: str = None,
    ) -> None:
        """
        Initialize a VpcDnsResolutionBindingsPager object.
        :param str vpc_id: The VPC identifier.
        :param str sort: (optional) Sorts the returned collection by the specified
               property name in ascending order. A `-` may be prepended to the name to
               sort in descending order. For example, the value `-created_at` sorts the
               collection by the `created_at` property in descending order, and the value
               `name` sorts it by the `name` property in ascending order.
        :param int limit: (optional) The number of resources to return on a page.
        :param str name: (optional) Filters the collection to resources with a
               `name` property matching the exact specified name.
        :param str vpc_crn: (optional) Filters the collection to resources with a
               `vpc.crn` property matching the specified CRN.
        :param str vpc_name: (optional) Filters the collection to resources with a
               `vpc.name` property matching the exact specified name.
        :param str account_id: (optional) Filters the collection to resources with
               a `vpc.remote.account.id` property matching the specified account
               identifier.
        """
        self._has_next = True
        self._client = client
        self._page_context = {'next': None}
        self._vpc_id = vpc_id
        self._sort = sort
        self._limit = limit
        self._name = name
        self._vpc_crn = vpc_crn
        self._vpc_name = vpc_name
        self._account_id = account_id

    def has_next(self) -> bool:
        """
        Returns true if there are potentially more results to be retrieved.
        """
        return self._has_next

    def get_next(self) -> List[dict]:
        """
        Returns the next page of results.
        :return: A List[dict], where each element is a dict that represents an instance of VPCDNSResolutionBinding.
        :rtype: List[dict]
        """
        if not self.has_next():
            raise StopIteration(message='No more results available')

        result = self._client.list_vpc_dns_resolution_bindings(
            vpc_id=self._vpc_id,
            sort=self._sort,
            limit=self._limit,
            name=self._name,
            vpc_crn=self._vpc_crn,
            vpc_name=self._vpc_name,
            account_id=self._account_id,
            start=self._page_context.get('next'),
        ).get_result()

        next = None
        next_page_link = result.get('next')
        if next_page_link is not None:
            next = get_query_param(next_page_link.get('href'), 'start')
        self._page_context['next'] = next
        if next is None:
            self._has_next = False

        return result.get('dns_resolution_bindings')

    def get_all(self) -> List[dict]:
        """
        Returns all results by invoking get_next() repeatedly
        until all pages of results have been retrieved.
        :return: A List[dict], where each element is a dict that represents an instance of VPCDNSResolutionBinding.
        :rtype: List[dict]
        """
        results = []
        while self.has_next():
            next_page = self.get_next()
            results.extend(next_page)
        return results


class VpcRoutesPager:
    """
    VpcRoutesPager can be used to simplify the use of the "list_vpc_routes" method.
    """

    def __init__(
        self,
        *,
        client: VpcV1,
        vpc_id: str,
        zone_name: str = None,
        limit: int = None,
    ) -> None:
        """
        Initialize a VpcRoutesPager object.
        :param str vpc_id: The VPC identifier.
        :param str zone_name: (optional) Filters the collection to resources with a
               `zone.name` property matching the exact specified name.
        :param int limit: (optional) The number of resources to return on a page.
        """
        self._has_next = True
        self._client = client
        self._page_context = {'next': None}
        self._vpc_id = vpc_id
        self._zone_name = zone_name
        self._limit = limit

    def has_next(self) -> bool:
        """
        Returns true if there are potentially more results to be retrieved.
        """
        return self._has_next

    def get_next(self) -> List[dict]:
        """
        Returns the next page of results.
        :return: A List[dict], where each element is a dict that represents an instance of RouteCollectionVPCContextRoutesItem.
        :rtype: List[dict]
        """
        if not self.has_next():
            raise StopIteration(message='No more results available')

        result = self._client.list_vpc_routes(
            vpc_id=self._vpc_id,
            zone_name=self._zone_name,
            limit=self._limit,
            start=self._page_context.get('next'),
        ).get_result()

        next = None
        next_page_link = result.get('next')
        if next_page_link is not None:
            next = get_query_param(next_page_link.get('href'), 'start')
        self._page_context['next'] = next
        if next is None:
            self._has_next = False

        return result.get('routes')

    def get_all(self) -> List[dict]:
        """
        Returns all results by invoking get_next() repeatedly
        until all pages of results have been retrieved.
        :return: A List[dict], where each element is a dict that represents an instance of RouteCollectionVPCContextRoutesItem.
        :rtype: List[dict]
        """
        results = []
        while self.has_next():
            next_page = self.get_next()
            results.extend(next_page)
        return results


class VpcRoutingTablesPager:
    """
    VpcRoutingTablesPager can be used to simplify the use of the "list_vpc_routing_tables" method.
    """

    def __init__(
        self,
        *,
        client: VpcV1,
        vpc_id: str,
        limit: int = None,
        is_default: bool = None,
    ) -> None:
        """
        Initialize a VpcRoutingTablesPager object.
        :param str vpc_id: The VPC identifier.
        :param int limit: (optional) The number of resources to return on a page.
        :param bool is_default: (optional) Filters the collection to routing tables
               with an `is_default` property matching the specified value.
        """
        self._has_next = True
        self._client = client
        self._page_context = {'next': None}
        self._vpc_id = vpc_id
        self._limit = limit
        self._is_default = is_default

    def has_next(self) -> bool:
        """
        Returns true if there are potentially more results to be retrieved.
        """
        return self._has_next

    def get_next(self) -> List[dict]:
        """
        Returns the next page of results.
        :return: A List[dict], where each element is a dict that represents an instance of RoutingTable.
        :rtype: List[dict]
        """
        if not self.has_next():
            raise StopIteration(message='No more results available')

        result = self._client.list_vpc_routing_tables(
            vpc_id=self._vpc_id,
            limit=self._limit,
            is_default=self._is_default,
            start=self._page_context.get('next'),
        ).get_result()

        next = None
        next_page_link = result.get('next')
        if next_page_link is not None:
            next = get_query_param(next_page_link.get('href'), 'start')
        self._page_context['next'] = next
        if next is None:
            self._has_next = False

        return result.get('routing_tables')

    def get_all(self) -> List[dict]:
        """
        Returns all results by invoking get_next() repeatedly
        until all pages of results have been retrieved.
        :return: A List[dict], where each element is a dict that represents an instance of RoutingTable.
        :rtype: List[dict]
        """
        results = []
        while self.has_next():
            next_page = self.get_next()
            results.extend(next_page)
        return results


class VpcRoutingTableRoutesPager:
    """
    VpcRoutingTableRoutesPager can be used to simplify the use of the "list_vpc_routing_table_routes" method.
    """

    def __init__(
        self,
        *,
        client: VpcV1,
        vpc_id: str,
        routing_table_id: str,
        limit: int = None,
    ) -> None:
        """
        Initialize a VpcRoutingTableRoutesPager object.
        :param str vpc_id: The VPC identifier.
        :param str routing_table_id: The routing table identifier.
        :param int limit: (optional) The number of resources to return on a page.
        """
        self._has_next = True
        self._client = client
        self._page_context = {'next': None}
        self._vpc_id = vpc_id
        self._routing_table_id = routing_table_id
        self._limit = limit

    def has_next(self) -> bool:
        """
        Returns true if there are potentially more results to be retrieved.
        """
        return self._has_next

    def get_next(self) -> List[dict]:
        """
        Returns the next page of results.
        :return: A List[dict], where each element is a dict that represents an instance of Route.
        :rtype: List[dict]
        """
        if not self.has_next():
            raise StopIteration(message='No more results available')

        result = self._client.list_vpc_routing_table_routes(
            vpc_id=self._vpc_id,
            routing_table_id=self._routing_table_id,
            limit=self._limit,
            start=self._page_context.get('next'),
        ).get_result()

        next = None
        next_page_link = result.get('next')
        if next_page_link is not None:
            next = get_query_param(next_page_link.get('href'), 'start')
        self._page_context['next'] = next
        if next is None:
            self._has_next = False

        return result.get('routes')

    def get_all(self) -> List[dict]:
        """
        Returns all results by invoking get_next() repeatedly
        until all pages of results have been retrieved.
        :return: A List[dict], where each element is a dict that represents an instance of Route.
        :rtype: List[dict]
        """
        results = []
        while self.has_next():
            next_page = self.get_next()
            results.extend(next_page)
        return results


class SubnetsPager:
    """
    SubnetsPager can be used to simplify the use of the "list_subnets" method.
    """

    def __init__(
        self,
        *,
        client: VpcV1,
        limit: int = None,
        resource_group_id: str = None,
        zone_name: str = None,
        vpc_id: str = None,
        vpc_crn: str = None,
        vpc_name: str = None,
        routing_table_id: str = None,
        routing_table_name: str = None,
    ) -> None:
        """
        Initialize a SubnetsPager object.
        :param int limit: (optional) The number of resources to return on a page.
        :param str resource_group_id: (optional) Filters the collection to
               resources with a `resource_group.id` property matching the specified
               identifier.
        :param str zone_name: (optional) Filters the collection to resources with a
               `zone.name` property matching the exact specified name.
        :param str vpc_id: (optional) Filters the collection to resources with a
               `vpc.id` property matching the specified identifier.
        :param str vpc_crn: (optional) Filters the collection to resources with a
               `vpc.crn` property matching the specified CRN.
        :param str vpc_name: (optional) Filters the collection to resources with a
               `vpc.name` property matching the exact specified name.
        :param str routing_table_id: (optional) Filters the collection to subnets
               with a `routing_table.id` property matching the specified identifier.
        :param str routing_table_name: (optional) Filters the collection to subnets
               with a `routing_table.name` property matching the exact specified name.
        """
        self._has_next = True
        self._client = client
        self._page_context = {'next': None}
        self._limit = limit
        self._resource_group_id = resource_group_id
        self._zone_name = zone_name
        self._vpc_id = vpc_id
        self._vpc_crn = vpc_crn
        self._vpc_name = vpc_name
        self._routing_table_id = routing_table_id
        self._routing_table_name = routing_table_name

    def has_next(self) -> bool:
        """
        Returns true if there are potentially more results to be retrieved.
        """
        return self._has_next

    def get_next(self) -> List[dict]:
        """
        Returns the next page of results.
        :return: A List[dict], where each element is a dict that represents an instance of Subnet.
        :rtype: List[dict]
        """
        if not self.has_next():
            raise StopIteration(message='No more results available')

        result = self._client.list_subnets(
            limit=self._limit,
            resource_group_id=self._resource_group_id,
            zone_name=self._zone_name,
            vpc_id=self._vpc_id,
            vpc_crn=self._vpc_crn,
            vpc_name=self._vpc_name,
            routing_table_id=self._routing_table_id,
            routing_table_name=self._routing_table_name,
            start=self._page_context.get('next'),
        ).get_result()

        next = None
        next_page_link = result.get('next')
        if next_page_link is not None:
            next = get_query_param(next_page_link.get('href'), 'start')
        self._page_context['next'] = next
        if next is None:
            self._has_next = False

        return result.get('subnets')

    def get_all(self) -> List[dict]:
        """
        Returns all results by invoking get_next() repeatedly
        until all pages of results have been retrieved.
        :return: A List[dict], where each element is a dict that represents an instance of Subnet.
        :rtype: List[dict]
        """
        results = []
        while self.has_next():
            next_page = self.get_next()
            results.extend(next_page)
        return results


class SubnetReservedIpsPager:
    """
    SubnetReservedIpsPager can be used to simplify the use of the "list_subnet_reserved_ips" method.
    """

    def __init__(
        self,
        *,
        client: VpcV1,
        subnet_id: str,
        limit: int = None,
        sort: str = None,
    ) -> None:
        """
        Initialize a SubnetReservedIpsPager object.
        :param str subnet_id: The subnet identifier.
        :param int limit: (optional) The number of resources to return on a page.
        :param str sort: (optional) Sorts the returned collection by the specified
               property name in ascending order. A `-` may be prepended to the name to
               sort in descending order. For example, the value `-created_at` sorts the
               collection by the `created_at` property in descending order, and the value
               `name` sorts it by the `name` property in ascending order.
        """
        self._has_next = True
        self._client = client
        self._page_context = {'next': None}
        self._subnet_id = subnet_id
        self._limit = limit
        self._sort = sort

    def has_next(self) -> bool:
        """
        Returns true if there are potentially more results to be retrieved.
        """
        return self._has_next

    def get_next(self) -> List[dict]:
        """
        Returns the next page of results.
        :return: A List[dict], where each element is a dict that represents an instance of ReservedIP.
        :rtype: List[dict]
        """
        if not self.has_next():
            raise StopIteration(message='No more results available')

        result = self._client.list_subnet_reserved_ips(
            subnet_id=self._subnet_id,
            limit=self._limit,
            sort=self._sort,
            start=self._page_context.get('next'),
        ).get_result()

        next = None
        next_page_link = result.get('next')
        if next_page_link is not None:
            next = get_query_param(next_page_link.get('href'), 'start')
        self._page_context['next'] = next
        if next is None:
            self._has_next = False

        return result.get('reserved_ips')

    def get_all(self) -> List[dict]:
        """
        Returns all results by invoking get_next() repeatedly
        until all pages of results have been retrieved.
        :return: A List[dict], where each element is a dict that represents an instance of ReservedIP.
        :rtype: List[dict]
        """
        results = []
        while self.has_next():
            next_page = self.get_next()
            results.extend(next_page)
        return results


class ImagesPager:
    """
    ImagesPager can be used to simplify the use of the "list_images" method.
    """

    def __init__(
        self,
        *,
        client: VpcV1,
        limit: int = None,
        resource_group_id: str = None,
        name: str = None,
        status: List[str] = None,
        visibility: str = None,
    ) -> None:
        """
        Initialize a ImagesPager object.
        :param int limit: (optional) The number of resources to return on a page.
        :param str resource_group_id: (optional) Filters the collection to
               resources with a `resource_group.id` property matching the specified
               identifier.
        :param str name: (optional) Filters the collection to resources with a
               `name` property matching the exact specified name.
        :param List[str] status: (optional) Filters the collection to images with a
               `status` property matching one of the specified comma-separated values.
        :param str visibility: (optional) Filters the collection to images with a
               `visibility` property matching the specified value.
        """
        self._has_next = True
        self._client = client
        self._page_context = {'next': None}
        self._limit = limit
        self._resource_group_id = resource_group_id
        self._name = name
        self._status = status
        self._visibility = visibility

    def has_next(self) -> bool:
        """
        Returns true if there are potentially more results to be retrieved.
        """
        return self._has_next

    def get_next(self) -> List[dict]:
        """
        Returns the next page of results.
        :return: A List[dict], where each element is a dict that represents an instance of Image.
        :rtype: List[dict]
        """
        if not self.has_next():
            raise StopIteration(message='No more results available')

        result = self._client.list_images(
            limit=self._limit,
            resource_group_id=self._resource_group_id,
            name=self._name,
            status=self._status,
            visibility=self._visibility,
            start=self._page_context.get('next'),
        ).get_result()

        next = None
        next_page_link = result.get('next')
        if next_page_link is not None:
            next = get_query_param(next_page_link.get('href'), 'start')
        self._page_context['next'] = next
        if next is None:
            self._has_next = False

        return result.get('images')

    def get_all(self) -> List[dict]:
        """
        Returns all results by invoking get_next() repeatedly
        until all pages of results have been retrieved.
        :return: A List[dict], where each element is a dict that represents an instance of Image.
        :rtype: List[dict]
        """
        results = []
        while self.has_next():
            next_page = self.get_next()
            results.extend(next_page)
        return results


class OperatingSystemsPager:
    """
    OperatingSystemsPager can be used to simplify the use of the "list_operating_systems" method.
    """

    def __init__(
        self,
        *,
        client: VpcV1,
        limit: int = None,
    ) -> None:
        """
        Initialize a OperatingSystemsPager object.
        :param int limit: (optional) The number of resources to return on a page.
        """
        self._has_next = True
        self._client = client
        self._page_context = {'next': None}
        self._limit = limit

    def has_next(self) -> bool:
        """
        Returns true if there are potentially more results to be retrieved.
        """
        return self._has_next

    def get_next(self) -> List[dict]:
        """
        Returns the next page of results.
        :return: A List[dict], where each element is a dict that represents an instance of OperatingSystem.
        :rtype: List[dict]
        """
        if not self.has_next():
            raise StopIteration(message='No more results available')

        result = self._client.list_operating_systems(
            limit=self._limit,
            start=self._page_context.get('next'),
        ).get_result()

        next = None
        next_page_link = result.get('next')
        if next_page_link is not None:
            next = get_query_param(next_page_link.get('href'), 'start')
        self._page_context['next'] = next
        if next is None:
            self._has_next = False

        return result.get('operating_systems')

    def get_all(self) -> List[dict]:
        """
        Returns all results by invoking get_next() repeatedly
        until all pages of results have been retrieved.
        :return: A List[dict], where each element is a dict that represents an instance of OperatingSystem.
        :rtype: List[dict]
        """
        results = []
        while self.has_next():
            next_page = self.get_next()
            results.extend(next_page)
        return results


class KeysPager:
    """
    KeysPager can be used to simplify the use of the "list_keys" method.
    """

    def __init__(
        self,
        *,
        client: VpcV1,
        limit: int = None,
    ) -> None:
        """
        Initialize a KeysPager object.
        :param int limit: (optional) The number of resources to return on a page.
        """
        self._has_next = True
        self._client = client
        self._page_context = {'next': None}
        self._limit = limit

    def has_next(self) -> bool:
        """
        Returns true if there are potentially more results to be retrieved.
        """
        return self._has_next

    def get_next(self) -> List[dict]:
        """
        Returns the next page of results.
        :return: A List[dict], where each element is a dict that represents an instance of Key.
        :rtype: List[dict]
        """
        if not self.has_next():
            raise StopIteration(message='No more results available')

        result = self._client.list_keys(
            limit=self._limit,
            start=self._page_context.get('next'),
        ).get_result()

        next = None
        next_page_link = result.get('next')
        if next_page_link is not None:
            next = get_query_param(next_page_link.get('href'), 'start')
        self._page_context['next'] = next
        if next is None:
            self._has_next = False

        return result.get('keys')

    def get_all(self) -> List[dict]:
        """
        Returns all results by invoking get_next() repeatedly
        until all pages of results have been retrieved.
        :return: A List[dict], where each element is a dict that represents an instance of Key.
        :rtype: List[dict]
        """
        results = []
        while self.has_next():
            next_page = self.get_next()
            results.extend(next_page)
        return results


class InstancesPager:
    """
    InstancesPager can be used to simplify the use of the "list_instances" method.
    """

    def __init__(
        self,
        *,
        client: VpcV1,
        limit: int = None,
        resource_group_id: str = None,
        name: str = None,
        vpc_id: str = None,
        vpc_crn: str = None,
        vpc_name: str = None,
        dedicated_host_id: str = None,
        dedicated_host_crn: str = None,
        dedicated_host_name: str = None,
        placement_group_id: str = None,
        placement_group_crn: str = None,
        placement_group_name: str = None,
    ) -> None:
        """
        Initialize a InstancesPager object.
        :param int limit: (optional) The number of resources to return on a page.
        :param str resource_group_id: (optional) Filters the collection to
               resources with a `resource_group.id` property matching the specified
               identifier.
        :param str name: (optional) Filters the collection to resources with a
               `name` property matching the exact specified name.
        :param str vpc_id: (optional) Filters the collection to resources with a
               `vpc.id` property matching the specified identifier.
        :param str vpc_crn: (optional) Filters the collection to resources with a
               `vpc.crn` property matching the specified CRN.
        :param str vpc_name: (optional) Filters the collection to resources with a
               `vpc.name` property matching the exact specified name.
        :param str dedicated_host_id: (optional) Filters the collection to
               instances with a `dedicated_host.id` property matching the specified
               identifier.
        :param str dedicated_host_crn: (optional) Filters the collection to
               instances with a `dedicated_host.crn` property matching the specified CRN.
        :param str dedicated_host_name: (optional) Filters the collection to
               instances with a `dedicated_host.name` property matching the exact
               specified name.
        :param str placement_group_id: (optional) Filters the collection to
               instances with a `placement_target.id` property matching the specified
               placement group identifier.
        :param str placement_group_crn: (optional) Filters the collection to
               instances with a `placement_target.crn` property matching the specified
               placement group CRN.
        :param str placement_group_name: (optional) Filters the collection to
               instances with a `placement_target.name` property matching the exact
               specified placement group name.
        """
        self._has_next = True
        self._client = client
        self._page_context = {'next': None}
        self._limit = limit
        self._resource_group_id = resource_group_id
        self._name = name
        self._vpc_id = vpc_id
        self._vpc_crn = vpc_crn
        self._vpc_name = vpc_name
        self._dedicated_host_id = dedicated_host_id
        self._dedicated_host_crn = dedicated_host_crn
        self._dedicated_host_name = dedicated_host_name
        self._placement_group_id = placement_group_id
        self._placement_group_crn = placement_group_crn
        self._placement_group_name = placement_group_name

    def has_next(self) -> bool:
        """
        Returns true if there are potentially more results to be retrieved.
        """
        return self._has_next

    def get_next(self) -> List[dict]:
        """
        Returns the next page of results.
        :return: A List[dict], where each element is a dict that represents an instance of Instance.
        :rtype: List[dict]
        """
        if not self.has_next():
            raise StopIteration(message='No more results available')

        result = self._client.list_instances(
            limit=self._limit,
            resource_group_id=self._resource_group_id,
            name=self._name,
            vpc_id=self._vpc_id,
            vpc_crn=self._vpc_crn,
            vpc_name=self._vpc_name,
            dedicated_host_id=self._dedicated_host_id,
            dedicated_host_crn=self._dedicated_host_crn,
            dedicated_host_name=self._dedicated_host_name,
            placement_group_id=self._placement_group_id,
            placement_group_crn=self._placement_group_crn,
            placement_group_name=self._placement_group_name,
            start=self._page_context.get('next'),
        ).get_result()

        next = None
        next_page_link = result.get('next')
        if next_page_link is not None:
            next = get_query_param(next_page_link.get('href'), 'start')
        self._page_context['next'] = next
        if next is None:
            self._has_next = False

        return result.get('instances')

    def get_all(self) -> List[dict]:
        """
        Returns all results by invoking get_next() repeatedly
        until all pages of results have been retrieved.
        :return: A List[dict], where each element is a dict that represents an instance of Instance.
        :rtype: List[dict]
        """
        results = []
        while self.has_next():
            next_page = self.get_next()
            results.extend(next_page)
        return results


class InstanceNetworkInterfaceIpsPager:
    """
    InstanceNetworkInterfaceIpsPager can be used to simplify the use of the "list_instance_network_interface_ips" method.
    """

    def __init__(
        self,
        *,
        client: VpcV1,
        instance_id: str,
        network_interface_id: str,
        limit: int = None,
    ) -> None:
        """
        Initialize a InstanceNetworkInterfaceIpsPager object.
        :param str instance_id: The virtual server instance identifier.
        :param str network_interface_id: The instance network interface identifier.
        :param int limit: (optional) The number of resources to return on a page.
        """
        self._has_next = True
        self._client = client
        self._page_context = {'next': None}
        self._instance_id = instance_id
        self._network_interface_id = network_interface_id
        self._limit = limit

    def has_next(self) -> bool:
        """
        Returns true if there are potentially more results to be retrieved.
        """
        return self._has_next

    def get_next(self) -> List[dict]:
        """
        Returns the next page of results.
        :return: A List[dict], where each element is a dict that represents an instance of ReservedIP.
        :rtype: List[dict]
        """
        if not self.has_next():
            raise StopIteration(message='No more results available')

        result = self._client.list_instance_network_interface_ips(
            instance_id=self._instance_id,
            network_interface_id=self._network_interface_id,
            limit=self._limit,
            start=self._page_context.get('next'),
        ).get_result()

        next = None
        next_page_link = result.get('next')
        if next_page_link is not None:
            next = get_query_param(next_page_link.get('href'), 'start')
        self._page_context['next'] = next
        if next is None:
            self._has_next = False

        return result.get('ips')

    def get_all(self) -> List[dict]:
        """
        Returns all results by invoking get_next() repeatedly
        until all pages of results have been retrieved.
        :return: A List[dict], where each element is a dict that represents an instance of ReservedIP.
        :rtype: List[dict]
        """
        results = []
        while self.has_next():
            next_page = self.get_next()
            results.extend(next_page)
        return results


class InstanceGroupsPager:
    """
    InstanceGroupsPager can be used to simplify the use of the "list_instance_groups" method.
    """

    def __init__(
        self,
        *,
        client: VpcV1,
        limit: int = None,
    ) -> None:
        """
        Initialize a InstanceGroupsPager object.
        :param int limit: (optional) The number of resources to return on a page.
        """
        self._has_next = True
        self._client = client
        self._page_context = {'next': None}
        self._limit = limit

    def has_next(self) -> bool:
        """
        Returns true if there are potentially more results to be retrieved.
        """
        return self._has_next

    def get_next(self) -> List[dict]:
        """
        Returns the next page of results.
        :return: A List[dict], where each element is a dict that represents an instance of InstanceGroup.
        :rtype: List[dict]
        """
        if not self.has_next():
            raise StopIteration(message='No more results available')

        result = self._client.list_instance_groups(
            limit=self._limit,
            start=self._page_context.get('next'),
        ).get_result()

        next = None
        next_page_link = result.get('next')
        if next_page_link is not None:
            next = get_query_param(next_page_link.get('href'), 'start')
        self._page_context['next'] = next
        if next is None:
            self._has_next = False

        return result.get('instance_groups')

    def get_all(self) -> List[dict]:
        """
        Returns all results by invoking get_next() repeatedly
        until all pages of results have been retrieved.
        :return: A List[dict], where each element is a dict that represents an instance of InstanceGroup.
        :rtype: List[dict]
        """
        results = []
        while self.has_next():
            next_page = self.get_next()
            results.extend(next_page)
        return results


class InstanceGroupManagersPager:
    """
    InstanceGroupManagersPager can be used to simplify the use of the "list_instance_group_managers" method.
    """

    def __init__(
        self,
        *,
        client: VpcV1,
        instance_group_id: str,
        limit: int = None,
    ) -> None:
        """
        Initialize a InstanceGroupManagersPager object.
        :param str instance_group_id: The instance group identifier.
        :param int limit: (optional) The number of resources to return on a page.
        """
        self._has_next = True
        self._client = client
        self._page_context = {'next': None}
        self._instance_group_id = instance_group_id
        self._limit = limit

    def has_next(self) -> bool:
        """
        Returns true if there are potentially more results to be retrieved.
        """
        return self._has_next

    def get_next(self) -> List[dict]:
        """
        Returns the next page of results.
        :return: A List[dict], where each element is a dict that represents an instance of InstanceGroupManager.
        :rtype: List[dict]
        """
        if not self.has_next():
            raise StopIteration(message='No more results available')

        result = self._client.list_instance_group_managers(
            instance_group_id=self._instance_group_id,
            limit=self._limit,
            start=self._page_context.get('next'),
        ).get_result()

        next = None
        next_page_link = result.get('next')
        if next_page_link is not None:
            next = get_query_param(next_page_link.get('href'), 'start')
        self._page_context['next'] = next
        if next is None:
            self._has_next = False

        return result.get('managers')

    def get_all(self) -> List[dict]:
        """
        Returns all results by invoking get_next() repeatedly
        until all pages of results have been retrieved.
        :return: A List[dict], where each element is a dict that represents an instance of InstanceGroupManager.
        :rtype: List[dict]
        """
        results = []
        while self.has_next():
            next_page = self.get_next()
            results.extend(next_page)
        return results


class InstanceGroupManagerActionsPager:
    """
    InstanceGroupManagerActionsPager can be used to simplify the use of the "list_instance_group_manager_actions" method.
    """

    def __init__(
        self,
        *,
        client: VpcV1,
        instance_group_id: str,
        instance_group_manager_id: str,
        limit: int = None,
    ) -> None:
        """
        Initialize a InstanceGroupManagerActionsPager object.
        :param str instance_group_id: The instance group identifier.
        :param str instance_group_manager_id: The instance group manager
               identifier.
        :param int limit: (optional) The number of resources to return on a page.
        """
        self._has_next = True
        self._client = client
        self._page_context = {'next': None}
        self._instance_group_id = instance_group_id
        self._instance_group_manager_id = instance_group_manager_id
        self._limit = limit

    def has_next(self) -> bool:
        """
        Returns true if there are potentially more results to be retrieved.
        """
        return self._has_next

    def get_next(self) -> List[dict]:
        """
        Returns the next page of results.
        :return: A List[dict], where each element is a dict that represents an instance of InstanceGroupManagerAction.
        :rtype: List[dict]
        """
        if not self.has_next():
            raise StopIteration(message='No more results available')

        result = self._client.list_instance_group_manager_actions(
            instance_group_id=self._instance_group_id,
            instance_group_manager_id=self._instance_group_manager_id,
            limit=self._limit,
            start=self._page_context.get('next'),
        ).get_result()

        next = None
        next_page_link = result.get('next')
        if next_page_link is not None:
            next = get_query_param(next_page_link.get('href'), 'start')
        self._page_context['next'] = next
        if next is None:
            self._has_next = False

        return result.get('actions')

    def get_all(self) -> List[dict]:
        """
        Returns all results by invoking get_next() repeatedly
        until all pages of results have been retrieved.
        :return: A List[dict], where each element is a dict that represents an instance of InstanceGroupManagerAction.
        :rtype: List[dict]
        """
        results = []
        while self.has_next():
            next_page = self.get_next()
            results.extend(next_page)
        return results


class InstanceGroupManagerPoliciesPager:
    """
    InstanceGroupManagerPoliciesPager can be used to simplify the use of the "list_instance_group_manager_policies" method.
    """

    def __init__(
        self,
        *,
        client: VpcV1,
        instance_group_id: str,
        instance_group_manager_id: str,
        limit: int = None,
    ) -> None:
        """
        Initialize a InstanceGroupManagerPoliciesPager object.
        :param str instance_group_id: The instance group identifier.
        :param str instance_group_manager_id: The instance group manager
               identifier.
        :param int limit: (optional) The number of resources to return on a page.
        """
        self._has_next = True
        self._client = client
        self._page_context = {'next': None}
        self._instance_group_id = instance_group_id
        self._instance_group_manager_id = instance_group_manager_id
        self._limit = limit

    def has_next(self) -> bool:
        """
        Returns true if there are potentially more results to be retrieved.
        """
        return self._has_next

    def get_next(self) -> List[dict]:
        """
        Returns the next page of results.
        :return: A List[dict], where each element is a dict that represents an instance of InstanceGroupManagerPolicy.
        :rtype: List[dict]
        """
        if not self.has_next():
            raise StopIteration(message='No more results available')

        result = self._client.list_instance_group_manager_policies(
            instance_group_id=self._instance_group_id,
            instance_group_manager_id=self._instance_group_manager_id,
            limit=self._limit,
            start=self._page_context.get('next'),
        ).get_result()

        next = None
        next_page_link = result.get('next')
        if next_page_link is not None:
            next = get_query_param(next_page_link.get('href'), 'start')
        self._page_context['next'] = next
        if next is None:
            self._has_next = False

        return result.get('policies')

    def get_all(self) -> List[dict]:
        """
        Returns all results by invoking get_next() repeatedly
        until all pages of results have been retrieved.
        :return: A List[dict], where each element is a dict that represents an instance of InstanceGroupManagerPolicy.
        :rtype: List[dict]
        """
        results = []
        while self.has_next():
            next_page = self.get_next()
            results.extend(next_page)
        return results


class InstanceGroupMembershipsPager:
    """
    InstanceGroupMembershipsPager can be used to simplify the use of the "list_instance_group_memberships" method.
    """

    def __init__(
        self,
        *,
        client: VpcV1,
        instance_group_id: str,
        limit: int = None,
    ) -> None:
        """
        Initialize a InstanceGroupMembershipsPager object.
        :param str instance_group_id: The instance group identifier.
        :param int limit: (optional) The number of resources to return on a page.
        """
        self._has_next = True
        self._client = client
        self._page_context = {'next': None}
        self._instance_group_id = instance_group_id
        self._limit = limit

    def has_next(self) -> bool:
        """
        Returns true if there are potentially more results to be retrieved.
        """
        return self._has_next

    def get_next(self) -> List[dict]:
        """
        Returns the next page of results.
        :return: A List[dict], where each element is a dict that represents an instance of InstanceGroupMembership.
        :rtype: List[dict]
        """
        if not self.has_next():
            raise StopIteration(message='No more results available')

        result = self._client.list_instance_group_memberships(
            instance_group_id=self._instance_group_id,
            limit=self._limit,
            start=self._page_context.get('next'),
        ).get_result()

        next = None
        next_page_link = result.get('next')
        if next_page_link is not None:
            next = get_query_param(next_page_link.get('href'), 'start')
        self._page_context['next'] = next
        if next is None:
            self._has_next = False

        return result.get('memberships')

    def get_all(self) -> List[dict]:
        """
        Returns all results by invoking get_next() repeatedly
        until all pages of results have been retrieved.
        :return: A List[dict], where each element is a dict that represents an instance of InstanceGroupMembership.
        :rtype: List[dict]
        """
        results = []
        while self.has_next():
            next_page = self.get_next()
            results.extend(next_page)
        return results


class DedicatedHostGroupsPager:
    """
    DedicatedHostGroupsPager can be used to simplify the use of the "list_dedicated_host_groups" method.
    """

    def __init__(
        self,
        *,
        client: VpcV1,
        limit: int = None,
        resource_group_id: str = None,
        zone_name: str = None,
        name: str = None,
    ) -> None:
        """
        Initialize a DedicatedHostGroupsPager object.
        :param int limit: (optional) The number of resources to return on a page.
        :param str resource_group_id: (optional) Filters the collection to
               resources with a `resource_group.id` property matching the specified
               identifier.
        :param str zone_name: (optional) Filters the collection to resources with a
               `zone.name` property matching the exact specified name.
        :param str name: (optional) Filters the collection to resources with a
               `name` property matching the exact specified name.
        """
        self._has_next = True
        self._client = client
        self._page_context = {'next': None}
        self._limit = limit
        self._resource_group_id = resource_group_id
        self._zone_name = zone_name
        self._name = name

    def has_next(self) -> bool:
        """
        Returns true if there are potentially more results to be retrieved.
        """
        return self._has_next

    def get_next(self) -> List[dict]:
        """
        Returns the next page of results.
        :return: A List[dict], where each element is a dict that represents an instance of DedicatedHostGroup.
        :rtype: List[dict]
        """
        if not self.has_next():
            raise StopIteration(message='No more results available')

        result = self._client.list_dedicated_host_groups(
            limit=self._limit,
            resource_group_id=self._resource_group_id,
            zone_name=self._zone_name,
            name=self._name,
            start=self._page_context.get('next'),
        ).get_result()

        next = None
        next_page_link = result.get('next')
        if next_page_link is not None:
            next = get_query_param(next_page_link.get('href'), 'start')
        self._page_context['next'] = next
        if next is None:
            self._has_next = False

        return result.get('groups')

    def get_all(self) -> List[dict]:
        """
        Returns all results by invoking get_next() repeatedly
        until all pages of results have been retrieved.
        :return: A List[dict], where each element is a dict that represents an instance of DedicatedHostGroup.
        :rtype: List[dict]
        """
        results = []
        while self.has_next():
            next_page = self.get_next()
            results.extend(next_page)
        return results


class DedicatedHostProfilesPager:
    """
    DedicatedHostProfilesPager can be used to simplify the use of the "list_dedicated_host_profiles" method.
    """

    def __init__(
        self,
        *,
        client: VpcV1,
        limit: int = None,
    ) -> None:
        """
        Initialize a DedicatedHostProfilesPager object.
        :param int limit: (optional) The number of resources to return on a page.
        """
        self._has_next = True
        self._client = client
        self._page_context = {'next': None}
        self._limit = limit

    def has_next(self) -> bool:
        """
        Returns true if there are potentially more results to be retrieved.
        """
        return self._has_next

    def get_next(self) -> List[dict]:
        """
        Returns the next page of results.
        :return: A List[dict], where each element is a dict that represents an instance of DedicatedHostProfile.
        :rtype: List[dict]
        """
        if not self.has_next():
            raise StopIteration(message='No more results available')

        result = self._client.list_dedicated_host_profiles(
            limit=self._limit,
            start=self._page_context.get('next'),
        ).get_result()

        next = None
        next_page_link = result.get('next')
        if next_page_link is not None:
            next = get_query_param(next_page_link.get('href'), 'start')
        self._page_context['next'] = next
        if next is None:
            self._has_next = False

        return result.get('profiles')

    def get_all(self) -> List[dict]:
        """
        Returns all results by invoking get_next() repeatedly
        until all pages of results have been retrieved.
        :return: A List[dict], where each element is a dict that represents an instance of DedicatedHostProfile.
        :rtype: List[dict]
        """
        results = []
        while self.has_next():
            next_page = self.get_next()
            results.extend(next_page)
        return results


class DedicatedHostsPager:
    """
    DedicatedHostsPager can be used to simplify the use of the "list_dedicated_hosts" method.
    """

    def __init__(
        self,
        *,
        client: VpcV1,
        dedicated_host_group_id: str = None,
        limit: int = None,
        resource_group_id: str = None,
        zone_name: str = None,
        name: str = None,
    ) -> None:
        """
        Initialize a DedicatedHostsPager object.
        :param str dedicated_host_group_id: (optional) Filters the collection to
               dedicated hosts with a `group.id` property matching the specified
               identifier.
        :param int limit: (optional) The number of resources to return on a page.
        :param str resource_group_id: (optional) Filters the collection to
               resources with a `resource_group.id` property matching the specified
               identifier.
        :param str zone_name: (optional) Filters the collection to resources with a
               `zone.name` property matching the exact specified name.
        :param str name: (optional) Filters the collection to resources with a
               `name` property matching the exact specified name.
        """
        self._has_next = True
        self._client = client
        self._page_context = {'next': None}
        self._dedicated_host_group_id = dedicated_host_group_id
        self._limit = limit
        self._resource_group_id = resource_group_id
        self._zone_name = zone_name
        self._name = name

    def has_next(self) -> bool:
        """
        Returns true if there are potentially more results to be retrieved.
        """
        return self._has_next

    def get_next(self) -> List[dict]:
        """
        Returns the next page of results.
        :return: A List[dict], where each element is a dict that represents an instance of DedicatedHost.
        :rtype: List[dict]
        """
        if not self.has_next():
            raise StopIteration(message='No more results available')

        result = self._client.list_dedicated_hosts(
            dedicated_host_group_id=self._dedicated_host_group_id,
            limit=self._limit,
            resource_group_id=self._resource_group_id,
            zone_name=self._zone_name,
            name=self._name,
            start=self._page_context.get('next'),
        ).get_result()

        next = None
        next_page_link = result.get('next')
        if next_page_link is not None:
            next = get_query_param(next_page_link.get('href'), 'start')
        self._page_context['next'] = next
        if next is None:
            self._has_next = False

        return result.get('dedicated_hosts')

    def get_all(self) -> List[dict]:
        """
        Returns all results by invoking get_next() repeatedly
        until all pages of results have been retrieved.
        :return: A List[dict], where each element is a dict that represents an instance of DedicatedHost.
        :rtype: List[dict]
        """
        results = []
        while self.has_next():
            next_page = self.get_next()
            results.extend(next_page)
        return results


class BackupPoliciesPager:
    """
    BackupPoliciesPager can be used to simplify the use of the "list_backup_policies" method.
    """

    def __init__(
        self,
        *,
        client: VpcV1,
        limit: int = None,
        resource_group_id: str = None,
        name: str = None,
        tag: str = None,
    ) -> None:
        """
        Initialize a BackupPoliciesPager object.
        :param int limit: (optional) The number of resources to return on a page.
        :param str resource_group_id: (optional) Filters the collection to
               resources with a `resource_group.id` property matching the specified
               identifier.
        :param str name: (optional) Filters the collection to resources with a
               `name` property matching the exact specified name.
        :param str tag: (optional) Filters the collection to resources with an item
               in the `tags` property matching the exact specified tag.
        """
        self._has_next = True
        self._client = client
        self._page_context = {'next': None}
        self._limit = limit
        self._resource_group_id = resource_group_id
        self._name = name
        self._tag = tag

    def has_next(self) -> bool:
        """
        Returns true if there are potentially more results to be retrieved.
        """
        return self._has_next

    def get_next(self) -> List[dict]:
        """
        Returns the next page of results.
        :return: A List[dict], where each element is a dict that represents an instance of BackupPolicy.
        :rtype: List[dict]
        """
        if not self.has_next():
            raise StopIteration(message='No more results available')

        result = self._client.list_backup_policies(
            limit=self._limit,
            resource_group_id=self._resource_group_id,
            name=self._name,
            tag=self._tag,
            start=self._page_context.get('next'),
        ).get_result()

        next = None
        next_page_link = result.get('next')
        if next_page_link is not None:
            next = get_query_param(next_page_link.get('href'), 'start')
        self._page_context['next'] = next
        if next is None:
            self._has_next = False

        return result.get('backup_policies')

    def get_all(self) -> List[dict]:
        """
        Returns all results by invoking get_next() repeatedly
        until all pages of results have been retrieved.
        :return: A List[dict], where each element is a dict that represents an instance of BackupPolicy.
        :rtype: List[dict]
        """
        results = []
        while self.has_next():
            next_page = self.get_next()
            results.extend(next_page)
        return results


class BackupPolicyJobsPager:
    """
    BackupPolicyJobsPager can be used to simplify the use of the "list_backup_policy_jobs" method.
    """

    def __init__(
        self,
        *,
        client: VpcV1,
        backup_policy_id: str,
        status: str = None,
        backup_policy_plan_id: str = None,
        limit: int = None,
        sort: str = None,
        source_id: str = None,
        target_snapshots_id: str = None,
        target_snapshots_crn: str = None,
    ) -> None:
        """
        Initialize a BackupPolicyJobsPager object.
        :param str backup_policy_id: The backup policy identifier.
        :param str status: (optional) Filters the collection to backup policy jobs
               with a `status` property matching the specified value.
        :param str backup_policy_plan_id: (optional) Filters the collection to
               backup policy jobs with a `backup_policy_plan.id` property matching the
               specified identifier.
        :param int limit: (optional) The number of resources to return on a page.
        :param str sort: (optional) Sorts the returned collection by the specified
               property name in ascending order. A `-` may be prepended to the name to
               sort in descending order. For example, the value `-created_at` sorts the
               collection by the `created_at` property in descending order, and the value
               `name` sorts it by the `name` property in ascending order.
        :param str source_id: (optional) Filters the collection to backup policy
               jobs with a `source.id` property matching the specified identifier.
        :param str target_snapshots_id: (optional) Filters the collection to backup
               policy jobs with an item in the `target_snapshots` property with an `id`
               property matching the specified identifier.
        :param str target_snapshots_crn: (optional) Filters the collection to
               backup policy jobs with an item in the `target_snapshots` property with a
               `crn` property matching the specified CRN.
        """
        self._has_next = True
        self._client = client
        self._page_context = {'next': None}
        self._backup_policy_id = backup_policy_id
        self._status = status
        self._backup_policy_plan_id = backup_policy_plan_id
        self._limit = limit
        self._sort = sort
        self._source_id = source_id
        self._target_snapshots_id = target_snapshots_id
        self._target_snapshots_crn = target_snapshots_crn

    def has_next(self) -> bool:
        """
        Returns true if there are potentially more results to be retrieved.
        """
        return self._has_next

    def get_next(self) -> List[dict]:
        """
        Returns the next page of results.
        :return: A List[dict], where each element is a dict that represents an instance of BackupPolicyJob.
        :rtype: List[dict]
        """
        if not self.has_next():
            raise StopIteration(message='No more results available')

        result = self._client.list_backup_policy_jobs(
            backup_policy_id=self._backup_policy_id,
            status=self._status,
            backup_policy_plan_id=self._backup_policy_plan_id,
            limit=self._limit,
            sort=self._sort,
            source_id=self._source_id,
            target_snapshots_id=self._target_snapshots_id,
            target_snapshots_crn=self._target_snapshots_crn,
            start=self._page_context.get('next'),
        ).get_result()

        next = None
        next_page_link = result.get('next')
        if next_page_link is not None:
            next = get_query_param(next_page_link.get('href'), 'start')
        self._page_context['next'] = next
        if next is None:
            self._has_next = False

        return result.get('jobs')

    def get_all(self) -> List[dict]:
        """
        Returns all results by invoking get_next() repeatedly
        until all pages of results have been retrieved.
        :return: A List[dict], where each element is a dict that represents an instance of BackupPolicyJob.
        :rtype: List[dict]
        """
        results = []
        while self.has_next():
            next_page = self.get_next()
            results.extend(next_page)
        return results


class PlacementGroupsPager:
    """
    PlacementGroupsPager can be used to simplify the use of the "list_placement_groups" method.
    """

    def __init__(
        self,
        *,
        client: VpcV1,
        limit: int = None,
    ) -> None:
        """
        Initialize a PlacementGroupsPager object.
        :param int limit: (optional) The number of resources to return on a page.
        """
        self._has_next = True
        self._client = client
        self._page_context = {'next': None}
        self._limit = limit

    def has_next(self) -> bool:
        """
        Returns true if there are potentially more results to be retrieved.
        """
        return self._has_next

    def get_next(self) -> List[dict]:
        """
        Returns the next page of results.
        :return: A List[dict], where each element is a dict that represents an instance of PlacementGroup.
        :rtype: List[dict]
        """
        if not self.has_next():
            raise StopIteration(message='No more results available')

        result = self._client.list_placement_groups(
            limit=self._limit,
            start=self._page_context.get('next'),
        ).get_result()

        next = None
        next_page_link = result.get('next')
        if next_page_link is not None:
            next = get_query_param(next_page_link.get('href'), 'start')
        self._page_context['next'] = next
        if next is None:
            self._has_next = False

        return result.get('placement_groups')

    def get_all(self) -> List[dict]:
        """
        Returns all results by invoking get_next() repeatedly
        until all pages of results have been retrieved.
        :return: A List[dict], where each element is a dict that represents an instance of PlacementGroup.
        :rtype: List[dict]
        """
        results = []
        while self.has_next():
            next_page = self.get_next()
            results.extend(next_page)
        return results


class BareMetalServerProfilesPager:
    """
    BareMetalServerProfilesPager can be used to simplify the use of the "list_bare_metal_server_profiles" method.
    """

    def __init__(
        self,
        *,
        client: VpcV1,
        limit: int = None,
    ) -> None:
        """
        Initialize a BareMetalServerProfilesPager object.
        :param int limit: (optional) The number of resources to return on a page.
        """
        self._has_next = True
        self._client = client
        self._page_context = {'next': None}
        self._limit = limit

    def has_next(self) -> bool:
        """
        Returns true if there are potentially more results to be retrieved.
        """
        return self._has_next

    def get_next(self) -> List[dict]:
        """
        Returns the next page of results.
        :return: A List[dict], where each element is a dict that represents an instance of BareMetalServerProfile.
        :rtype: List[dict]
        """
        if not self.has_next():
            raise StopIteration(message='No more results available')

        result = self._client.list_bare_metal_server_profiles(
            limit=self._limit,
            start=self._page_context.get('next'),
        ).get_result()

        next = None
        next_page_link = result.get('next')
        if next_page_link is not None:
            next = get_query_param(next_page_link.get('href'), 'start')
        self._page_context['next'] = next
        if next is None:
            self._has_next = False

        return result.get('profiles')

    def get_all(self) -> List[dict]:
        """
        Returns all results by invoking get_next() repeatedly
        until all pages of results have been retrieved.
        :return: A List[dict], where each element is a dict that represents an instance of BareMetalServerProfile.
        :rtype: List[dict]
        """
        results = []
        while self.has_next():
            next_page = self.get_next()
            results.extend(next_page)
        return results


class BareMetalServersPager:
    """
    BareMetalServersPager can be used to simplify the use of the "list_bare_metal_servers" method.
    """

    def __init__(
        self,
        *,
        client: VpcV1,
        limit: int = None,
        resource_group_id: str = None,
        name: str = None,
        vpc_id: str = None,
        vpc_crn: str = None,
        vpc_name: str = None,
    ) -> None:
        """
        Initialize a BareMetalServersPager object.
        :param int limit: (optional) The number of resources to return on a page.
        :param str resource_group_id: (optional) Filters the collection to
               resources with a `resource_group.id` property matching the specified
               identifier.
        :param str name: (optional) Filters the collection to resources with a
               `name` property matching the exact specified name.
        :param str vpc_id: (optional) Filters the collection to resources with a
               `vpc.id` property matching the specified identifier.
        :param str vpc_crn: (optional) Filters the collection to resources with a
               `vpc.crn` property matching the specified CRN.
        :param str vpc_name: (optional) Filters the collection to resources with a
               `vpc.name` property matching the exact specified name.
        """
        self._has_next = True
        self._client = client
        self._page_context = {'next': None}
        self._limit = limit
        self._resource_group_id = resource_group_id
        self._name = name
        self._vpc_id = vpc_id
        self._vpc_crn = vpc_crn
        self._vpc_name = vpc_name

    def has_next(self) -> bool:
        """
        Returns true if there are potentially more results to be retrieved.
        """
        return self._has_next

    def get_next(self) -> List[dict]:
        """
        Returns the next page of results.
        :return: A List[dict], where each element is a dict that represents an instance of BareMetalServer.
        :rtype: List[dict]
        """
        if not self.has_next():
            raise StopIteration(message='No more results available')

        result = self._client.list_bare_metal_servers(
            limit=self._limit,
            resource_group_id=self._resource_group_id,
            name=self._name,
            vpc_id=self._vpc_id,
            vpc_crn=self._vpc_crn,
            vpc_name=self._vpc_name,
            start=self._page_context.get('next'),
        ).get_result()

        next = None
        next_page_link = result.get('next')
        if next_page_link is not None:
            next = get_query_param(next_page_link.get('href'), 'start')
        self._page_context['next'] = next
        if next is None:
            self._has_next = False

        return result.get('bare_metal_servers')

    def get_all(self) -> List[dict]:
        """
        Returns all results by invoking get_next() repeatedly
        until all pages of results have been retrieved.
        :return: A List[dict], where each element is a dict that represents an instance of BareMetalServer.
        :rtype: List[dict]
        """
        results = []
        while self.has_next():
            next_page = self.get_next()
            results.extend(next_page)
        return results


class BareMetalServerNetworkInterfacesPager:
    """
    BareMetalServerNetworkInterfacesPager can be used to simplify the use of the "list_bare_metal_server_network_interfaces" method.
    """

    def __init__(
        self,
        *,
        client: VpcV1,
        bare_metal_server_id: str,
        limit: int = None,
    ) -> None:
        """
        Initialize a BareMetalServerNetworkInterfacesPager object.
        :param str bare_metal_server_id: The bare metal server identifier.
        :param int limit: (optional) The number of resources to return on a page.
        """
        self._has_next = True
        self._client = client
        self._page_context = {'next': None}
        self._bare_metal_server_id = bare_metal_server_id
        self._limit = limit

    def has_next(self) -> bool:
        """
        Returns true if there are potentially more results to be retrieved.
        """
        return self._has_next

    def get_next(self) -> List[dict]:
        """
        Returns the next page of results.
        :return: A List[dict], where each element is a dict that represents an instance of BareMetalServerNetworkInterface.
        :rtype: List[dict]
        """
        if not self.has_next():
            raise StopIteration(message='No more results available')

        result = self._client.list_bare_metal_server_network_interfaces(
            bare_metal_server_id=self._bare_metal_server_id,
            limit=self._limit,
            start=self._page_context.get('next'),
        ).get_result()

        next = None
        next_page_link = result.get('next')
        if next_page_link is not None:
            next = get_query_param(next_page_link.get('href'), 'start')
        self._page_context['next'] = next
        if next is None:
            self._has_next = False

        return result.get('network_interfaces')

    def get_all(self) -> List[dict]:
        """
        Returns all results by invoking get_next() repeatedly
        until all pages of results have been retrieved.
        :return: A List[dict], where each element is a dict that represents an instance of BareMetalServerNetworkInterface.
        :rtype: List[dict]
        """
        results = []
        while self.has_next():
            next_page = self.get_next()
            results.extend(next_page)
        return results


class VolumeProfilesPager:
    """
    VolumeProfilesPager can be used to simplify the use of the "list_volume_profiles" method.
    """

    def __init__(
        self,
        *,
        client: VpcV1,
        limit: int = None,
    ) -> None:
        """
        Initialize a VolumeProfilesPager object.
        :param int limit: (optional) The number of resources to return on a page.
        """
        self._has_next = True
        self._client = client
        self._page_context = {'next': None}
        self._limit = limit

    def has_next(self) -> bool:
        """
        Returns true if there are potentially more results to be retrieved.
        """
        return self._has_next

    def get_next(self) -> List[dict]:
        """
        Returns the next page of results.
        :return: A List[dict], where each element is a dict that represents an instance of VolumeProfile.
        :rtype: List[dict]
        """
        if not self.has_next():
            raise StopIteration(message='No more results available')

        result = self._client.list_volume_profiles(
            limit=self._limit,
            start=self._page_context.get('next'),
        ).get_result()

        next = None
        next_page_link = result.get('next')
        if next_page_link is not None:
            next = get_query_param(next_page_link.get('href'), 'start')
        self._page_context['next'] = next
        if next is None:
            self._has_next = False

        return result.get('profiles')

    def get_all(self) -> List[dict]:
        """
        Returns all results by invoking get_next() repeatedly
        until all pages of results have been retrieved.
        :return: A List[dict], where each element is a dict that represents an instance of VolumeProfile.
        :rtype: List[dict]
        """
        results = []
        while self.has_next():
            next_page = self.get_next()
            results.extend(next_page)
        return results


class VolumesPager:
    """
    VolumesPager can be used to simplify the use of the "list_volumes" method.
    """

    def __init__(
        self,
        *,
        client: VpcV1,
        limit: int = None,
        name: str = None,
        attachment_state: str = None,
        encryption: str = None,
        operating_system_family: str = None,
        operating_system_architecture: str = None,
        zone_name: str = None,
    ) -> None:
        """
        Initialize a VolumesPager object.
        :param int limit: (optional) The number of resources to return on a page.
        :param str name: (optional) Filters the collection to resources with a
               `name` property matching the exact specified name.
        :param str attachment_state: (optional) Filters the collection to volumes
               with an `attachment_state` property matching the specified value.
        :param str encryption: (optional) Filters the collection to resources with
               an `encryption` property matching the specified value.
        :param str operating_system_family: (optional) Filters the collection to
               resources with an `operating_system.family` property matching the specified
               operating system family.
               This parameter also supports the values `null` and `not:null` which filter
               the collection to resources which have no operating system or any operating
               system, respectively.
        :param str operating_system_architecture: (optional) Filters the collection
               to resources with an `operating_system.architecture` property matching the
               specified operating system architecture.
               This parameter also supports the values `null` and `not:null` which filter
               the collection to resources which have no operating system or any operating
               system, respectively.
        :param str zone_name: (optional) Filters the collection to resources with a
               `zone.name` property matching the exact specified name.
        """
        self._has_next = True
        self._client = client
        self._page_context = {'next': None}
        self._limit = limit
        self._name = name
        self._attachment_state = attachment_state
        self._encryption = encryption
        self._operating_system_family = operating_system_family
        self._operating_system_architecture = operating_system_architecture
        self._zone_name = zone_name

    def has_next(self) -> bool:
        """
        Returns true if there are potentially more results to be retrieved.
        """
        return self._has_next

    def get_next(self) -> List[dict]:
        """
        Returns the next page of results.
        :return: A List[dict], where each element is a dict that represents an instance of Volume.
        :rtype: List[dict]
        """
        if not self.has_next():
            raise StopIteration(message='No more results available')

        result = self._client.list_volumes(
            limit=self._limit,
            name=self._name,
            attachment_state=self._attachment_state,
            encryption=self._encryption,
            operating_system_family=self._operating_system_family,
            operating_system_architecture=self._operating_system_architecture,
            zone_name=self._zone_name,
            start=self._page_context.get('next'),
        ).get_result()

        next = None
        next_page_link = result.get('next')
        if next_page_link is not None:
            next = get_query_param(next_page_link.get('href'), 'start')
        self._page_context['next'] = next
        if next is None:
            self._has_next = False

        return result.get('volumes')

    def get_all(self) -> List[dict]:
        """
        Returns all results by invoking get_next() repeatedly
        until all pages of results have been retrieved.
        :return: A List[dict], where each element is a dict that represents an instance of Volume.
        :rtype: List[dict]
        """
        results = []
        while self.has_next():
            next_page = self.get_next()
            results.extend(next_page)
        return results


class SnapshotsPager:
    """
    SnapshotsPager can be used to simplify the use of the "list_snapshots" method.
    """

    def __init__(
        self,
        *,
        client: VpcV1,
        limit: int = None,
        tag: str = None,
        resource_group_id: str = None,
        name: str = None,
        source_volume_id: str = None,
        source_volume_crn: str = None,
        source_image_id: str = None,
        source_image_crn: str = None,
        sort: str = None,
        backup_policy_plan_id: str = None,
        copies_id: str = None,
        copies_name: str = None,
        copies_crn: str = None,
        copies_remote_region_name: str = None,
        source_snapshot_id: str = None,
        source_snapshot_remote_region_name: str = None,
        source_volume_remote_region_name: str = None,
        source_image_remote_region_name: str = None,
        clones_zone_name: str = None,
    ) -> None:
        """
        Initialize a SnapshotsPager object.
        :param int limit: (optional) The number of resources to return on a page.
        :param str tag: (optional) Filters the collection to resources with an item
               in the `tags` property matching the exact specified tag.
        :param str resource_group_id: (optional) Filters the collection to
               resources with a `resource_group.id` property matching the specified
               identifier.
        :param str name: (optional) Filters the collection to resources with a
               `name` property matching the exact specified name.
        :param str source_volume_id: (optional) Filters the collection to resources
               with a `source_volume.id` property matching the specified identifier.
        :param str source_volume_crn: (optional) Filters the collection to
               resources with a `source_volume.crn` property matching the specified CRN.
        :param str source_image_id: (optional) Filters the collection to resources
               with a `source_image.id` property matching the specified identifier.
               This parameter also supports the values `null` and `not:null` which filter
               the collection to resources which have no source image or any existent
               source image, respectively.
        :param str source_image_crn: (optional) Filters the collection to resources
               with a `source_image.crn` property matching the specified CRN.
               This parameter also supports the values `null` and `not:null` which filter
               the collection to resources which have no source image or any existent
               source image, respectively.
        :param str sort: (optional) Sorts the returned collection by the specified
               property name in ascending order. A `-` may be prepended to the name to
               sort in descending order. For example, the value `-created_at` sorts the
               collection by the `created_at` property in descending order, and the value
               `name` sorts it by the `name` property in ascending order.
        :param str backup_policy_plan_id: (optional) Filters the collection to
               backup policy jobs with a `backup_policy_plan.id` property matching the
               specified identifier.
        :param str copies_id: (optional) Filters the collection to snapshots with
               an item in the `copies` property with an `id` property matching the
               specified identifier.
        :param str copies_name: (optional) Filters the collection to snapshots with
               an item in the `copies` property with a `name` property matching the exact
               specified name.
        :param str copies_crn: (optional) Filters the collection to snapshots with
               an item in the `copies` property with an `id` property matching the
               specified CRN.
        :param str copies_remote_region_name: (optional) Filters the collection to
               snapshots with an item in the `copies` property with a
               `remote.region.name` property matching the exact specified name.
        :param str source_snapshot_id: (optional) Filters the collection to
               resources with a `source_snapshot.id` property matching the specified
               identifier.
        :param str source_snapshot_remote_region_name: (optional) Filters the
               collection to resources with a `source_snapshot.remote.region.name`
               property matching the exact specified name.
        :param str source_volume_remote_region_name: (optional) Filters the
               collection to resources with a `source_volume.remote.region.name` property
               matching the exact specified name.
        :param str source_image_remote_region_name: (optional) Filters the
               collection to resources with a `source_image.remote.region.name` property
               matching the exact specified name.
        :param str clones_zone_name: (optional) Filters the collection to snapshots
               with an item in the `clones` property with a `zone.name` property matching
               the exact specified name.
        """
        self._has_next = True
        self._client = client
        self._page_context = {'next': None}
        self._limit = limit
        self._tag = tag
        self._resource_group_id = resource_group_id
        self._name = name
        self._source_volume_id = source_volume_id
        self._source_volume_crn = source_volume_crn
        self._source_image_id = source_image_id
        self._source_image_crn = source_image_crn
        self._sort = sort
        self._backup_policy_plan_id = backup_policy_plan_id
        self._copies_id = copies_id
        self._copies_name = copies_name
        self._copies_crn = copies_crn
        self._copies_remote_region_name = copies_remote_region_name
        self._source_snapshot_id = source_snapshot_id
        self._source_snapshot_remote_region_name = source_snapshot_remote_region_name
        self._source_volume_remote_region_name = source_volume_remote_region_name
        self._source_image_remote_region_name = source_image_remote_region_name
        self._clones_zone_name = clones_zone_name

    def has_next(self) -> bool:
        """
        Returns true if there are potentially more results to be retrieved.
        """
        return self._has_next

    def get_next(self) -> List[dict]:
        """
        Returns the next page of results.
        :return: A List[dict], where each element is a dict that represents an instance of Snapshot.
        :rtype: List[dict]
        """
        if not self.has_next():
            raise StopIteration(message='No more results available')

        result = self._client.list_snapshots(
            limit=self._limit,
            tag=self._tag,
            resource_group_id=self._resource_group_id,
            name=self._name,
            source_volume_id=self._source_volume_id,
            source_volume_crn=self._source_volume_crn,
            source_image_id=self._source_image_id,
            source_image_crn=self._source_image_crn,
            sort=self._sort,
            backup_policy_plan_id=self._backup_policy_plan_id,
            copies_id=self._copies_id,
            copies_name=self._copies_name,
            copies_crn=self._copies_crn,
            copies_remote_region_name=self._copies_remote_region_name,
            source_snapshot_id=self._source_snapshot_id,
            source_snapshot_remote_region_name=self._source_snapshot_remote_region_name,
            source_volume_remote_region_name=self._source_volume_remote_region_name,
            source_image_remote_region_name=self._source_image_remote_region_name,
            clones_zone_name=self._clones_zone_name,
            start=self._page_context.get('next'),
        ).get_result()

        next = None
        next_page_link = result.get('next')
        if next_page_link is not None:
            next = get_query_param(next_page_link.get('href'), 'start')
        self._page_context['next'] = next
        if next is None:
            self._has_next = False

        return result.get('snapshots')

    def get_all(self) -> List[dict]:
        """
        Returns all results by invoking get_next() repeatedly
        until all pages of results have been retrieved.
        :return: A List[dict], where each element is a dict that represents an instance of Snapshot.
        :rtype: List[dict]
        """
        results = []
        while self.has_next():
            next_page = self.get_next()
            results.extend(next_page)
        return results


class ShareProfilesPager:
    """
    ShareProfilesPager can be used to simplify the use of the "list_share_profiles" method.
    """

    def __init__(
        self,
        *,
        client: VpcV1,
        limit: int = None,
        sort: str = None,
    ) -> None:
        """
        Initialize a ShareProfilesPager object.
        :param int limit: (optional) The number of resources to return on a page.
        :param str sort: (optional) Sorts the returned collection by the specified
               property name in ascending order. A `-` may be prepended to the name to
               sort in descending order. For example, the value `-created_at` sorts the
               collection by the `created_at` property in descending order, and the value
               `name` sorts it by the `name` property in ascending order.
        """
        self._has_next = True
        self._client = client
        self._page_context = {'next': None}
        self._limit = limit
        self._sort = sort

    def has_next(self) -> bool:
        """
        Returns true if there are potentially more results to be retrieved.
        """
        return self._has_next

    def get_next(self) -> List[dict]:
        """
        Returns the next page of results.
        :return: A List[dict], where each element is a dict that represents an instance of ShareProfile.
        :rtype: List[dict]
        """
        if not self.has_next():
            raise StopIteration(message='No more results available')

        result = self._client.list_share_profiles(
            limit=self._limit,
            sort=self._sort,
            start=self._page_context.get('next'),
        ).get_result()

        next = None
        next_page_link = result.get('next')
        if next_page_link is not None:
            next = get_query_param(next_page_link.get('href'), 'start')
        self._page_context['next'] = next
        if next is None:
            self._has_next = False

        return result.get('profiles')

    def get_all(self) -> List[dict]:
        """
        Returns all results by invoking get_next() repeatedly
        until all pages of results have been retrieved.
        :return: A List[dict], where each element is a dict that represents an instance of ShareProfile.
        :rtype: List[dict]
        """
        results = []
        while self.has_next():
            next_page = self.get_next()
            results.extend(next_page)
        return results


class SharesPager:
    """
    SharesPager can be used to simplify the use of the "list_shares" method.
    """

    def __init__(
        self,
        *,
        client: VpcV1,
        limit: int = None,
        resource_group_id: str = None,
        name: str = None,
        sort: str = None,
        replication_role: str = None,
    ) -> None:
        """
        Initialize a SharesPager object.
        :param int limit: (optional) The number of resources to return on a page.
        :param str resource_group_id: (optional) Filters the collection to
               resources with a `resource_group.id` property matching the specified
               identifier.
        :param str name: (optional) Filters the collection to resources with a
               `name` property matching the exact specified name.
        :param str sort: (optional) Sorts the returned collection by the specified
               property name in ascending order. A `-` may be prepended to the name to
               sort in descending order. For example, the value `-created_at` sorts the
               collection by the `created_at` property in descending order, and the value
               `name` sorts it by the `name` property in ascending order.
        :param str replication_role: (optional) Filters the collection to file
               shares with a `replication_role` property matching the specified value.
        """
        self._has_next = True
        self._client = client
        self._page_context = {'next': None}
        self._limit = limit
        self._resource_group_id = resource_group_id
        self._name = name
        self._sort = sort
        self._replication_role = replication_role

    def has_next(self) -> bool:
        """
        Returns true if there are potentially more results to be retrieved.
        """
        return self._has_next

    def get_next(self) -> List[dict]:
        """
        Returns the next page of results.
        :return: A List[dict], where each element is a dict that represents an instance of Share.
        :rtype: List[dict]
        """
        if not self.has_next():
            raise StopIteration(message='No more results available')

        result = self._client.list_shares(
            limit=self._limit,
            resource_group_id=self._resource_group_id,
            name=self._name,
            sort=self._sort,
            replication_role=self._replication_role,
            start=self._page_context.get('next'),
        ).get_result()

        next = None
        next_page_link = result.get('next')
        if next_page_link is not None:
            next = get_query_param(next_page_link.get('href'), 'start')
        self._page_context['next'] = next
        if next is None:
            self._has_next = False

        return result.get('shares')

    def get_all(self) -> List[dict]:
        """
        Returns all results by invoking get_next() repeatedly
        until all pages of results have been retrieved.
        :return: A List[dict], where each element is a dict that represents an instance of Share.
        :rtype: List[dict]
        """
        results = []
        while self.has_next():
            next_page = self.get_next()
            results.extend(next_page)
        return results


class ShareMountTargetsPager:
    """
    ShareMountTargetsPager can be used to simplify the use of the "list_share_mount_targets" method.
    """

    def __init__(
        self,
        *,
        client: VpcV1,
        share_id: str,
        name: str = None,
        limit: int = None,
    ) -> None:
        """
        Initialize a ShareMountTargetsPager object.
        :param str share_id: The file share identifier.
        :param str name: (optional) Filters the collection to resources with a
               `name` property matching the exact specified name.
        :param int limit: (optional) The number of resources to return on a page.
        """
        self._has_next = True
        self._client = client
        self._page_context = {'next': None}
        self._share_id = share_id
        self._name = name
        self._limit = limit

    def has_next(self) -> bool:
        """
        Returns true if there are potentially more results to be retrieved.
        """
        return self._has_next

    def get_next(self) -> List[dict]:
        """
        Returns the next page of results.
        :return: A List[dict], where each element is a dict that represents an instance of ShareMountTarget.
        :rtype: List[dict]
        """
        if not self.has_next():
            raise StopIteration(message='No more results available')

        result = self._client.list_share_mount_targets(
            share_id=self._share_id,
            name=self._name,
            limit=self._limit,
            start=self._page_context.get('next'),
        ).get_result()

        next = None
        next_page_link = result.get('next')
        if next_page_link is not None:
            next = get_query_param(next_page_link.get('href'), 'start')
        self._page_context['next'] = next
        if next is None:
            self._has_next = False

        return result.get('mount_targets')

    def get_all(self) -> List[dict]:
        """
        Returns all results by invoking get_next() repeatedly
        until all pages of results have been retrieved.
        :return: A List[dict], where each element is a dict that represents an instance of ShareMountTarget.
        :rtype: List[dict]
        """
        results = []
        while self.has_next():
            next_page = self.get_next()
            results.extend(next_page)
        return results


class VirtualNetworkInterfacesPager:
    """
    VirtualNetworkInterfacesPager can be used to simplify the use of the "list_virtual_network_interfaces" method.
    """

    def __init__(
        self,
        *,
        client: VpcV1,
        limit: int = None,
        resource_group_id: str = None,
    ) -> None:
        """
        Initialize a VirtualNetworkInterfacesPager object.
        :param int limit: (optional) The number of resources to return on a page.
        :param str resource_group_id: (optional) Filters the collection to
               resources with a `resource_group.id` property matching the specified
               identifier.
        """
        self._has_next = True
        self._client = client
        self._page_context = {'next': None}
        self._limit = limit
        self._resource_group_id = resource_group_id

    def has_next(self) -> bool:
        """
        Returns true if there are potentially more results to be retrieved.
        """
        return self._has_next

    def get_next(self) -> List[dict]:
        """
        Returns the next page of results.
        :return: A List[dict], where each element is a dict that represents an instance of VirtualNetworkInterface.
        :rtype: List[dict]
        """
        if not self.has_next():
            raise StopIteration(message='No more results available')

        result = self._client.list_virtual_network_interfaces(
            limit=self._limit,
            resource_group_id=self._resource_group_id,
            start=self._page_context.get('next'),
        ).get_result()

        next = None
        next_page_link = result.get('next')
        if next_page_link is not None:
            next = get_query_param(next_page_link.get('href'), 'start')
        self._page_context['next'] = next
        if next is None:
            self._has_next = False

        return result.get('virtual_network_interfaces')

    def get_all(self) -> List[dict]:
        """
        Returns all results by invoking get_next() repeatedly
        until all pages of results have been retrieved.
        :return: A List[dict], where each element is a dict that represents an instance of VirtualNetworkInterface.
        :rtype: List[dict]
        """
        results = []
        while self.has_next():
            next_page = self.get_next()
            results.extend(next_page)
        return results


class PublicGatewaysPager:
    """
    PublicGatewaysPager can be used to simplify the use of the "list_public_gateways" method.
    """

    def __init__(
        self,
        *,
        client: VpcV1,
        limit: int = None,
        resource_group_id: str = None,
    ) -> None:
        """
        Initialize a PublicGatewaysPager object.
        :param int limit: (optional) The number of resources to return on a page.
        :param str resource_group_id: (optional) Filters the collection to
               resources with a `resource_group.id` property matching the specified
               identifier.
        """
        self._has_next = True
        self._client = client
        self._page_context = {'next': None}
        self._limit = limit
        self._resource_group_id = resource_group_id

    def has_next(self) -> bool:
        """
        Returns true if there are potentially more results to be retrieved.
        """
        return self._has_next

    def get_next(self) -> List[dict]:
        """
        Returns the next page of results.
        :return: A List[dict], where each element is a dict that represents an instance of PublicGateway.
        :rtype: List[dict]
        """
        if not self.has_next():
            raise StopIteration(message='No more results available')

        result = self._client.list_public_gateways(
            limit=self._limit,
            resource_group_id=self._resource_group_id,
            start=self._page_context.get('next'),
        ).get_result()

        next = None
        next_page_link = result.get('next')
        if next_page_link is not None:
            next = get_query_param(next_page_link.get('href'), 'start')
        self._page_context['next'] = next
        if next is None:
            self._has_next = False

        return result.get('public_gateways')

    def get_all(self) -> List[dict]:
        """
        Returns all results by invoking get_next() repeatedly
        until all pages of results have been retrieved.
        :return: A List[dict], where each element is a dict that represents an instance of PublicGateway.
        :rtype: List[dict]
        """
        results = []
        while self.has_next():
            next_page = self.get_next()
            results.extend(next_page)
        return results


class FloatingIpsPager:
    """
    FloatingIpsPager can be used to simplify the use of the "list_floating_ips" method.
    """

    def __init__(
        self,
        *,
        client: VpcV1,
        limit: int = None,
        resource_group_id: str = None,
        sort: str = None,
    ) -> None:
        """
        Initialize a FloatingIpsPager object.
        :param int limit: (optional) The number of resources to return on a page.
        :param str resource_group_id: (optional) Filters the collection to
               resources with a `resource_group.id` property matching the specified
               identifier.
        :param str sort: (optional) Sorts the returned collection by the specified
               property name in ascending order. A `-` may be prepended to the name to
               sort in descending order. For example, the value `-created_at` sorts the
               collection by the `created_at` property in descending order, and the value
               `name` sorts it by the `name` property in ascending order.
        """
        self._has_next = True
        self._client = client
        self._page_context = {'next': None}
        self._limit = limit
        self._resource_group_id = resource_group_id
        self._sort = sort

    def has_next(self) -> bool:
        """
        Returns true if there are potentially more results to be retrieved.
        """
        return self._has_next

    def get_next(self) -> List[dict]:
        """
        Returns the next page of results.
        :return: A List[dict], where each element is a dict that represents an instance of FloatingIP.
        :rtype: List[dict]
        """
        if not self.has_next():
            raise StopIteration(message='No more results available')

        result = self._client.list_floating_ips(
            limit=self._limit,
            resource_group_id=self._resource_group_id,
            sort=self._sort,
            start=self._page_context.get('next'),
        ).get_result()

        next = None
        next_page_link = result.get('next')
        if next_page_link is not None:
            next = get_query_param(next_page_link.get('href'), 'start')
        self._page_context['next'] = next
        if next is None:
            self._has_next = False

        return result.get('floating_ips')

    def get_all(self) -> List[dict]:
        """
        Returns all results by invoking get_next() repeatedly
        until all pages of results have been retrieved.
        :return: A List[dict], where each element is a dict that represents an instance of FloatingIP.
        :rtype: List[dict]
        """
        results = []
        while self.has_next():
            next_page = self.get_next()
            results.extend(next_page)
        return results


class NetworkAclsPager:
    """
    NetworkAclsPager can be used to simplify the use of the "list_network_acls" method.
    """

    def __init__(
        self,
        *,
        client: VpcV1,
        limit: int = None,
        resource_group_id: str = None,
    ) -> None:
        """
        Initialize a NetworkAclsPager object.
        :param int limit: (optional) The number of resources to return on a page.
        :param str resource_group_id: (optional) Filters the collection to
               resources with a `resource_group.id` property matching the specified
               identifier.
        """
        self._has_next = True
        self._client = client
        self._page_context = {'next': None}
        self._limit = limit
        self._resource_group_id = resource_group_id

    def has_next(self) -> bool:
        """
        Returns true if there are potentially more results to be retrieved.
        """
        return self._has_next

    def get_next(self) -> List[dict]:
        """
        Returns the next page of results.
        :return: A List[dict], where each element is a dict that represents an instance of NetworkACL.
        :rtype: List[dict]
        """
        if not self.has_next():
            raise StopIteration(message='No more results available')

        result = self._client.list_network_acls(
            limit=self._limit,
            resource_group_id=self._resource_group_id,
            start=self._page_context.get('next'),
        ).get_result()

        next = None
        next_page_link = result.get('next')
        if next_page_link is not None:
            next = get_query_param(next_page_link.get('href'), 'start')
        self._page_context['next'] = next
        if next is None:
            self._has_next = False

        return result.get('network_acls')

    def get_all(self) -> List[dict]:
        """
        Returns all results by invoking get_next() repeatedly
        until all pages of results have been retrieved.
        :return: A List[dict], where each element is a dict that represents an instance of NetworkACL.
        :rtype: List[dict]
        """
        results = []
        while self.has_next():
            next_page = self.get_next()
            results.extend(next_page)
        return results


class NetworkAclRulesPager:
    """
    NetworkAclRulesPager can be used to simplify the use of the "list_network_acl_rules" method.
    """

    def __init__(
        self,
        *,
        client: VpcV1,
        network_acl_id: str,
        limit: int = None,
        direction: str = None,
    ) -> None:
        """
        Initialize a NetworkAclRulesPager object.
        :param str network_acl_id: The network ACL identifier.
        :param int limit: (optional) The number of resources to return on a page.
        :param str direction: (optional) Filters the collection to rules with a
               `direction` property matching the specified value.
        """
        self._has_next = True
        self._client = client
        self._page_context = {'next': None}
        self._network_acl_id = network_acl_id
        self._limit = limit
        self._direction = direction

    def has_next(self) -> bool:
        """
        Returns true if there are potentially more results to be retrieved.
        """
        return self._has_next

    def get_next(self) -> List[dict]:
        """
        Returns the next page of results.
        :return: A List[dict], where each element is a dict that represents an instance of NetworkACLRuleItem.
        :rtype: List[dict]
        """
        if not self.has_next():
            raise StopIteration(message='No more results available')

        result = self._client.list_network_acl_rules(
            network_acl_id=self._network_acl_id,
            limit=self._limit,
            direction=self._direction,
            start=self._page_context.get('next'),
        ).get_result()

        next = None
        next_page_link = result.get('next')
        if next_page_link is not None:
            next = get_query_param(next_page_link.get('href'), 'start')
        self._page_context['next'] = next
        if next is None:
            self._has_next = False

        return result.get('rules')

    def get_all(self) -> List[dict]:
        """
        Returns all results by invoking get_next() repeatedly
        until all pages of results have been retrieved.
        :return: A List[dict], where each element is a dict that represents an instance of NetworkACLRuleItem.
        :rtype: List[dict]
        """
        results = []
        while self.has_next():
            next_page = self.get_next()
            results.extend(next_page)
        return results


class SecurityGroupsPager:
    """
    SecurityGroupsPager can be used to simplify the use of the "list_security_groups" method.
    """

    def __init__(
        self,
        *,
        client: VpcV1,
        limit: int = None,
        resource_group_id: str = None,
        vpc_id: str = None,
        vpc_crn: str = None,
        vpc_name: str = None,
    ) -> None:
        """
        Initialize a SecurityGroupsPager object.
        :param int limit: (optional) The number of resources to return on a page.
        :param str resource_group_id: (optional) Filters the collection to
               resources with a `resource_group.id` property matching the specified
               identifier.
        :param str vpc_id: (optional) Filters the collection to resources with a
               `vpc.id` property matching the specified identifier.
        :param str vpc_crn: (optional) Filters the collection to resources with a
               `vpc.crn` property matching the specified CRN.
        :param str vpc_name: (optional) Filters the collection to resources with a
               `vpc.name` property matching the exact specified name.
        """
        self._has_next = True
        self._client = client
        self._page_context = {'next': None}
        self._limit = limit
        self._resource_group_id = resource_group_id
        self._vpc_id = vpc_id
        self._vpc_crn = vpc_crn
        self._vpc_name = vpc_name

    def has_next(self) -> bool:
        """
        Returns true if there are potentially more results to be retrieved.
        """
        return self._has_next

    def get_next(self) -> List[dict]:
        """
        Returns the next page of results.
        :return: A List[dict], where each element is a dict that represents an instance of SecurityGroup.
        :rtype: List[dict]
        """
        if not self.has_next():
            raise StopIteration(message='No more results available')

        result = self._client.list_security_groups(
            limit=self._limit,
            resource_group_id=self._resource_group_id,
            vpc_id=self._vpc_id,
            vpc_crn=self._vpc_crn,
            vpc_name=self._vpc_name,
            start=self._page_context.get('next'),
        ).get_result()

        next = None
        next_page_link = result.get('next')
        if next_page_link is not None:
            next = get_query_param(next_page_link.get('href'), 'start')
        self._page_context['next'] = next
        if next is None:
            self._has_next = False

        return result.get('security_groups')

    def get_all(self) -> List[dict]:
        """
        Returns all results by invoking get_next() repeatedly
        until all pages of results have been retrieved.
        :return: A List[dict], where each element is a dict that represents an instance of SecurityGroup.
        :rtype: List[dict]
        """
        results = []
        while self.has_next():
            next_page = self.get_next()
            results.extend(next_page)
        return results


class SecurityGroupTargetsPager:
    """
    SecurityGroupTargetsPager can be used to simplify the use of the "list_security_group_targets" method.
    """

    def __init__(
        self,
        *,
        client: VpcV1,
        security_group_id: str,
        limit: int = None,
    ) -> None:
        """
        Initialize a SecurityGroupTargetsPager object.
        :param str security_group_id: The security group identifier.
        :param int limit: (optional) The number of resources to return on a page.
        """
        self._has_next = True
        self._client = client
        self._page_context = {'next': None}
        self._security_group_id = security_group_id
        self._limit = limit

    def has_next(self) -> bool:
        """
        Returns true if there are potentially more results to be retrieved.
        """
        return self._has_next

    def get_next(self) -> List[dict]:
        """
        Returns the next page of results.
        :return: A List[dict], where each element is a dict that represents an instance of SecurityGroupTargetReference.
        :rtype: List[dict]
        """
        if not self.has_next():
            raise StopIteration(message='No more results available')

        result = self._client.list_security_group_targets(
            security_group_id=self._security_group_id,
            limit=self._limit,
            start=self._page_context.get('next'),
        ).get_result()

        next = None
        next_page_link = result.get('next')
        if next_page_link is not None:
            next = get_query_param(next_page_link.get('href'), 'start')
        self._page_context['next'] = next
        if next is None:
            self._has_next = False

        return result.get('targets')

    def get_all(self) -> List[dict]:
        """
        Returns all results by invoking get_next() repeatedly
        until all pages of results have been retrieved.
        :return: A List[dict], where each element is a dict that represents an instance of SecurityGroupTargetReference.
        :rtype: List[dict]
        """
        results = []
        while self.has_next():
            next_page = self.get_next()
            results.extend(next_page)
        return results


class IkePoliciesPager:
    """
    IkePoliciesPager can be used to simplify the use of the "list_ike_policies" method.
    """

    def __init__(
        self,
        *,
        client: VpcV1,
        limit: int = None,
    ) -> None:
        """
        Initialize a IkePoliciesPager object.
        :param int limit: (optional) The number of resources to return on a page.
        """
        self._has_next = True
        self._client = client
        self._page_context = {'next': None}
        self._limit = limit

    def has_next(self) -> bool:
        """
        Returns true if there are potentially more results to be retrieved.
        """
        return self._has_next

    def get_next(self) -> List[dict]:
        """
        Returns the next page of results.
        :return: A List[dict], where each element is a dict that represents an instance of IKEPolicy.
        :rtype: List[dict]
        """
        if not self.has_next():
            raise StopIteration(message='No more results available')

        result = self._client.list_ike_policies(
            limit=self._limit,
            start=self._page_context.get('next'),
        ).get_result()

        next = None
        next_page_link = result.get('next')
        if next_page_link is not None:
            next = get_query_param(next_page_link.get('href'), 'start')
        self._page_context['next'] = next
        if next is None:
            self._has_next = False

        return result.get('ike_policies')

    def get_all(self) -> List[dict]:
        """
        Returns all results by invoking get_next() repeatedly
        until all pages of results have been retrieved.
        :return: A List[dict], where each element is a dict that represents an instance of IKEPolicy.
        :rtype: List[dict]
        """
        results = []
        while self.has_next():
            next_page = self.get_next()
            results.extend(next_page)
        return results


class IpsecPoliciesPager:
    """
    IpsecPoliciesPager can be used to simplify the use of the "list_ipsec_policies" method.
    """

    def __init__(
        self,
        *,
        client: VpcV1,
        limit: int = None,
    ) -> None:
        """
        Initialize a IpsecPoliciesPager object.
        :param int limit: (optional) The number of resources to return on a page.
        """
        self._has_next = True
        self._client = client
        self._page_context = {'next': None}
        self._limit = limit

    def has_next(self) -> bool:
        """
        Returns true if there are potentially more results to be retrieved.
        """
        return self._has_next

    def get_next(self) -> List[dict]:
        """
        Returns the next page of results.
        :return: A List[dict], where each element is a dict that represents an instance of IPsecPolicy.
        :rtype: List[dict]
        """
        if not self.has_next():
            raise StopIteration(message='No more results available')

        result = self._client.list_ipsec_policies(
            limit=self._limit,
            start=self._page_context.get('next'),
        ).get_result()

        next = None
        next_page_link = result.get('next')
        if next_page_link is not None:
            next = get_query_param(next_page_link.get('href'), 'start')
        self._page_context['next'] = next
        if next is None:
            self._has_next = False

        return result.get('ipsec_policies')

    def get_all(self) -> List[dict]:
        """
        Returns all results by invoking get_next() repeatedly
        until all pages of results have been retrieved.
        :return: A List[dict], where each element is a dict that represents an instance of IPsecPolicy.
        :rtype: List[dict]
        """
        results = []
        while self.has_next():
            next_page = self.get_next()
            results.extend(next_page)
        return results


class VpnGatewaysPager:
    """
    VpnGatewaysPager can be used to simplify the use of the "list_vpn_gateways" method.
    """

    def __init__(
        self,
        *,
        client: VpcV1,
        limit: int = None,
        resource_group_id: str = None,
        sort: str = None,
        mode: str = None,
    ) -> None:
        """
        Initialize a VpnGatewaysPager object.
        :param int limit: (optional) The number of resources to return on a page.
        :param str resource_group_id: (optional) Filters the collection to
               resources with a `resource_group.id` property matching the specified
               identifier.
        :param str sort: (optional) Sorts the returned collection by the specified
               property name in ascending order. A `-` may be prepended to the name to
               sort in descending order. For example, the value `-created_at` sorts the
               collection by the `created_at` property in descending order, and the value
               `name` sorts it by the `name` property in ascending order.
        :param str mode: (optional) Filters the collection to VPN gateways with a
               `mode` property matching the specified value.
        """
        self._has_next = True
        self._client = client
        self._page_context = {'next': None}
        self._limit = limit
        self._resource_group_id = resource_group_id
        self._sort = sort
        self._mode = mode

    def has_next(self) -> bool:
        """
        Returns true if there are potentially more results to be retrieved.
        """
        return self._has_next

    def get_next(self) -> List[dict]:
        """
        Returns the next page of results.
        :return: A List[dict], where each element is a dict that represents an instance of VPNGateway.
        :rtype: List[dict]
        """
        if not self.has_next():
            raise StopIteration(message='No more results available')

        result = self._client.list_vpn_gateways(
            limit=self._limit,
            resource_group_id=self._resource_group_id,
            sort=self._sort,
            mode=self._mode,
            start=self._page_context.get('next'),
        ).get_result()

        next = None
        next_page_link = result.get('next')
        if next_page_link is not None:
            next = get_query_param(next_page_link.get('href'), 'start')
        self._page_context['next'] = next
        if next is None:
            self._has_next = False

        return result.get('vpn_gateways')

    def get_all(self) -> List[dict]:
        """
        Returns all results by invoking get_next() repeatedly
        until all pages of results have been retrieved.
        :return: A List[dict], where each element is a dict that represents an instance of VPNGateway.
        :rtype: List[dict]
        """
        results = []
        while self.has_next():
            next_page = self.get_next()
            results.extend(next_page)
        return results


class VpnServersPager:
    """
    VpnServersPager can be used to simplify the use of the "list_vpn_servers" method.
    """

    def __init__(
        self,
        *,
        client: VpcV1,
        name: str = None,
        limit: int = None,
        resource_group_id: str = None,
        sort: str = None,
    ) -> None:
        """
        Initialize a VpnServersPager object.
        :param str name: (optional) Filters the collection to resources with a
               `name` property matching the exact specified name.
        :param int limit: (optional) The number of resources to return on a page.
        :param str resource_group_id: (optional) Filters the collection to
               resources with a `resource_group.id` property matching the specified
               identifier.
        :param str sort: (optional) Sorts the returned collection by the specified
               property name in ascending order. A `-` may be prepended to the name to
               sort in descending order. For example, the value `-created_at` sorts the
               collection by the `created_at` property in descending order, and the value
               `name` sorts it by the `name` property in ascending order.
        """
        self._has_next = True
        self._client = client
        self._page_context = {'next': None}
        self._name = name
        self._limit = limit
        self._resource_group_id = resource_group_id
        self._sort = sort

    def has_next(self) -> bool:
        """
        Returns true if there are potentially more results to be retrieved.
        """
        return self._has_next

    def get_next(self) -> List[dict]:
        """
        Returns the next page of results.
        :return: A List[dict], where each element is a dict that represents an instance of VPNServer.
        :rtype: List[dict]
        """
        if not self.has_next():
            raise StopIteration(message='No more results available')

        result = self._client.list_vpn_servers(
            name=self._name,
            limit=self._limit,
            resource_group_id=self._resource_group_id,
            sort=self._sort,
            start=self._page_context.get('next'),
        ).get_result()

        next = None
        next_page_link = result.get('next')
        if next_page_link is not None:
            next = get_query_param(next_page_link.get('href'), 'start')
        self._page_context['next'] = next
        if next is None:
            self._has_next = False

        return result.get('vpn_servers')

    def get_all(self) -> List[dict]:
        """
        Returns all results by invoking get_next() repeatedly
        until all pages of results have been retrieved.
        :return: A List[dict], where each element is a dict that represents an instance of VPNServer.
        :rtype: List[dict]
        """
        results = []
        while self.has_next():
            next_page = self.get_next()
            results.extend(next_page)
        return results


class VpnServerClientsPager:
    """
    VpnServerClientsPager can be used to simplify the use of the "list_vpn_server_clients" method.
    """

    def __init__(
        self,
        *,
        client: VpcV1,
        vpn_server_id: str,
        limit: int = None,
        sort: str = None,
    ) -> None:
        """
        Initialize a VpnServerClientsPager object.
        :param str vpn_server_id: The VPN server identifier.
        :param int limit: (optional) The number of resources to return on a page.
        :param str sort: (optional) Sorts the returned collection by the specified
               property name in ascending order. A `-` may be prepended to the name to
               sort in descending order. For example, the value `-created_at` sorts the
               collection by the `created_at` property in descending order.
        """
        self._has_next = True
        self._client = client
        self._page_context = {'next': None}
        self._vpn_server_id = vpn_server_id
        self._limit = limit
        self._sort = sort

    def has_next(self) -> bool:
        """
        Returns true if there are potentially more results to be retrieved.
        """
        return self._has_next

    def get_next(self) -> List[dict]:
        """
        Returns the next page of results.
        :return: A List[dict], where each element is a dict that represents an instance of VPNServerClient.
        :rtype: List[dict]
        """
        if not self.has_next():
            raise StopIteration(message='No more results available')

        result = self._client.list_vpn_server_clients(
            vpn_server_id=self._vpn_server_id,
            limit=self._limit,
            sort=self._sort,
            start=self._page_context.get('next'),
        ).get_result()

        next = None
        next_page_link = result.get('next')
        if next_page_link is not None:
            next = get_query_param(next_page_link.get('href'), 'start')
        self._page_context['next'] = next
        if next is None:
            self._has_next = False

        return result.get('clients')

    def get_all(self) -> List[dict]:
        """
        Returns all results by invoking get_next() repeatedly
        until all pages of results have been retrieved.
        :return: A List[dict], where each element is a dict that represents an instance of VPNServerClient.
        :rtype: List[dict]
        """
        results = []
        while self.has_next():
            next_page = self.get_next()
            results.extend(next_page)
        return results


class VpnServerRoutesPager:
    """
    VpnServerRoutesPager can be used to simplify the use of the "list_vpn_server_routes" method.
    """

    def __init__(
        self,
        *,
        client: VpcV1,
        vpn_server_id: str,
        limit: int = None,
        sort: str = None,
    ) -> None:
        """
        Initialize a VpnServerRoutesPager object.
        :param str vpn_server_id: The VPN server identifier.
        :param int limit: (optional) The number of resources to return on a page.
        :param str sort: (optional) Sorts the returned collection by the specified
               property name in ascending order. A `-` may be prepended to the name to
               sort in descending order. For example, the value `-created_at` sorts the
               collection by the `created_at` property in descending order, and the value
               `name` sorts it by the `name` property in ascending order.
        """
        self._has_next = True
        self._client = client
        self._page_context = {'next': None}
        self._vpn_server_id = vpn_server_id
        self._limit = limit
        self._sort = sort

    def has_next(self) -> bool:
        """
        Returns true if there are potentially more results to be retrieved.
        """
        return self._has_next

    def get_next(self) -> List[dict]:
        """
        Returns the next page of results.
        :return: A List[dict], where each element is a dict that represents an instance of VPNServerRoute.
        :rtype: List[dict]
        """
        if not self.has_next():
            raise StopIteration(message='No more results available')

        result = self._client.list_vpn_server_routes(
            vpn_server_id=self._vpn_server_id,
            limit=self._limit,
            sort=self._sort,
            start=self._page_context.get('next'),
        ).get_result()

        next = None
        next_page_link = result.get('next')
        if next_page_link is not None:
            next = get_query_param(next_page_link.get('href'), 'start')
        self._page_context['next'] = next
        if next is None:
            self._has_next = False

        return result.get('routes')

    def get_all(self) -> List[dict]:
        """
        Returns all results by invoking get_next() repeatedly
        until all pages of results have been retrieved.
        :return: A List[dict], where each element is a dict that represents an instance of VPNServerRoute.
        :rtype: List[dict]
        """
        results = []
        while self.has_next():
            next_page = self.get_next()
            results.extend(next_page)
        return results


class LoadBalancerProfilesPager:
    """
    LoadBalancerProfilesPager can be used to simplify the use of the "list_load_balancer_profiles" method.
    """

    def __init__(
        self,
        *,
        client: VpcV1,
        limit: int = None,
    ) -> None:
        """
        Initialize a LoadBalancerProfilesPager object.
        :param int limit: (optional) The number of resources to return on a page.
        """
        self._has_next = True
        self._client = client
        self._page_context = {'next': None}
        self._limit = limit

    def has_next(self) -> bool:
        """
        Returns true if there are potentially more results to be retrieved.
        """
        return self._has_next

    def get_next(self) -> List[dict]:
        """
        Returns the next page of results.
        :return: A List[dict], where each element is a dict that represents an instance of LoadBalancerProfile.
        :rtype: List[dict]
        """
        if not self.has_next():
            raise StopIteration(message='No more results available')

        result = self._client.list_load_balancer_profiles(
            limit=self._limit,
            start=self._page_context.get('next'),
        ).get_result()

        next = None
        next_page_link = result.get('next')
        if next_page_link is not None:
            next = get_query_param(next_page_link.get('href'), 'start')
        self._page_context['next'] = next
        if next is None:
            self._has_next = False

        return result.get('profiles')

    def get_all(self) -> List[dict]:
        """
        Returns all results by invoking get_next() repeatedly
        until all pages of results have been retrieved.
        :return: A List[dict], where each element is a dict that represents an instance of LoadBalancerProfile.
        :rtype: List[dict]
        """
        results = []
        while self.has_next():
            next_page = self.get_next()
            results.extend(next_page)
        return results


class LoadBalancersPager:
    """
    LoadBalancersPager can be used to simplify the use of the "list_load_balancers" method.
    """

    def __init__(
        self,
        *,
        client: VpcV1,
        limit: int = None,
    ) -> None:
        """
        Initialize a LoadBalancersPager object.
        :param int limit: (optional) The number of resources to return on a page.
        """
        self._has_next = True
        self._client = client
        self._page_context = {'next': None}
        self._limit = limit

    def has_next(self) -> bool:
        """
        Returns true if there are potentially more results to be retrieved.
        """
        return self._has_next

    def get_next(self) -> List[dict]:
        """
        Returns the next page of results.
        :return: A List[dict], where each element is a dict that represents an instance of LoadBalancer.
        :rtype: List[dict]
        """
        if not self.has_next():
            raise StopIteration(message='No more results available')

        result = self._client.list_load_balancers(
            limit=self._limit,
            start=self._page_context.get('next'),
        ).get_result()

        next = None
        next_page_link = result.get('next')
        if next_page_link is not None:
            next = get_query_param(next_page_link.get('href'), 'start')
        self._page_context['next'] = next
        if next is None:
            self._has_next = False

        return result.get('load_balancers')

    def get_all(self) -> List[dict]:
        """
        Returns all results by invoking get_next() repeatedly
        until all pages of results have been retrieved.
        :return: A List[dict], where each element is a dict that represents an instance of LoadBalancer.
        :rtype: List[dict]
        """
        results = []
        while self.has_next():
            next_page = self.get_next()
            results.extend(next_page)
        return results


class EndpointGatewaysPager:
    """
    EndpointGatewaysPager can be used to simplify the use of the "list_endpoint_gateways" method.
    """

    def __init__(
        self,
        *,
        client: VpcV1,
        name: str = None,
        limit: int = None,
        resource_group_id: str = None,
        vpc_id: str = None,
        vpc_crn: str = None,
        vpc_name: str = None,
        allow_dns_resolution_binding: bool = None,
    ) -> None:
        """
        Initialize a EndpointGatewaysPager object.
        :param str name: (optional) Filters the collection to resources with a
               `name` property matching the exact specified name.
        :param int limit: (optional) The number of resources to return on a page.
        :param str resource_group_id: (optional) Filters the collection to
               resources with a `resource_group.id` property matching the specified
               identifier.
        :param str vpc_id: (optional) Filters the collection to resources with a
               `vpc.id` property matching the specified identifier.
        :param str vpc_crn: (optional) Filters the collection to resources with a
               `vpc.crn` property matching the specified CRN.
        :param str vpc_name: (optional) Filters the collection to resources with a
               `vpc.name` property matching the exact specified name.
        :param bool allow_dns_resolution_binding: (optional) Filters the collection
               to endpoint gateways with an `allow_dns_resolution_binding` property
               matching the specified value.
        """
        self._has_next = True
        self._client = client
        self._page_context = {'next': None}
        self._name = name
        self._limit = limit
        self._resource_group_id = resource_group_id
        self._vpc_id = vpc_id
        self._vpc_crn = vpc_crn
        self._vpc_name = vpc_name
        self._allow_dns_resolution_binding = allow_dns_resolution_binding

    def has_next(self) -> bool:
        """
        Returns true if there are potentially more results to be retrieved.
        """
        return self._has_next

    def get_next(self) -> List[dict]:
        """
        Returns the next page of results.
        :return: A List[dict], where each element is a dict that represents an instance of EndpointGateway.
        :rtype: List[dict]
        """
        if not self.has_next():
            raise StopIteration(message='No more results available')

        result = self._client.list_endpoint_gateways(
            name=self._name,
            limit=self._limit,
            resource_group_id=self._resource_group_id,
            vpc_id=self._vpc_id,
            vpc_crn=self._vpc_crn,
            vpc_name=self._vpc_name,
            allow_dns_resolution_binding=self._allow_dns_resolution_binding,
            start=self._page_context.get('next'),
        ).get_result()

        next = None
        next_page_link = result.get('next')
        if next_page_link is not None:
            next = get_query_param(next_page_link.get('href'), 'start')
        self._page_context['next'] = next
        if next is None:
            self._has_next = False

        return result.get('endpoint_gateways')

    def get_all(self) -> List[dict]:
        """
        Returns all results by invoking get_next() repeatedly
        until all pages of results have been retrieved.
        :return: A List[dict], where each element is a dict that represents an instance of EndpointGateway.
        :rtype: List[dict]
        """
        results = []
        while self.has_next():
            next_page = self.get_next()
            results.extend(next_page)
        return results


class EndpointGatewayIpsPager:
    """
    EndpointGatewayIpsPager can be used to simplify the use of the "list_endpoint_gateway_ips" method.
    """

    def __init__(
        self,
        *,
        client: VpcV1,
        endpoint_gateway_id: str,
        limit: int = None,
        sort: str = None,
    ) -> None:
        """
        Initialize a EndpointGatewayIpsPager object.
        :param str endpoint_gateway_id: The endpoint gateway identifier.
        :param int limit: (optional) The number of resources to return on a page.
        :param str sort: (optional) Sorts the returned collection by the specified
               property name in ascending order. A `-` may be prepended to the name to
               sort in descending order. For example, the value `-created_at` sorts the
               collection by the `created_at` property in descending order, and the value
               `name` sorts it by the `name` property in ascending order.
        """
        self._has_next = True
        self._client = client
        self._page_context = {'next': None}
        self._endpoint_gateway_id = endpoint_gateway_id
        self._limit = limit
        self._sort = sort

    def has_next(self) -> bool:
        """
        Returns true if there are potentially more results to be retrieved.
        """
        return self._has_next

    def get_next(self) -> List[dict]:
        """
        Returns the next page of results.
        :return: A List[dict], where each element is a dict that represents an instance of ReservedIP.
        :rtype: List[dict]
        """
        if not self.has_next():
            raise StopIteration(message='No more results available')

        result = self._client.list_endpoint_gateway_ips(
            endpoint_gateway_id=self._endpoint_gateway_id,
            limit=self._limit,
            sort=self._sort,
            start=self._page_context.get('next'),
        ).get_result()

        next = None
        next_page_link = result.get('next')
        if next_page_link is not None:
            next = get_query_param(next_page_link.get('href'), 'start')
        self._page_context['next'] = next
        if next is None:
            self._has_next = False

        return result.get('ips')

    def get_all(self) -> List[dict]:
        """
        Returns all results by invoking get_next() repeatedly
        until all pages of results have been retrieved.
        :return: A List[dict], where each element is a dict that represents an instance of ReservedIP.
        :rtype: List[dict]
        """
        results = []
        while self.has_next():
            next_page = self.get_next()
            results.extend(next_page)
        return results


class FlowLogCollectorsPager:
    """
    FlowLogCollectorsPager can be used to simplify the use of the "list_flow_log_collectors" method.
    """

    def __init__(
        self,
        *,
        client: VpcV1,
        limit: int = None,
        resource_group_id: str = None,
        name: str = None,
        vpc_id: str = None,
        vpc_crn: str = None,
        vpc_name: str = None,
        target_id: str = None,
        target_resource_type: str = None,
    ) -> None:
        """
        Initialize a FlowLogCollectorsPager object.
        :param int limit: (optional) The number of resources to return on a page.
        :param str resource_group_id: (optional) Filters the collection to
               resources with a `resource_group.id` property matching the specified
               identifier.
        :param str name: (optional) Filters the collection to resources with a
               `name` property matching the exact specified name.
        :param str vpc_id: (optional) Filters the collection to resources with a
               `vpc.id` property matching the specified identifier.
        :param str vpc_crn: (optional) Filters the collection to resources with a
               `vpc.crn` property matching the specified CRN.
        :param str vpc_name: (optional) Filters the collection to resources with a
               `vpc.name` property matching the exact specified name.
        :param str target_id: (optional) Filters the collection to resources with a
               `target.id` property matching the specified identifier.
        :param str target_resource_type: (optional) Filters the collection to
               resources with a `target.resource_type` property matching the specified
               value.
        """
        self._has_next = True
        self._client = client
        self._page_context = {'next': None}
        self._limit = limit
        self._resource_group_id = resource_group_id
        self._name = name
        self._vpc_id = vpc_id
        self._vpc_crn = vpc_crn
        self._vpc_name = vpc_name
        self._target_id = target_id
        self._target_resource_type = target_resource_type

    def has_next(self) -> bool:
        """
        Returns true if there are potentially more results to be retrieved.
        """
        return self._has_next

    def get_next(self) -> List[dict]:
        """
        Returns the next page of results.
        :return: A List[dict], where each element is a dict that represents an instance of FlowLogCollector.
        :rtype: List[dict]
        """
        if not self.has_next():
            raise StopIteration(message='No more results available')

        result = self._client.list_flow_log_collectors(
            limit=self._limit,
            resource_group_id=self._resource_group_id,
            name=self._name,
            vpc_id=self._vpc_id,
            vpc_crn=self._vpc_crn,
            vpc_name=self._vpc_name,
            target_id=self._target_id,
            target_resource_type=self._target_resource_type,
            start=self._page_context.get('next'),
        ).get_result()

        next = None
        next_page_link = result.get('next')
        if next_page_link is not None:
            next = get_query_param(next_page_link.get('href'), 'start')
        self._page_context['next'] = next
        if next is None:
            self._has_next = False

        return result.get('flow_log_collectors')

    def get_all(self) -> List[dict]:
        """
        Returns all results by invoking get_next() repeatedly
        until all pages of results have been retrieved.
        :return: A List[dict], where each element is a dict that represents an instance of FlowLogCollector.
        :rtype: List[dict]
        """
        results = []
        while self.has_next():
            next_page = self.get_next()
            results.extend(next_page)
        return results
