# coding: utf-8

# (C) Copyright IBM Corp. 2024.
#
# 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.96.1-5136e54a-20241108-203028

"""
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: 2024-11-13
"""

from datetime import datetime
from enum import Enum
from typing import Dict, List, Optional
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: Optional[str] = "2024-11-12",
        service_name: str = DEFAULT_SERVICE_NAME,
        generation: Optional[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 `2024-04-30` and
               `2024-11-14`.
        """
        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: Optional[str] = "2024-11-12",
        authenticator: Authenticator = None,
        generation: Optional[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 `2024-04-30` and
               `2024-11-14`.

        :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: Optional[str] = None,
        limit: Optional[int] = None,
        resource_group_id: Optional[str] = None,
        classic_access: Optional[bool] = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        List VPCs.

        This request lists 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: Optional[str] = None,
        classic_access: Optional[bool] = None,
        dns: Optional['VPCDNSPrototype'] = None,
        name: Optional[str] = None,
        resource_group: Optional['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) Deprecated: 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.
               This property has been deprecated. Instead, use a [Transit
               Gateway](https://cloud.ibm.com/docs/transit-gateway) to connect this VPC to
               Classic Infrastructure. For more information, see [upcoming
               changes](https://cloud.ibm.com/docs/vpc?topic=vpc-api-change-log#upcoming-changes).
        :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: Optional[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, endpoint gateways, and private path service
          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: Optional[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: Optional[str] = None,
        limit: Optional[int] = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        List address prefixes for a VPC.

        This request lists 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: Optional[bool] = None,
        name: Optional[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: Optional[str] = None,
        start: Optional[str] = None,
        limit: Optional[int] = None,
        name: Optional[str] = None,
        vpc_crn: Optional[str] = None,
        vpc_name: Optional[str] = None,
        account_id: Optional[str] = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        List DNS resolution bindings for a VPC.

        This request lists 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: Optional[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-vpe-dns-sharing) 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.
        For this request to succeed, the VPC specified by the identifier in the URL must
        not have
        `dns.resolver.type` set to `delegated`.

        :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='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']
        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='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: Optional[str] = None,
        start: Optional[str] = None,
        limit: Optional[int] = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        List routes in a VPC's default routing table.

        This request lists 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: Optional[str] = None,
        advertise: Optional[bool] = None,
        name: Optional[str] = None,
        next_hop: Optional['RouteNextHopPrototype'] = None,
        priority: Optional[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.
               If subnets are attached to the route's routing table, egress traffic from
               those
               subnets in this zone will be subject to this route. If this route's routing
               table
               has any of `route_direct_link_ingress`, `route_internet_ingress`,
               `route_transit_gateway_ingress` or `route_vpc_zone_ingress`  set to`true`,
               traffic
               from those ingress sources arriving 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 bool advertise: (optional) Indicates whether this route will be
               advertised to the ingress sources specified by the `advertise_routes_to`
               routing table property.
               All routes in a routing table with the same `destination` and `zone` must
               have the same
               `advertise` value.
        :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 RouteNextHopPrototype next_hop: (optional) If `action` is `deliver`,
               the next hop that packets will be delivered to (must not be
               `0.0.0.0`). 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,
            'advertise': advertise,
            '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: Optional[str] = None,
        limit: Optional[int] = None,
        is_default: Optional[bool] = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        List routing tables for a VPC.

        This request lists 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: Optional[List['ResourceFilter']] = None,
        advertise_routes_to: Optional[List[str]] = None,
        name: Optional[str] = None,
        route_direct_link_ingress: Optional[bool] = None,
        route_internet_ingress: Optional[bool] = None,
        route_transit_gateway_ingress: Optional[bool] = None,
        route_vpc_zone_ingress: Optional[bool] = None,
        routes: Optional[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.
        At present, the routing table's `resource_group` will be inherited from its VPC,
        but may be specifiable in the future.

        :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.
               If specified, `resource_type` must be `vpn_gateway` or `vpn_server`.
        :param List[str] advertise_routes_to: (optional) The ingress sources to
               advertise routes to. Routes in the table with `advertise` enabled will be
               advertised to these sources.
        :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,
            'advertise_routes_to': advertise_routes_to,
            '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: Optional[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: Optional[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: Optional[str] = None,
        limit: Optional[int] = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        List routes in a VPC routing table.

        This request lists 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: Optional[str] = None,
        advertise: Optional[bool] = None,
        name: Optional[str] = None,
        next_hop: Optional['RouteNextHopPrototype'] = None,
        priority: Optional[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.
               If subnets are attached to the route's routing table, egress traffic from
               those
               subnets in this zone will be subject to this route. If this route's routing
               table
               has any of `route_direct_link_ingress`, `route_internet_ingress`,
               `route_transit_gateway_ingress` or `route_vpc_zone_ingress`  set to`true`,
               traffic
               from those ingress sources arriving 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 bool advertise: (optional) Indicates whether this route will be
               advertised to the ingress sources specified by the `advertise_routes_to`
               routing table property.
               All routes in a routing table with the same `destination` and `zone` must
               have the same
               `advertise` value.
        :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 RouteNextHopPrototype next_hop: (optional) If `action` is `deliver`,
               the next hop that packets will be delivered to (must not be
               `0.0.0.0`). 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,
            'advertise': advertise,
            '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: Optional[str] = None,
        limit: Optional[int] = None,
        resource_group_id: Optional[str] = None,
        zone_name: Optional[str] = None,
        vpc_id: Optional[str] = None,
        vpc_crn: Optional[str] = None,
        vpc_name: Optional[str] = None,
        routing_table_id: Optional[str] = None,
        routing_table_name: Optional[str] = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        List subnets.

        This request lists 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, virtual 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_internet_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: Optional[str] = None,
        limit: Optional[int] = None,
        sort: Optional[str] = None,
        target_id: Optional[str] = None,
        target_crn: Optional[str] = None,
        target_name: Optional[str] = None,
        target_resource_type: Optional[str] = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        List reserved IPs in a subnet.

        This request lists 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 str target_id: (optional) Filters the collection to resources with a
               `target.id` property matching the specified identifier.
        :param str target_crn: (optional) Filters the collection to resources with
               a `target.crn` property matching the specified CRN.
        :param str target_name: (optional) Filters the collection to resources with
               a `target.name` property matching the exact specified name.
        :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 `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,
            'target.id': target_id,
            'target.crn': target_crn,
            'target.name': target_name,
            'target.resource_type': target_resource_type,
        }

        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: Optional[str] = None,
        auto_delete: Optional[bool] = None,
        name: Optional[str] = None,
        target: Optional['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.
               The following targets are supported:
               - An endpoint gateway not already bound to a reserved IP in the subnet's
               zone.
               - A virtual network interface.
               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, instance network
        interface or virtual 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: Optional[str] = None,
        limit: Optional[int] = None,
        resource_group_id: Optional[str] = None,
        name: Optional[str] = None,
        status: Optional[List[str]] = None,
        visibility: Optional[str] = None,
        user_data_format: Optional[List[str]] = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        List images.

        This request lists 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 List[str] user_data_format: (optional) Filters the collection to
               images with a `user_data_format` property matching one of the specified
               comma-separated values.
        :param dict headers: 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,
            'user_data_format': convert_list(user_data_format),
        }

        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: Optional[str] = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        List export jobs for an image.

        This request lists 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: Optional[str] = None,
        name: Optional[str] = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        Create an export job for an image.

        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: Optional[str] = None,
        limit: Optional[int] = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        List operating systems.

        This request lists 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: Optional[str] = None,
        limit: Optional[int] = None,
        resource_group_id: Optional[str] = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        List keys.

        This request lists 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 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 `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,
            'resource_group.id': resource_group_id,
        }

        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: Optional[str] = None,
        resource_group: Optional['ResourceGroupIdentity'] = None,
        type: Optional[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 for this key.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `Key` object
        """

        if 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 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 instance templates.

        This request lists 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: Optional[str] = None,
        limit: Optional[int] = None,
        resource_group_id: Optional[str] = None,
        name: Optional[str] = None,
        cluster_network_id: Optional[str] = None,
        cluster_network_crn: Optional[str] = None,
        cluster_network_name: Optional[str] = None,
        dedicated_host_id: Optional[str] = None,
        dedicated_host_crn: Optional[str] = None,
        dedicated_host_name: Optional[str] = None,
        placement_group_id: Optional[str] = None,
        placement_group_crn: Optional[str] = None,
        placement_group_name: Optional[str] = None,
        reservation_id: Optional[str] = None,
        reservation_crn: Optional[str] = None,
        reservation_name: Optional[str] = None,
        vpc_id: Optional[str] = None,
        vpc_crn: Optional[str] = None,
        vpc_name: Optional[str] = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        List instances.

        This request lists 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 cluster_network_id: (optional) Filters the collection to
               instances with a `cluster_network.id` property matching the specified
               identifier.
        :param str cluster_network_crn: (optional) Filters the collection to
               instances with a `cluster_network.crn` property matching the specified CRN.
        :param str cluster_network_name: (optional) Filters the collection to
               resources with a `cluster_network.name` property matching the exact
               specified name.
        :param str dedicated_host_id: (optional) Filters the collection to
               resources with a `dedicated_host.id` property matching the specified
               identifier.
        :param str dedicated_host_crn: (optional) Filters the collection to
               resources with a `dedicated_host.crn` property matching the specified CRN.
        :param str dedicated_host_name: (optional) Filters the collection to
               resources with a `dedicated_host.name` property matching the exact
               specified name.
        :param str placement_group_id: (optional) Filters the collection to
               resources with a `placement_target.id` property matching the specified
               placement group identifier.
        :param str placement_group_crn: (optional) Filters the collection to
               resources with a `placement_target.crn` property matching the specified
               placement group CRN.
        :param str placement_group_name: (optional) Filters the collection to
               resources with a `placement_target.name` property matching the exact
               specified placement group name.
        :param str reservation_id: (optional) Filters the collection to resources
               with a `reservation.id` property matching the specified identifier.
        :param str reservation_crn: (optional) Filters the collection to resources
               with a `reservation.crn` property matching the specified identifier.
        :param str reservation_name: (optional) Filters the collection to resources
               with a `reservation.name` 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 `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,
            'cluster_network.id': cluster_network_id,
            'cluster_network.crn': cluster_network_crn,
            'cluster_network.name': cluster_network_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,
            'reservation.id': reservation_id,
            'reservation.crn': reservation_crn,
            'reservation.name': reservation_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 = '/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,
        *,
        if_match: Optional[str] = None,
        **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
        virtual network interfaces with `auto_delete` set to `true` targeting instance
        network attachments on the instance are automatically deleted. All flow log
        collectors with
        `auto_delete` set to `true` targeting the instance, the instance network
        attachments, the instance network interfaces, or the automatically deleted virtual
        network interfaces are automatically deleted.

        :param str id: The virtual server instance 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_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',
        *,
        if_match: Optional[str] = None,
        **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 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 `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 = {
            'If-Match': if_match,
        }
        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: Optional[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 list_instance_cluster_network_attachments(
        self,
        instance_id: str,
        *,
        start: Optional[str] = None,
        limit: Optional[int] = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        List cluster network attachments on an instance.

        This request lists cluster network attachments on an instance. A cluster network
        attachment represents a device on the instance to which a cluster network
        interface is attached.

        :param str instance_id: The virtual server instance 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 `InstanceClusterNetworkAttachmentCollection` 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_cluster_network_attachments',
        )
        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']
        path_param_values = self.encode_path_vars(instance_id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/instances/{instance_id}/cluster_network_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_cluster_network_attachment(
        self,
        instance_id: str,
        cluster_network_interface: 'InstanceClusterNetworkAttachmentPrototypeClusterNetworkInterface',
        *,
        before: Optional['InstanceClusterNetworkAttachmentBeforePrototype'] = None,
        name: Optional[str] = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        Create a cluster network attachment.

        This request creates a cluster network attachment from an instance cluster network
        attachment prototype object. A cluster network attachment will attach the instance
        to a cluster network. The cluster network attachment prototype must specify a
        cluster network interface identity or a cluster network interface prototype.
        The instance must be in a `stopped` or `stopping` state to create an instance
        cluster network attachment.

        :param str instance_id: The virtual server instance identifier.
        :param InstanceClusterNetworkAttachmentPrototypeClusterNetworkInterface
               cluster_network_interface: A cluster network interface for the instance
               cluster network attachment. This can be
               specified using an existing cluster network interface that does not already
               have a `target`,
               or a prototype object for a new cluster network interface.
               This instance must reside in the same VPC as the specified cluster network
               interface. The
               cluster network interface must reside in the same cluster network as the
               `cluster_network_interface` of any other `cluster_network_attachments` for
               this instance.
        :param InstanceClusterNetworkAttachmentBeforePrototype before: (optional)
               The instance cluster network attachment to insert this instance cluster
               network attachment
               immediately before.
               If unspecified, this instance cluster network attachment will be inserted
               after all
               existing instance cluster network attachments.
        :param str name: (optional) The name for this cluster network attachment.
               Names must be unique within the instance the cluster network attachment
               resides in. If unspecified, the name will be a hyphenated list of
               randomly-selected words. Names starting with `ibm-` are reserved for
               provider-owned resources, and are not allowed.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `InstanceClusterNetworkAttachment` object
        """

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

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

        data = {
            'cluster_network_interface': cluster_network_interface,
            'before': before,
            '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}/cluster_network_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_cluster_network_attachment(
        self,
        instance_id: str,
        id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Delete an instance cluster network attachment.

        This request deletes an instance cluster network attachment. The instance must be
        in a
        `stopped` or `stopping` state to delete an instance cluster network attachment.
        This operation cannot be reversed.

        :param str instance_id: The virtual server instance identifier.
        :param str id: The instance cluster network 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 `InstanceClusterNetworkAttachment` 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='delete_instance_cluster_network_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}/cluster_network_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_cluster_network_attachment(
        self,
        instance_id: str,
        id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Retrieve an instance cluster network attachment.

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

        :param str instance_id: The virtual server instance identifier.
        :param str id: The instance cluster network 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 `InstanceClusterNetworkAttachment` 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_cluster_network_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}/cluster_network_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_cluster_network_attachment(
        self,
        instance_id: str,
        id: str,
        instance_cluster_network_attachment_patch: 'InstanceClusterNetworkAttachmentPatch',
        **kwargs,
    ) -> DetailedResponse:
        """
        Update an instance cluster network attachment.

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

        :param str instance_id: The virtual server instance identifier.
        :param str id: The instance cluster network attachment identifier.
        :param InstanceClusterNetworkAttachmentPatch
               instance_cluster_network_attachment_patch: The instance cluster network
               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 `InstanceClusterNetworkAttachment` object
        """

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

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

        data = json.dumps(instance_cluster_network_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}/cluster_network_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

    def create_instance_console_access_token(
        self,
        instance_id: str,
        console_type: str,
        *,
        force: Optional[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 disks on an instance.

        This request lists 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_attachments(
        self,
        instance_id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        List network attachments on an instance.

        This request lists network attachments on an instance. A network attachment
        represents a device on the instance to which a virtual network interface is
        attached.
        The network attachments will be sorted by their `created_at` property values, with
        newest network attachments first. Network attachments with identical `created_at`
        property values will in turn be sorted by ascending `name` property values.

        :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 `InstanceNetworkAttachmentCollection` 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_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}/network_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_network_attachment(
        self,
        instance_id: str,
        virtual_network_interface: 'InstanceNetworkAttachmentPrototypeVirtualNetworkInterface',
        *,
        name: Optional[str] = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        Create a network attachment on an instance.

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

        :param str instance_id: The virtual server instance identifier.
        :param InstanceNetworkAttachmentPrototypeVirtualNetworkInterface
               virtual_network_interface: A virtual network interface for the instance
               network attachment. This can be specified
               using an existing virtual network interface, or a prototype object for a
               new virtual
               network interface.
               If an existing virtual network interface is specified,
               `enable_infrastructure_nat` must be
               `true`.
        :param str name: (optional) The name for this network attachment. Names
               must be unique within the instance the network attachment resides in. If
               unspecified, the name will be a hyphenated list of randomly-selected words.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `InstanceNetworkAttachment` object
        """

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

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

        data = {
            'virtual_network_interface': virtual_network_interface,
            '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}/network_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_network_attachment(
        self,
        instance_id: str,
        id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Delete an instance network attachment.

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

        :param str instance_id: The virtual server instance identifier.
        :param str id: The instance network 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_network_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}/network_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_network_attachment(
        self,
        instance_id: str,
        id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Retrieve an instance network attachment.

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

        :param str instance_id: The virtual server instance identifier.
        :param str id: The instance network 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 `InstanceNetworkAttachment` 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_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}/network_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_network_attachment(
        self,
        instance_id: str,
        id: str,
        instance_network_attachment_patch: 'InstanceNetworkAttachmentPatch',
        **kwargs,
    ) -> DetailedResponse:
        """
        Update an instance network attachment.

        This request updates an instance network attachment with the information provided
        in an instance network interface patch object. The instance network attachment
        patch object is structured in the same way as a retrieved instance network
        attachment 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 attachment identifier.
        :param InstanceNetworkAttachmentPatch instance_network_attachment_patch:
               The instance network 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 `InstanceNetworkAttachment` object
        """

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

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

        data = json.dumps(instance_network_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}/network_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

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

        This request lists 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.
        If this instance has network attachments, each returned network interface is a
        [read-only
        representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
        of its corresponding network attachment and its attached virtual network
        interface.

        :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: Optional[bool] = None,
        name: Optional[str] = None,
        primary_ip: Optional['NetworkInterfaceIPPrototype'] = None,
        security_groups: Optional[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.
        If this instance has network attachments, each network interface is a [read-only
        representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
        of its corresponding network attachment and its attached virtual network
        interface, and new network interfaces are not allowed to be created.

        :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.
               If this instance has network attachments, this network interface is a
               [read-only
               representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
               of its corresponding network attachment and its attached virtual network
               interface, and source IP spoofing is managed on the attached virtual
               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.
        If this instance has network attachments, this network interface is a [read-only
        representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
        of its corresponding network attachment and its attached virtual network
        interface, and 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.
        If this instance has network attachments, the retrieved network interface is a
        [read-only
        representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
        of its corresponding network attachment and its attached virtual network
        interface.

        :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.
        If this instance has network attachments, this network interface is a [read-only
        representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
        of its corresponding network attachment and its attached virtual network
        interface, and is not allowed 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 floating IPs associated with an instance network interface.

        This request lists 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.
        The existing floating IP must:
        - not be required by another resource, such as a public gateway
        - be in the same `zone` as the instance
        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: Optional[str] = None,
        limit: Optional[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

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

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

        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

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

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

        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 volumes attachments on an instance.

        This request lists 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: Optional[bool] = None,
        name: Optional[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: Optional[str] = None,
        limit: Optional[int] = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        List instance groups.

        This request lists 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: Optional[int] = None,
        load_balancer: Optional['LoadBalancerIdentity'] = None,
        load_balancer_pool: Optional['LoadBalancerPoolIdentity'] = None,
        membership_count: Optional[int] = None,
        name: Optional[str] = None,
        resource_group: Optional['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: Optional[str] = None,
        limit: Optional[int] = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        List managers for an instance group.

        This request lists 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: Optional[str] = None,
        limit: Optional[int] = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        List actions for an instance group manager.

        This request lists 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: Optional[str] = None,
        limit: Optional[int] = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        List policies for an instance group manager.

        This request lists 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 memberships from an instance group.

        This request deletes memberships of an instance group. This operation cannot be
        reversed. 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: Optional[str] = None,
        limit: Optional[int] = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        List memberships for an instance group.

        This request lists 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

    #########################
    # Reservations
    #########################

    def list_reservations(
        self,
        *,
        start: Optional[str] = None,
        limit: Optional[int] = None,
        name: Optional[str] = None,
        resource_group_id: Optional[str] = None,
        zone_name: Optional[str] = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        List reservations.

        This request lists reservations in the region. A reservation provides reserved
        capacity for a specified profile in a specified zone. A reservation can also
        include a long-term committed use discount.
        The reservations will be sorted by their `created_at` property values, with newest
        reservations first. Reservations 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 name: (optional) Filters the collection to resources with a
               `name` property matching the exact specified name.
        :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 dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `ReservationCollection` object
        """

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

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

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

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

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

    def create_reservation(
        self,
        capacity: 'ReservationCapacityPrototype',
        committed_use: 'ReservationCommittedUsePrototype',
        profile: 'ReservationProfilePrototype',
        zone: 'ZoneIdentity',
        *,
        affinity_policy: Optional[str] = None,
        name: Optional[str] = None,
        resource_group: Optional['ResourceGroupIdentity'] = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        Create a reservation.

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

        :param ReservationCapacityPrototype capacity: The capacity reservation
               configuration to use.
        :param ReservationCommittedUsePrototype committed_use: The committed use
               configuration to use for this reservation.
        :param ReservationProfilePrototype profile: The
               [profile](https://cloud.ibm.com/docs/vpc?topic=vpc-profiles) to use for
               this
               reservation.
        :param ZoneIdentity zone: The zone to use for this reservation.
        :param str affinity_policy: (optional) The affinity policy to use for this
               reservation:
               - `restricted`: The reservation must be manually requested.
        :param str name: (optional) The name for this reservation. The name must
               not be used by another reservation 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 `Reservation` object
        """

        if capacity is None:
            raise ValueError('capacity must be provided')
        if committed_use is None:
            raise ValueError('committed_use must be provided')
        if profile is None:
            raise ValueError('profile must be provided')
        if zone is None:
            raise ValueError('zone must be provided')
        capacity = convert_model(capacity)
        committed_use = convert_model(committed_use)
        profile = convert_model(profile)
        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_reservation',
        )
        headers.update(sdk_headers)

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

        data = {
            'capacity': capacity,
            'committed_use': committed_use,
            'profile': profile,
            'zone': zone,
            'affinity_policy': affinity_policy,
            '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 = '/reservations'
        request = self.prepare_request(
            method='POST',
            url=url,
            headers=headers,
            params=params,
            data=data,
        )

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

    def delete_reservation(
        self,
        id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Delete a reservation.

        This request deletes a reservation. This operation cannot be reversed.
        Reservations with a `status` of `active` are not allowed to be deleted.

        :param str id: The reservation identifier.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `Reservation` 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='delete_reservation',
        )
        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 = '/reservations/{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_reservation(
        self,
        id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Retrieve a reservation.

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

        :param str id: The reservation identifier.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `Reservation` 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_reservation',
        )
        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 = '/reservations/{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_reservation(
        self,
        id: str,
        reservation_patch: 'ReservationPatch',
        **kwargs,
    ) -> DetailedResponse:
        """
        Update a reservation.

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

        :param str id: The reservation identifier.
        :param ReservationPatch reservation_patch: The reservation 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 `Reservation` object
        """

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

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

        data = json.dumps(reservation_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 = '/reservations/{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 activate_reservation(
        self,
        id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Activate a reservation.

        This request activates a reservation. For this request to succeed, the reservation
        status must be `inactive`.

        :param str id: The reservation 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='activate_reservation',
        )
        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 = '/reservations/{id}/activate'.format(**path_param_dict)
        request = self.prepare_request(
            method='POST',
            url=url,
            headers=headers,
            params=params,
        )

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

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

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

        This request lists dedicated host groups in the region. Each dedicated host must
        belong to exactly one group, which controls placement of instances. Dedicated 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: Optional[str] = None,
        resource_group: Optional['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: Optional[str] = None,
        limit: Optional[int] = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        List 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: Optional[str] = None,
        start: Optional[str] = None,
        limit: Optional[int] = None,
        resource_group_id: Optional[str] = None,
        zone_name: Optional[str] = None,
        name: Optional[str] = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        List dedicated hosts.

        This request lists 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 disks on a dedicated host.

        This request lists 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

    #########################
    # Placement groups
    #########################

    def list_placement_groups(
        self,
        *,
        start: Optional[str] = None,
        limit: Optional[int] = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        List placement groups.

        This request lists 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: Optional[str] = None,
        resource_group: Optional['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.
        :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: Optional[str] = None,
        limit: Optional[int] = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        List bare metal server profiles.

        This request lists [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: Optional[str] = None,
        limit: Optional[int] = None,
        resource_group_id: Optional[str] = None,
        name: Optional[str] = None,
        vpc_id: Optional[str] = None,
        vpc_crn: Optional[str] = None,
        vpc_name: Optional[str] = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        List bare metal servers.

        This request lists 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,
        bare_metal_server_prototype: 'BareMetalServerPrototype',
        **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 BareMetalServerPrototype bare_metal_server_prototype: The bare metal
               server 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 `BareMetalServer` object
        """

        if bare_metal_server_prototype is None:
            raise ValueError('bare_metal_server_prototype must be provided')
        if isinstance(bare_metal_server_prototype, BareMetalServerPrototype):
            bare_metal_server_prototype = convert_model(bare_metal_server_prototype)
        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 = json.dumps(bare_metal_server_prototype)
        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: Optional[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.  For this request
        to succeed, the server must have a `status` of `stopped`, `starting`, or
        `running`.

        :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 disks on a bare metal server.

        This request lists  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_attachments(
        self,
        bare_metal_server_id: str,
        *,
        start: Optional[str] = None,
        limit: Optional[int] = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        List network attachments on a bare metal server.

        This request lists network attachments on a bare metal server. A bare metal server
        network attachment 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.
        The network attachments will be sorted by their `created_at` property values, with
        newest network attachments first. Network attachments with identical `created_at`
        property values will in turn be sorted by ascending `name` property values.

        :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 `BareMetalServerNetworkAttachmentCollection` 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_attachments',
        )
        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_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_bare_metal_server_network_attachment(
        self,
        bare_metal_server_id: str,
        bare_metal_server_network_attachment_prototype: 'BareMetalServerNetworkAttachmentPrototype',
        **kwargs,
    ) -> DetailedResponse:
        """
        Create a network attachment on a bare metal server.

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

        :param str bare_metal_server_id: The bare metal server identifier.
        :param BareMetalServerNetworkAttachmentPrototype
               bare_metal_server_network_attachment_prototype: The bare metal server
               network attachment 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 `BareMetalServerNetworkAttachment` object
        """

        if not bare_metal_server_id:
            raise ValueError('bare_metal_server_id must be provided')
        if bare_metal_server_network_attachment_prototype is None:
            raise ValueError('bare_metal_server_network_attachment_prototype must be provided')
        if isinstance(bare_metal_server_network_attachment_prototype, BareMetalServerNetworkAttachmentPrototype):
            bare_metal_server_network_attachment_prototype = convert_model(bare_metal_server_network_attachment_prototype)
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='create_bare_metal_server_network_attachment',
        )
        headers.update(sdk_headers)

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

        data = json.dumps(bare_metal_server_network_attachment_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_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_bare_metal_server_network_attachment(
        self,
        bare_metal_server_id: str,
        id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Delete a bare metal server network attachment.

        This request deletes a bare metal server network attachment. This operation cannot
        be reversed. Any floating IPs associated with the bare metal server network
        attachment are implicitly disassociated.
        The bare metal server's primary network attachment cannot be deleted.

        :param str bare_metal_server_id: The bare metal server identifier.
        :param str id: The bare metal server network 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 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_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 = ['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_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_bare_metal_server_network_attachment(
        self,
        bare_metal_server_id: str,
        id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Retrieve a bare metal server network attachment.

        This request retrieves a single bare metal server network attachment 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 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 `BareMetalServerNetworkAttachment` 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_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 = ['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_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_bare_metal_server_network_attachment(
        self,
        bare_metal_server_id: str,
        id: str,
        bare_metal_server_network_attachment_patch: 'BareMetalServerNetworkAttachmentPatch',
        **kwargs,
    ) -> DetailedResponse:
        """
        Update a bare metal server network attachment.

        This request updates a bare metal server network attachment with the information
        provided in a bare metal server network attachment patch object. The bare metal
        server network attachment patch object is structured in the same way as a
        retrieved bare metal server network attachment and contains 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 attachment identifier.
        :param BareMetalServerNetworkAttachmentPatch
               bare_metal_server_network_attachment_patch: The bare metal server network
               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 `BareMetalServerNetworkAttachment` 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_attachment_patch is None:
            raise ValueError('bare_metal_server_network_attachment_patch must be provided')
        if isinstance(bare_metal_server_network_attachment_patch, BareMetalServerNetworkAttachmentPatch):
            bare_metal_server_network_attachment_patch = convert_model(bare_metal_server_network_attachment_patch)
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='update_bare_metal_server_network_attachment',
        )
        headers.update(sdk_headers)

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

        data = json.dumps(bare_metal_server_network_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 = ['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_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

    def list_bare_metal_server_network_interfaces(
        self,
        bare_metal_server_id: str,
        *,
        start: Optional[str] = None,
        limit: Optional[int] = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        List network interfaces on a bare metal server.

        This request lists 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.
        If this bare metal server has network attachments, each returned network interface
        is a [read-only
        representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
        of its corresponding network attachment and its attached virtual network
        interface.

        :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.
        If this bare metal server has network attachments, each network interface is a
        [read-only
        representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
        of its corresponding network attachment and its attached virtual network
        interface, and new network interfaces are not allowed to be created.

        :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.
        If this bare metal server has network attachments, this network interface is a
        [read-only
        representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
        of its corresponding network attachment and its attached virtual network
        interface, and 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.
        If this bare metal server has network attachments, the retrieved network interface
        is a [read-only
        representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
        of its corresponding network attachment and its attached virtual network
        interface.

        :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.
        If this bare metal server has network attachments, this network interface is a
        [read-only
        representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
        of its corresponding network attachment and its attached virtual network
        interface, and is not allowed 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 floating IPs associated with a bare metal server network interface.

        This request lists 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.
        The existing floating IP must:
        - not be required by another resource, such as a public gateway
        - be in the same `zone` as the bare metal server
        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

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

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

        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

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

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

        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 update_firmware_for_bare_metal_server(
        self,
        id: str,
        *,
        auto_start: Optional[bool] = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        Update firmware for a bare metal server.

        This request updates a bare metal server to the latest available firmware. The
        server must be stopped.

        :param str id: The bare metal server identifier.
        :param bool auto_start: (optional) Indicates whether to automatically start
               the bare metal server after the firmware update is successfully completed.
        :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='update_firmware_for_bare_metal_server',
        )
        headers.update(sdk_headers)

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

        data = {
            'auto_start': auto_start,
        }
        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}/firmware/update'.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 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 replace_bare_metal_server_initialization(
        self,
        id: str,
        image: 'ImageIdentity',
        keys: List['KeyIdentity'],
        *,
        user_data: Optional[str] = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        Reinitialize a bare metal server.

        This request reinitializes a bare metal server with the specified image and SSH
        keys. The server must be stopped. Upon successful reinitiatilization, the bare
        metal server will be started automatically.

        :param str id: The bare metal server identifier.
        :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.
               If unspecified, no user data will be made available.
        :param dict headers: 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')
        if image is None:
            raise ValueError('image must be provided')
        if keys is None:
            raise ValueError('keys must be provided')
        image = convert_model(image)
        keys = [convert_model(x) for x in keys]
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='replace_bare_metal_server_initialization',
        )
        headers.update(sdk_headers)

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

        data = {
            'image': image,
            'keys': keys,
            'user_data': user_data,
        }
        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 = ['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='PUT',
            url=url,
            headers=headers,
            params=params,
            data=data,
        )

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

    def restart_bare_metal_server(
        self,
        id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Restart a bare metal server.

        This request immediately restarts a bare metal server.  For this request to
        succeed, the server must have a `status` of `running`.

        :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: Optional[str] = None,
        limit: Optional[int] = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        List volume profiles.

        This request lists [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: Optional[str] = None,
        limit: Optional[int] = None,
        name: Optional[str] = None,
        attachment_state: Optional[str] = None,
        encryption: Optional[str] = None,
        operating_system_family: Optional[str] = None,
        operating_system_architecture: Optional[str] = None,
        zone_name: Optional[str] = None,
        tag: Optional[str] = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        List volumes.

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

        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: Optional[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: Optional[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 list_snapshot_consistency_groups(
        self,
        *,
        start: Optional[str] = None,
        limit: Optional[int] = None,
        resource_group_id: Optional[str] = None,
        name: Optional[str] = None,
        sort: Optional[str] = None,
        backup_policy_plan_id: Optional[str] = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        List snapshot consistency groups.

        This request lists snapshot consistency groups in the region. A snapshot
        consistency group is a collection of individual snapshots taken at the same time.

        :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 backup_policy_plan_id: (optional) Filters the collection to
               backup policy jobs with a `backup_policy_plan.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 `SnapshotConsistencyGroupCollection` object
        """

        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='list_snapshot_consistency_groups',
        )
        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,
            'backup_policy_plan.id': backup_policy_plan_id,
        }

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

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

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

    def create_snapshot_consistency_group(
        self,
        snapshot_consistency_group_prototype: 'SnapshotConsistencyGroupPrototype',
        **kwargs,
    ) -> DetailedResponse:
        """
        Create a snapshot consistency group.

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

        :param SnapshotConsistencyGroupPrototype
               snapshot_consistency_group_prototype: The snapshot consistency group
               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 `SnapshotConsistencyGroup` object
        """

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

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

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

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

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

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

    def delete_snapshot_consistency_group(
        self,
        id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Delete a snapshot consistency group.

        This request deletes snapshot consistency group. This operation cannot be
        reversed. If the `delete_snapshots_on_delete` property is `true`, all snapshots in
        the consistency group will also be deleted.

        :param str id: The snapshot consistency 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 `SnapshotConsistencyGroup` 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='delete_snapshot_consistency_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 = '/snapshot_consistency_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_snapshot_consistency_group(
        self,
        id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Retrieve a snapshot consistency group.

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

        :param str id: The snapshot consistency 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 `SnapshotConsistencyGroup` 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_consistency_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 = '/snapshot_consistency_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_snapshot_consistency_group(
        self,
        id: str,
        snapshot_consistency_group_patch: 'SnapshotConsistencyGroupPatch',
        *,
        if_match: Optional[str] = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        Update a snapshot consistency group.

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

        :param str id: The snapshot consistency group identifier.
        :param SnapshotConsistencyGroupPatch snapshot_consistency_group_patch: The
               snapshot consistency group 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 `SnapshotConsistencyGroup` object
        """

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

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

        data = json.dumps(snapshot_consistency_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 = '/snapshot_consistency_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_snapshots(
        self,
        source_volume_id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Delete a filtered collection of snapshots.

        This request deletes snapshots that match the specified filter. This operation
        cannot be reversed.

        :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: Optional[str] = None,
        limit: Optional[int] = None,
        tag: Optional[str] = None,
        resource_group_id: Optional[str] = None,
        name: Optional[str] = None,
        source_volume_id: Optional[str] = None,
        source_volume_crn: Optional[str] = None,
        source_image_id: Optional[str] = None,
        source_image_crn: Optional[str] = None,
        sort: Optional[str] = None,
        backup_policy_plan_id: Optional[str] = None,
        copies_id: Optional[str] = None,
        copies_name: Optional[str] = None,
        copies_crn: Optional[str] = None,
        copies_remote_region_name: Optional[str] = None,
        source_snapshot_id: Optional[str] = None,
        source_snapshot_remote_region_name: Optional[str] = None,
        source_volume_remote_region_name: Optional[str] = None,
        source_image_remote_region_name: Optional[str] = None,
        clones_zone_name: Optional[str] = None,
        snapshot_consistency_group_id: Optional[str] = None,
        snapshot_consistency_group_crn: Optional[str] = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        List snapshots.

        This request lists 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 str snapshot_consistency_group_id: (optional) Filters the collection
               to resources with a `snapshot_consistency_group.id` property matching the
               specified identifier.
        :param str snapshot_consistency_group_crn: (optional) Filters the
               collection to resources with a `snapshot_consistency_group.crn` 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 `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,
            'snapshot_consistency_group.id': snapshot_consistency_group_id,
            'snapshot_consistency_group.crn': snapshot_consistency_group_crn,
        }

        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: Optional[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: Optional[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 clones for a snapshot.

        This request lists 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: Optional[str] = None,
        limit: Optional[int] = None,
        sort: Optional[str] = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        List file share profiles.

        This request lists [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: Optional[str] = None,
        limit: Optional[int] = None,
        resource_group_id: Optional[str] = None,
        name: Optional[str] = None,
        sort: Optional[str] = None,
        replication_role: Optional[str] = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        List file shares.

        This request lists 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: Optional[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: Optional[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 list_share_accessor_bindings(
        self,
        id: str,
        *,
        start: Optional[str] = None,
        limit: Optional[int] = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        List accessor bindings for a file share.

        This request lists accessor bindings for a share. Each accessor binding identifies
        a resource (possibly in another account) with access to this file share's data.
        The share accessor bindings will be sorted by their `created_at` property values,
        with newest bindings first.

        :param str id: The file share 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 `ShareAccessorBindingCollection` 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_share_accessor_bindings',
        )
        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 = ['id']
        path_param_values = self.encode_path_vars(id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/shares/{id}/accessor_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 delete_share_accessor_binding(
        self,
        share_id: str,
        id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Delete a file share accessor binding.

        This request deletes a share accessor binding. This operation cannot be reversed.

        :param str share_id: The file share identifier.
        :param str id: The file share accessor 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 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_accessor_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 = ['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}/accessor_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_share_accessor_binding(
        self,
        share_id: str,
        id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Retrieve a file share accessor binding.

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

        :param str share_id: The file share identifier.
        :param str id: The file share accessor 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 `ShareAccessorBinding` 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_accessor_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 = ['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}/accessor_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 failover_share(
        self,
        share_id: str,
        *,
        fallback_policy: Optional[str] = None,
        timeout: Optional[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: Optional[str] = None,
        start: Optional[str] = None,
        limit: Optional[int] = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        List mount targets for a file share.

        This request lists mount targets for a file share. A 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 file 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 file 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 file 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 file 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 file 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 file 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 file 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

    #########################
    # Backup policies
    #########################

    def list_backup_policies(
        self,
        *,
        start: Optional[str] = None,
        limit: Optional[int] = None,
        resource_group_id: Optional[str] = None,
        name: Optional[str] = None,
        tag: Optional[str] = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        List backup policies.

        This request lists 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,
        backup_policy_prototype: 'BackupPolicyPrototype',
        **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 BackupPolicyPrototype backup_policy_prototype: The backup 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 `BackupPolicy` object
        """

        if backup_policy_prototype is None:
            raise ValueError('backup_policy_prototype must be provided')
        if isinstance(backup_policy_prototype, BackupPolicyPrototype):
            backup_policy_prototype = convert_model(backup_policy_prototype)
        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 = json.dumps(backup_policy_prototype)
        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: Optional[str] = None,
        backup_policy_plan_id: Optional[str] = None,
        start: Optional[str] = None,
        limit: Optional[int] = None,
        sort: Optional[str] = None,
        source_id: Optional[str] = None,
        target_snapshots_id: Optional[str] = None,
        target_snapshots_crn: Optional[str] = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        List jobs for a backup policy.

        This request retrieves 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: Optional[str] = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        List plans for a backup policy.

        This request retrieves 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: Optional[bool] = None,
        attach_user_tags: Optional[List[str]] = None,
        clone_policy: Optional['BackupPolicyPlanClonePolicyPrototype'] = None,
        copy_user_tags: Optional[bool] = None,
        deletion_trigger: Optional['BackupPolicyPlanDeletionTriggerPrototype'] = None,
        name: Optional[str] = None,
        remote_region_policies: Optional[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: Optional[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: Optional[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: Optional[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: Optional[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

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

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

        This request lists 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 zones in a region.

        This request lists 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: Optional[str] = None,
        limit: Optional[int] = None,
        resource_group_id: Optional[str] = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        List virtual network interfaces.

        This request lists 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 create_virtual_network_interface(
        self,
        *,
        allow_ip_spoofing: Optional[bool] = None,
        auto_delete: Optional[bool] = None,
        enable_infrastructure_nat: Optional[bool] = None,
        ips: Optional[List['VirtualNetworkInterfaceIPPrototype']] = None,
        name: Optional[str] = None,
        primary_ip: Optional['VirtualNetworkInterfacePrimaryIPPrototype'] = None,
        protocol_state_filtering_mode: Optional[str] = None,
        resource_group: Optional['ResourceGroupIdentity'] = None,
        security_groups: Optional[List['SecurityGroupIdentity']] = None,
        subnet: Optional['SubnetIdentity'] = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        Create a virtual network interface.

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

        :param bool allow_ip_spoofing: (optional) Indicates whether source IP
               spoofing is allowed on this interface. If `false`, source IP spoofing is
               prevented on this interface. If `true`, source IP spoofing is allowed on
               this interface.
        :param bool auto_delete: (optional) Indicates whether this virtual network
               interface will be automatically deleted when
               `target` is deleted. Must be `false` if the virtual network interface is
               unbound.
        :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 virtual network interface,
                 allowing the workload to perform any needed NAT operations.
               - `allow_ip_spoofing` must be `false`.
               - Can only be attached to a `target` with a `resource_type` of
                 `bare_metal_server_network_attachment`.
        :param List[VirtualNetworkInterfaceIPPrototype] ips: (optional) Additional
               IP addresses to bind to the virtual network interface. Each item may be
               either a reserved IP identity, or a reserved IP prototype object which will
               be used to create a new reserved IP. All IP addresses must be in the
               primary IP's subnet.
               If reserved IP identities are provided, the specified reserved IPs must be
               unbound.
               If reserved IP prototype objects with addresses are provided, the addresses
               must be available on the virtual network interface's subnet. For any
               prototype objects that do not specify an address, an available address on
               the subnet will be automatically selected and reserved.
        :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 str protocol_state_filtering_mode: (optional) The protocol state
               filtering mode to use for this virtual network interface. If
               `auto`, protocol state packet filtering is enabled or disabled based on the
               virtual network interface's `target` resource type:
               - `bare_metal_server_network_attachment`: disabled
               - `instance_network_attachment`: enabled
               - `share_mount_target`: enabled
               Protocol state filtering monitors each network connection flowing over this
               virtual network interface, and drops any packets that are invalid based on
               the current connection state and protocol. See [Protocol state filtering
               mode](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#protocol-state-filtering)
               for more information.
        :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 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.
        :param dict headers: 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 ips is not None:
            ips = [convert_model(x) for x in ips]
        if primary_ip is not None:
            primary_ip = convert_model(primary_ip)
        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]
        if subnet is not None:
            subnet = convert_model(subnet)
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='create_virtual_network_interface',
        )
        headers.update(sdk_headers)

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

        data = {
            'allow_ip_spoofing': allow_ip_spoofing,
            'auto_delete': auto_delete,
            'enable_infrastructure_nat': enable_infrastructure_nat,
            'ips': ips,
            'name': name,
            'primary_ip': primary_ip,
            'protocol_state_filtering_mode': protocol_state_filtering_mode,
            'resource_group': resource_group,
            'security_groups': security_groups,
            'subnet': subnet,
        }
        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 = '/virtual_network_interfaces'
        request = self.prepare_request(
            method='POST',
            url=url,
            headers=headers,
            params=params,
            data=data,
        )

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

    def delete_virtual_network_interfaces(
        self,
        id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Delete a virtual network interface.

        This request deletes a virtual network interface. This operation cannot be
        reversed. For this request to succeed, the virtual network interface must not be
        required by another resource, such as the primary network attachment for an
        instance.

        :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='delete_virtual_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 = ['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='DELETE',
            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

    def list_network_interface_floating_ips(
        self,
        virtual_network_interface_id: str,
        *,
        start: Optional[str] = None,
        limit: Optional[int] = None,
        sort: Optional[str] = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        List floating IPs associated with a virtual network interface.

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

        :param str virtual_network_interface_id: The virtual 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 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
               `-name` sorts the collection by the `name` 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 `FloatingIPCollectionVirtualNetworkInterfaceContext` object
        """

        if not virtual_network_interface_id:
            raise ValueError('virtual_network_interface_id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='list_network_interface_floating_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 = ['virtual_network_interface_id']
        path_param_values = self.encode_path_vars(virtual_network_interface_id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/virtual_network_interfaces/{virtual_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_network_interface_floating_ip(
        self,
        virtual_network_interface_id: str,
        id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Disassociate a floating IP from a virtual network interface.

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

        :param str virtual_network_interface_id: The virtual 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 virtual_network_interface_id:
            raise ValueError('virtual_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_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 = ['virtual_network_interface_id', 'id']
        path_param_values = self.encode_path_vars(virtual_network_interface_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/virtual_network_interfaces/{virtual_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_network_interface_floating_ip(
        self,
        virtual_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
        virtual network interface specified in the URL.

        :param str virtual_network_interface_id: The virtual 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 `FloatingIPReference` object
        """

        if not virtual_network_interface_id:
            raise ValueError('virtual_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_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 = ['virtual_network_interface_id', 'id']
        path_param_values = self.encode_path_vars(virtual_network_interface_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/virtual_network_interfaces/{virtual_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_network_interface_floating_ip(
        self,
        virtual_network_interface_id: str,
        id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Add an association between a floating IP and a virtual network interface.

        This request adds an association between the specified floating IP and the
        specified virtual network interface.
        If the virtual network interface has `enable_infrastructure_nat` set to `true`, no
        more than one floating IP can be associated, and network address translation is
        performed between the floating IP address and the virtual network interface's
        `primary_ip` address.
        If the virtual network interface has `enable_infrastructure_nat` set to `false`,
        packets are passed unchanged to/from the virtual network interface.
        The floating IP must:
        - be in the same `zone` as the virtual network interface
        - not currently be associated with another resource
        The virtual network interface's `target` must not currently be a file share mount
        target.
        A request body is not required, and if provided, is ignored.

        :param str virtual_network_interface_id: The virtual 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 `FloatingIPReference` object
        """

        if not virtual_network_interface_id:
            raise ValueError('virtual_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_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 = ['virtual_network_interface_id', 'id']
        path_param_values = self.encode_path_vars(virtual_network_interface_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/virtual_network_interfaces/{virtual_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_virtual_network_interface_ips(
        self,
        virtual_network_interface_id: str,
        *,
        start: Optional[str] = None,
        limit: Optional[int] = None,
        sort: Optional[str] = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        List reserved IPs bound to a virtual network interface.

        This request lists reserved IPs bound to a virtual network interface.

        :param str virtual_network_interface_id: The virtual 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 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
               `-name` sorts the collection by the `name` 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 `ReservedIPCollectionVirtualNetworkInterfaceContext` object
        """

        if not virtual_network_interface_id:
            raise ValueError('virtual_network_interface_id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='list_virtual_network_interface_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 = ['virtual_network_interface_id']
        path_param_values = self.encode_path_vars(virtual_network_interface_id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/virtual_network_interfaces/{virtual_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 remove_virtual_network_interface_ip(
        self,
        virtual_network_interface_id: str,
        id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Unbind a reserved IP from a virtual network interface.

        This request unbinds the specified reserved IP from the specified virtual network
        interface. If the reserved IP has `auto_delete` set to `true`, the reserved IP
        will be deleted.
        The reserved IP for the `primary_ip` cannot be unbound.

        :param str virtual_network_interface_id: The virtual 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
        """

        if not virtual_network_interface_id:
            raise ValueError('virtual_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_virtual_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']

        path_param_keys = ['virtual_network_interface_id', 'id']
        path_param_values = self.encode_path_vars(virtual_network_interface_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/virtual_network_interfaces/{virtual_network_interface_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_virtual_network_interface_ip(
        self,
        virtual_network_interface_id: str,
        id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Retrieve bound reserved IP.

        This request retrieves the specified reserved IP address if it is bound to the
        virtual network interface specified in the URL.

        :param str virtual_network_interface_id: The virtual 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 `ReservedIPReference` object
        """

        if not virtual_network_interface_id:
            raise ValueError('virtual_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_virtual_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 = ['virtual_network_interface_id', 'id']
        path_param_values = self.encode_path_vars(virtual_network_interface_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/virtual_network_interfaces/{virtual_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 add_virtual_network_interface_ip(
        self,
        virtual_network_interface_id: str,
        id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Bind a reserved IP to a virtual network interface.

        This request binds the specified reserved IP to the specified virtual network
        interface.
        The reserved IP must currently be unbound and in the primary IP's subnet. The
        virtual network interface's `target` must not currently be a file share mount
        target.

        :param str virtual_network_interface_id: The virtual 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 `ReservedIPReference` object
        """

        if not virtual_network_interface_id:
            raise ValueError('virtual_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_virtual_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 = ['virtual_network_interface_id', 'id']
        path_param_values = self.encode_path_vars(virtual_network_interface_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/virtual_network_interfaces/{virtual_network_interface_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

    #########################
    # Cluster networks
    #########################

    def list_cluster_network_profiles(
        self,
        *,
        start: Optional[str] = None,
        limit: Optional[int] = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        List cluster network profiles.

        This request lists cluster network profiles available in the region. A cluster
        network profile specifies the performance characteristics and capabilities for a
        cluster network.

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

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

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

    def get_cluster_network_profile(
        self,
        name: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Retrieve a cluster network profile.

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

        :param str name: The cluster network 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 `ClusterNetworkProfile` 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_cluster_network_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 = '/cluster_network/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_cluster_networks(
        self,
        *,
        start: Optional[str] = None,
        limit: Optional[int] = None,
        resource_group_id: Optional[str] = None,
        name: Optional[str] = None,
        sort: Optional[str] = None,
        vpc_id: Optional[str] = None,
        vpc_crn: Optional[str] = None,
        vpc_name: Optional[str] = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        List cluster networks.

        This request lists [cluster
        networks](https://cloud.ibm.com/docs/vpc?topic=vpc-about-cluster-network) in the
        region. A cluster network is a grouping of resources in a separate networking
        space for high performance computing and networking.

        :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 vpc_id: (optional) Filters the collection to cluster networks
               with a `vpc.id` property matching the specified id.
        :param str vpc_crn: (optional) Filters the collection to cluster networks
               with a `vpc.crn` property matching the specified CRN.
        :param str vpc_name: (optional) Filters the collection to cluster networks
               with a `vpc.name` property matching the specified name.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `ClusterNetworkCollection` object
        """

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

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

    def create_cluster_network(
        self,
        profile: 'ClusterNetworkProfileIdentity',
        vpc: 'VPCIdentity',
        zone: 'ZoneIdentity',
        *,
        name: Optional[str] = None,
        resource_group: Optional['ResourceGroupIdentity'] = None,
        subnet_prefixes: Optional[List['ClusterNetworkSubnetPrefixPrototype']] = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        Create a cluster network.

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

        :param ClusterNetworkProfileIdentity profile: The profile to use for this
               cluster network.
        :param VPCIdentity vpc: The VPC this cluster network will reside in.
        :param ZoneIdentity zone: The zone this cluster network will reside in. The
               zone must be listed
               as supported on the specified cluster network profile.
        :param str name: (optional) The name for this cluster network. The name
               must not be used by another cluster network in the region. 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 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[ClusterNetworkSubnetPrefixPrototype] subnet_prefixes:
               (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 `ClusterNetwork` object
        """

        if profile is None:
            raise ValueError('profile must be provided')
        if vpc is None:
            raise ValueError('vpc must be provided')
        if zone is None:
            raise ValueError('zone must be provided')
        profile = convert_model(profile)
        vpc = convert_model(vpc)
        zone = convert_model(zone)
        if resource_group is not None:
            resource_group = convert_model(resource_group)
        if subnet_prefixes is not None:
            subnet_prefixes = [convert_model(x) for x in subnet_prefixes]
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='create_cluster_network',
        )
        headers.update(sdk_headers)

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

        data = {
            'profile': profile,
            'vpc': vpc,
            'zone': zone,
            'name': name,
            'resource_group': resource_group,
            'subnet_prefixes': subnet_prefixes,
        }
        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 = '/cluster_networks'
        request = self.prepare_request(
            method='POST',
            url=url,
            headers=headers,
            params=params,
            data=data,
        )

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

    def list_cluster_network_interfaces(
        self,
        cluster_network_id: str,
        *,
        start: Optional[str] = None,
        limit: Optional[int] = None,
        name: Optional[str] = None,
        sort: Optional[str] = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        List cluster network interfaces.

        This request lists cluster network interfaces in the region. A cluster network
        interface is a logical abstraction of a cluster network interface in a subnet, and
        may be attached to a target resource.
        The cluster network interfaces will be sorted by their `created_at` property
        values, with newest cluster network interfaces first. Cluster network interfaces
        with identical
        `created_at` property values will in turn be sorted by ascending `name` property
        values.

        :param str cluster_network_id: The cluster network 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 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 dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `ClusterNetworkInterfaceCollection` object
        """

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

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

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

        path_param_keys = ['cluster_network_id']
        path_param_values = self.encode_path_vars(cluster_network_id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/cluster_networks/{cluster_network_id}/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_cluster_network_interface(
        self,
        cluster_network_id: str,
        *,
        name: Optional[str] = None,
        primary_ip: Optional['ClusterNetworkInterfacePrimaryIPPrototype'] = None,
        subnet: Optional['ClusterNetworkSubnetIdentity'] = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        Create a cluster network interface.

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

        :param str cluster_network_id: The cluster network identifier.
        :param str name: (optional) The name for this cluster network interface.
               The name must not be used by another interface in the cluster network.
               Names beginning 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 ClusterNetworkInterfacePrimaryIPPrototype primary_ip: (optional) The
               primary IP address to bind to the cluster network interface. May be either
               a cluster network subnet reserved IP identity, or a cluster network subnet
               reserved IP
               prototype object which will be used to create a new cluster network subnet
               reserved IP.
               If a cluster network subnet reserved IP identity is provided, the specified
               cluster
               network subnet reserved IP must be unbound.
               If a cluster network subnet reserved IP prototype object with an address is
               provided,
               the address must be available on the cluster network interface's cluster
               network
               subnet. If no address is specified, an available address on the cluster
               network subnet
               will be automatically selected and reserved.
        :param ClusterNetworkSubnetIdentity subnet: (optional) The associated
               cluster network subnet. Required if `primary_ip` does not specify a cluster
               network subnet reserved IP 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 `ClusterNetworkInterface` object
        """

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

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

        data = {
            'name': name,
            'primary_ip': primary_ip,
            'subnet': subnet,
        }
        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 = ['cluster_network_id']
        path_param_values = self.encode_path_vars(cluster_network_id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/cluster_networks/{cluster_network_id}/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_cluster_network_interface(
        self,
        cluster_network_id: str,
        id: str,
        *,
        if_match: Optional[str] = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        Delete a cluster network interface.

        This request deletes a cluster network interface. This operation cannot be
        reversed. For this request to succeed,  the cluster network interface must not be
        required by another resource, such as a cluster network attachment for a virtual
        server instance.

        :param str cluster_network_id: The cluster network identifier.
        :param str id: The cluster network interface 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 `ClusterNetworkInterface` object
        """

        if not cluster_network_id:
            raise ValueError('cluster_network_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_cluster_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 = ['cluster_network_id', 'id']
        path_param_values = self.encode_path_vars(cluster_network_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/cluster_networks/{cluster_network_id}/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_cluster_network_interface(
        self,
        cluster_network_id: str,
        id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Retrieve a cluster network interface.

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

        :param str cluster_network_id: The cluster network identifier.
        :param str id: The cluster 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 `ClusterNetworkInterface` object
        """

        if not cluster_network_id:
            raise ValueError('cluster_network_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_cluster_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 = ['cluster_network_id', 'id']
        path_param_values = self.encode_path_vars(cluster_network_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/cluster_networks/{cluster_network_id}/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_cluster_network_interface(
        self,
        cluster_network_id: str,
        id: str,
        cluster_network_interface_patch: 'ClusterNetworkInterfacePatch',
        *,
        if_match: Optional[str] = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        Update a cluster network interface.

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

        :param str cluster_network_id: The cluster network identifier.
        :param str id: The cluster network interface identifier.
        :param ClusterNetworkInterfacePatch cluster_network_interface_patch: The
               cluster network interface 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 `ClusterNetworkInterface` object
        """

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

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

        data = json.dumps(cluster_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 = ['cluster_network_id', 'id']
        path_param_values = self.encode_path_vars(cluster_network_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/cluster_networks/{cluster_network_id}/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_cluster_network_subnets(
        self,
        cluster_network_id: str,
        *,
        start: Optional[str] = None,
        limit: Optional[int] = None,
        name: Optional[str] = None,
        sort: Optional[str] = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        List cluster network subnets.

        This request lists cluster network subnets in the cluster network. A cluster
        network subnet provides network routing between other cluster network subnets
        within a cluster network.

        :param str cluster_network_id: The cluster network 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 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 dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `ClusterNetworkSubnetCollection` object
        """

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

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

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

        path_param_keys = ['cluster_network_id']
        path_param_values = self.encode_path_vars(cluster_network_id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/cluster_networks/{cluster_network_id}/subnets'.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_cluster_network_subnet(
        self,
        cluster_network_id: str,
        cluster_network_subnet_prototype: 'ClusterNetworkSubnetPrototype',
        **kwargs,
    ) -> DetailedResponse:
        """
        Create a cluster network subnet.

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

        :param str cluster_network_id: The cluster network identifier.
        :param ClusterNetworkSubnetPrototype cluster_network_subnet_prototype: The
               cluster network 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 `ClusterNetworkSubnet` object
        """

        if not cluster_network_id:
            raise ValueError('cluster_network_id must be provided')
        if cluster_network_subnet_prototype is None:
            raise ValueError('cluster_network_subnet_prototype must be provided')
        if isinstance(cluster_network_subnet_prototype, ClusterNetworkSubnetPrototype):
            cluster_network_subnet_prototype = convert_model(cluster_network_subnet_prototype)
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='create_cluster_network_subnet',
        )
        headers.update(sdk_headers)

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

        data = json.dumps(cluster_network_subnet_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 = ['cluster_network_id']
        path_param_values = self.encode_path_vars(cluster_network_id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/cluster_networks/{cluster_network_id}/subnets'.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_cluster_network_subnet_reserved_ips(
        self,
        cluster_network_id: str,
        cluster_network_subnet_id: str,
        *,
        start: Optional[str] = None,
        limit: Optional[int] = None,
        name: Optional[str] = None,
        sort: Optional[str] = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        List cluster network subnet reserved IPs.

        This request lists cluster network subnet reserved IPs in the cluster network.

        :param str cluster_network_id: The cluster network identifier.
        :param str cluster_network_subnet_id: The cluster network 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 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 dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `ClusterNetworkSubnetReservedIPCollection` object
        """

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

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

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

        path_param_keys = ['cluster_network_id', 'cluster_network_subnet_id']
        path_param_values = self.encode_path_vars(cluster_network_id, cluster_network_subnet_id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/cluster_networks/{cluster_network_id}/subnets/{cluster_network_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_cluster_network_subnet_reserved_ip(
        self,
        cluster_network_id: str,
        cluster_network_subnet_id: str,
        *,
        address: Optional[str] = None,
        name: Optional[str] = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        Create a cluster network subnet reserved IP.

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

        :param str cluster_network_id: The cluster network identifier.
        :param str cluster_network_subnet_id: The cluster network 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 str name: (optional) The name for this cluster network subnet
               reserved IP. The name must not be used by another reserved IP in the
               cluster network 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 dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `ClusterNetworkSubnetReservedIP` object
        """

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

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

        data = {
            'address': address,
            '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 = ['cluster_network_id', 'cluster_network_subnet_id']
        path_param_values = self.encode_path_vars(cluster_network_id, cluster_network_subnet_id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/cluster_networks/{cluster_network_id}/subnets/{cluster_network_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_cluster_network_subnet_reserved_ip(
        self,
        cluster_network_id: str,
        cluster_network_subnet_id: str,
        id: str,
        *,
        if_match: Optional[str] = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        Delete a cluster network subnet reserved IP.

        This request deletes a cluster network subnet reserved IP. This operation cannot
        be reversed.
        For this request to succeed, the reserved IP must be unbound. A provider-owned
        reserved IP is not allowed to be deleted.

        :param str cluster_network_id: The cluster network identifier.
        :param str cluster_network_subnet_id: The cluster network subnet
               identifier.
        :param str id: The cluster network subnet reserved IP 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 `ClusterNetworkSubnetReservedIP` object
        """

        if not cluster_network_id:
            raise ValueError('cluster_network_id must be provided')
        if not cluster_network_subnet_id:
            raise ValueError('cluster_network_subnet_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_cluster_network_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 = ['cluster_network_id', 'cluster_network_subnet_id', 'id']
        path_param_values = self.encode_path_vars(cluster_network_id, cluster_network_subnet_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/cluster_networks/{cluster_network_id}/subnets/{cluster_network_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_cluster_network_subnet_reserved_ip(
        self,
        cluster_network_id: str,
        cluster_network_subnet_id: str,
        id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Retrieve a cluster network subnet reserved IP.

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

        :param str cluster_network_id: The cluster network identifier.
        :param str cluster_network_subnet_id: The cluster network subnet
               identifier.
        :param str id: The cluster network subnet 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 `ClusterNetworkSubnetReservedIP` object
        """

        if not cluster_network_id:
            raise ValueError('cluster_network_id must be provided')
        if not cluster_network_subnet_id:
            raise ValueError('cluster_network_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_cluster_network_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 = ['cluster_network_id', 'cluster_network_subnet_id', 'id']
        path_param_values = self.encode_path_vars(cluster_network_id, cluster_network_subnet_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/cluster_networks/{cluster_network_id}/subnets/{cluster_network_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_cluster_network_subnet_reserved_ip(
        self,
        cluster_network_id: str,
        cluster_network_subnet_id: str,
        id: str,
        cluster_network_subnet_reserved_ip_patch: 'ClusterNetworkSubnetReservedIPPatch',
        *,
        if_match: Optional[str] = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        Update a cluster network subnet reserved IP.

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

        :param str cluster_network_id: The cluster network identifier.
        :param str cluster_network_subnet_id: The cluster network subnet
               identifier.
        :param str id: The cluster network subnet reserved IP identifier.
        :param ClusterNetworkSubnetReservedIPPatch
               cluster_network_subnet_reserved_ip_patch: The cluster network subnet
               reserved IP 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 `ClusterNetworkSubnetReservedIP` object
        """

        if not cluster_network_id:
            raise ValueError('cluster_network_id must be provided')
        if not cluster_network_subnet_id:
            raise ValueError('cluster_network_subnet_id must be provided')
        if not id:
            raise ValueError('id must be provided')
        if cluster_network_subnet_reserved_ip_patch is None:
            raise ValueError('cluster_network_subnet_reserved_ip_patch must be provided')
        if isinstance(cluster_network_subnet_reserved_ip_patch, ClusterNetworkSubnetReservedIPPatch):
            cluster_network_subnet_reserved_ip_patch = convert_model(cluster_network_subnet_reserved_ip_patch)
        headers = {
            'If-Match': if_match,
        }
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='update_cluster_network_subnet_reserved_ip',
        )
        headers.update(sdk_headers)

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

        data = json.dumps(cluster_network_subnet_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 = ['cluster_network_id', 'cluster_network_subnet_id', 'id']
        path_param_values = self.encode_path_vars(cluster_network_id, cluster_network_subnet_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/cluster_networks/{cluster_network_id}/subnets/{cluster_network_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

    def delete_cluster_network_subnet(
        self,
        cluster_network_id: str,
        id: str,
        *,
        if_match: Optional[str] = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        Delete a cluster network subnet.

        This request deletes a cluster network subnet. This operation cannot be reversed.
        For this request to succeed, this cluster subnet must not be attached to a cluster
        network interface.

        :param str cluster_network_id: The cluster network identifier.
        :param str id: The cluster network subnet 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 `ClusterNetworkSubnet` object
        """

        if not cluster_network_id:
            raise ValueError('cluster_network_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_cluster_network_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 = ['cluster_network_id', 'id']
        path_param_values = self.encode_path_vars(cluster_network_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/cluster_networks/{cluster_network_id}/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_cluster_network_subnet(
        self,
        cluster_network_id: str,
        id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Retrieve a cluster network subnet.

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

        :param str cluster_network_id: The cluster network identifier.
        :param str id: The cluster network 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 `ClusterNetworkSubnet` object
        """

        if not cluster_network_id:
            raise ValueError('cluster_network_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_cluster_network_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 = ['cluster_network_id', 'id']
        path_param_values = self.encode_path_vars(cluster_network_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/cluster_networks/{cluster_network_id}/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_cluster_network_subnet(
        self,
        cluster_network_id: str,
        id: str,
        cluster_network_subnet_patch: 'ClusterNetworkSubnetPatch',
        *,
        if_match: Optional[str] = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        Update a cluster network subnet.

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

        :param str cluster_network_id: The cluster network identifier.
        :param str id: The cluster network subnet identifier.
        :param ClusterNetworkSubnetPatch cluster_network_subnet_patch: The cluster
               network subnet 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 `ClusterNetworkSubnet` object
        """

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

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

        data = json.dumps(cluster_network_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 = ['cluster_network_id', 'id']
        path_param_values = self.encode_path_vars(cluster_network_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/cluster_networks/{cluster_network_id}/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 delete_cluster_network(
        self,
        id: str,
        *,
        if_match: Optional[str] = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        Delete a cluster network.

        This request deletes a cluster network. This operation cannot be reversed.
        For this request to succeed, virtual server instances must not reside in this
        cluster network.

        :param str id: The cluster network 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 `ClusterNetwork` 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_cluster_network',
        )
        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 = '/cluster_networks/{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_cluster_network(
        self,
        id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Retrieve a cluster network.

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

        :param str id: The cluster network identifier.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `ClusterNetwork` 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_cluster_network',
        )
        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 = '/cluster_networks/{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_cluster_network(
        self,
        id: str,
        cluster_network_patch: 'ClusterNetworkPatch',
        *,
        if_match: Optional[str] = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        Update a cluster.

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

        :param str id: The cluster network identifier.
        :param ClusterNetworkPatch cluster_network_patch: The cluster network
               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 `ClusterNetwork` object
        """

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

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

        data = json.dumps(cluster_network_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 = '/cluster_networks/{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: Optional[str] = None,
        limit: Optional[int] = None,
        resource_group_id: Optional[str] = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        List public gateways.

        This request lists 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: Optional['PublicGatewayFloatingIPPrototype'] = None,
        name: Optional[str] = None,
        resource_group: Optional['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: Optional[str] = None,
        limit: Optional[int] = None,
        resource_group_id: Optional[str] = None,
        sort: Optional[str] = None,
        target_id: Optional[str] = None,
        target_crn: Optional[str] = None,
        target_name: Optional[str] = None,
        target_resource_type: Optional[str] = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        List floating IPs.

        This request lists 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 str target_id: (optional) Filters the collection to resources with a
               `target.id` property matching the specified identifier.
        :param str target_crn: (optional) Filters the collection to resources with
               a `target.crn` property matching the specified CRN.
        :param str target_name: (optional) Filters the collection to resources with
               a `target.name` property matching the exact specified name.
        :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 `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,
            'target.id': target_id,
            'target.crn': target_crn,
            'target.name': target_name,
            'target.resource_type': target_resource_type,
        }

        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: Optional[str] = None,
        limit: Optional[int] = None,
        resource_group_id: Optional[str] = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        List network ACLs.

        This request lists 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: Optional[str] = None,
        limit: Optional[int] = None,
        direction: Optional[str] = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        List rules for a network ACL.

        This request lists 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 provided patch includes properties that are not used by 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: Optional[str] = None,
        limit: Optional[int] = None,
        resource_group_id: Optional[str] = None,
        vpc_id: Optional[str] = None,
        vpc_crn: Optional[str] = None,
        vpc_name: Optional[str] = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        List security groups.

        This request lists 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: Optional[str] = None,
        resource_group: Optional['ResourceGroupIdentity'] = None,
        rules: Optional[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 rules in a security group.

        This request lists 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 provided patch includes properties that are not used
        by 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: Optional[str] = None,
        limit: Optional[int] = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        List targets associated with a security group.

        This request lists 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: Optional[str] = None,
        limit: Optional[int] = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        List IKE policies.

        This request lists 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: Optional[int] = None,
        name: Optional[str] = None,
        resource_group: Optional['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,
        *,
        start: Optional[str] = None,
        limit: Optional[int] = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        List VPN gateway connections that use a specified IKE policy.

        This request lists VPN gateway connections that use a IKE policy.

        :param str id: The IKE policy 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 `IKEPolicyConnectionCollection` 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,
            'start': start,
            'limit': limit,
        }

        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: Optional[str] = None,
        limit: Optional[int] = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        List IPsec policies.

        This request lists 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: Optional[int] = None,
        name: Optional[str] = None,
        resource_group: Optional['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`
               The `md5` and `sha1` algorithms have been deprecated.
        :param str encryption_algorithm: The encryption algorithm
               The `authentication_algorithm` must be `disabled` if and only if
               `encryption_algorithm` is `aes128gcm16`, `aes192gcm16`, or `aes256gcm16`
               The `triple_des` algorithm has been deprecated.
        :param str pfs: The Perfect Forward Secrecy group.
               Groups `group_2` and `group_5` have been deprecated.
        :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,
        *,
        start: Optional[str] = None,
        limit: Optional[int] = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        List VPN gateway connections that use a specified IPsec policy.

        This request lists VPN gateway connections that use a IPsec policy.

        :param str id: The IPsec policy 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 `IPsecPolicyConnectionCollection` 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,
            'start': start,
            'limit': limit,
        }

        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: Optional[str] = None,
        limit: Optional[int] = None,
        resource_group_id: Optional[str] = None,
        sort: Optional[str] = None,
        mode: Optional[str] = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        List VPN gateways.

        This request lists 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,
        *,
        start: Optional[str] = None,
        limit: Optional[int] = None,
        status: Optional[str] = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        List connections of a VPN gateway.

        This request lists connections of a VPN gateway.

        :param str vpn_gateway_id: The VPN 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 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,
            'start': start,
            'limit': limit,
            '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_connections_local_cidrs(
        self,
        vpn_gateway_id: str,
        id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        List local CIDRs for a VPN gateway connection.

        This request lists 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 `VPNGatewayConnectionCIDRs` 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_connections_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_connections_local_cidr(
        self,
        vpn_gateway_id: str,
        id: str,
        cidr: 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: The IP address range in CIDR block notation.
        :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:
            raise ValueError('cidr must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='remove_vpn_gateway_connections_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']
        path_param_values = self.encode_path_vars(vpn_gateway_id, id, cidr)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/vpn_gateways/{vpn_gateway_id}/connections/{id}/local/cidrs/{cidr}'.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_connections_local_cidr(
        self,
        vpn_gateway_id: str,
        id: str,
        cidr: 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: The IP address range in CIDR block notation.
        :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:
            raise ValueError('cidr must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='check_vpn_gateway_connections_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']
        path_param_values = self.encode_path_vars(vpn_gateway_id, id, cidr)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/vpn_gateways/{vpn_gateway_id}/connections/{id}/local/cidrs/{cidr}'.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_connections_local_cidr(
        self,
        vpn_gateway_id: str,
        id: str,
        cidr: 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: The IP address range in CIDR block notation.
        :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:
            raise ValueError('cidr must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='add_vpn_gateway_connections_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']
        path_param_values = self.encode_path_vars(vpn_gateway_id, id, cidr)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/vpn_gateways/{vpn_gateway_id}/connections/{id}/local/cidrs/{cidr}'.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_connections_peer_cidrs(
        self,
        vpn_gateway_id: str,
        id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        List peer CIDRs for a VPN gateway connection.

        This request lists 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 `VPNGatewayConnectionCIDRs` 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_connections_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_connections_peer_cidr(
        self,
        vpn_gateway_id: str,
        id: str,
        cidr: 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: The IP address range in CIDR block notation.
        :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:
            raise ValueError('cidr must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='remove_vpn_gateway_connections_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']
        path_param_values = self.encode_path_vars(vpn_gateway_id, id, cidr)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/vpn_gateways/{vpn_gateway_id}/connections/{id}/peer/cidrs/{cidr}'.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_connections_peer_cidr(
        self,
        vpn_gateway_id: str,
        id: str,
        cidr: 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: The IP address range in CIDR block notation.
        :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:
            raise ValueError('cidr must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='check_vpn_gateway_connections_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']
        path_param_values = self.encode_path_vars(vpn_gateway_id, id, cidr)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/vpn_gateways/{vpn_gateway_id}/connections/{id}/peer/cidrs/{cidr}'.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_connections_peer_cidr(
        self,
        vpn_gateway_id: str,
        id: str,
        cidr: 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: The IP address range in CIDR block notation.
        :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:
            raise ValueError('cidr must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='add_vpn_gateway_connections_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']
        path_param_values = self.encode_path_vars(vpn_gateway_id, id, cidr)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/vpn_gateways/{vpn_gateway_id}/connections/{id}/peer/cidrs/{cidr}'.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: Optional[str] = None,
        start: Optional[str] = None,
        limit: Optional[int] = None,
        resource_group_id: Optional[str] = None,
        sort: Optional[str] = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        List VPN servers.

        This request lists 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: Optional[List['IP']] = None,
        client_idle_timeout: Optional[int] = None,
        enable_split_tunneling: Optional[bool] = None,
        name: Optional[str] = None,
        port: Optional[int] = None,
        protocol: Optional[str] = None,
        resource_group: Optional['ResourceGroupIdentity'] = None,
        security_groups: Optional[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: Optional[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: Optional[str] = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        Update a VPN server.

        This request updates the properties of an existing VPN server. Any updates other
        than to `name` will cause all connected VPN clients to be disconnected.

        :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: Optional[str] = None,
        limit: Optional[int] = None,
        sort: Optional[str] = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        List VPN clients for a VPN server.

        This request retrieves 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: Optional[str] = None,
        limit: Optional[int] = None,
        sort: Optional[str] = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        List VPN routes for a VPN server.

        This request lists 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: Optional[str] = None,
        name: Optional[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.

        :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.
        :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: Optional[str] = None,
        limit: Optional[int] = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        List load balancer profiles.

        This request lists 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: Optional[str] = None,
        limit: Optional[int] = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        List load balancers.

        This request lists 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'],
        *,
        dns: Optional['LoadBalancerDNSPrototype'] = None,
        is_private_path: Optional[bool] = None,
        listeners: Optional[List['LoadBalancerListenerPrototypeLoadBalancerContext']] = None,
        logging: Optional['LoadBalancerLoggingPrototype'] = None,
        name: Optional[str] = None,
        pools: Optional[List['LoadBalancerPoolPrototype']] = None,
        profile: Optional['LoadBalancerProfileIdentity'] = None,
        resource_group: Optional['ResourceGroupIdentity'] = None,
        route_mode: Optional[bool] = None,
        security_groups: Optional[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 be private.
               - If `is_private_path` is specified, it must be set to `false`.
        :param List[SubnetIdentity] subnets: The subnets to provision this load
               balancer in.  The subnets must be in the same VPC.
               - If 'availability' is specified as `subnet` in the profile, the load
               balancer's availability will depend on the availability of the zones that
               the subnets reside in.
               - If 'availability' is specified as `region` in the profile, the load
               balancer remains available as long as any zone in the region is available.
               Only members in healthy zones will be sent new connections.
               Load balancers in the `network` family allow only one subnet to be
               specified.
        :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`.
               Not supported by private path load balancers.
        :param bool is_private_path: (optional) Indicates whether this is a private
               path load balancer.
        :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. If unspecified, `datapath.active` will
               be `false`.
               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 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,
            'dns': dns,
            'is_private_path': is_private_path,
            '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: Optional[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` or it
        is referenced by a resource.

        :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: Optional[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 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 listeners for a load balancer.

        This request lists 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: Optional[bool] = None,
        certificate_instance: Optional['CertificateInstanceIdentity'] = None,
        connection_limit: Optional[int] = None,
        default_pool: Optional['LoadBalancerPoolIdentity'] = None,
        https_redirect: Optional['LoadBalancerListenerHTTPSRedirectPrototype'] = None,
        idle_connection_timeout: Optional[int] = None,
        policies: Optional[List['LoadBalancerListenerPolicyPrototype']] = None,
        port: Optional[int] = None,
        port_max: Optional[int] = None,
        port_min: Optional[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 concurrent connection limit for
               the listener. If reached, incoming connections may be queued or rejected.
               This property will be present for load balancers in the `application`
               family.
        :param LoadBalancerPoolIdentity default_pool: (optional) The default pool
               for this listener. If `https_redirect` is specified, the
               default pool will not be used.
               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 if none
               of the listener's
               `policies` match.
               If specified, 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`.
               Only load balancers with route mode enabled, or network load balancers with
               `is_public` or `is_private_path` set to `true` 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`.
               Only load balancers with route mode enabled, or network load balancers with
               `is_public` or `is_private_path` set to `true` 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 policies for a load balancer listener.

        This request lists policies for a load balancer listener. A policy consists of
        rules to match against each incoming request, and an action to apply to the
        request if a rule matches.

        :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: Optional[str] = None,
        rules: Optional[List['LoadBalancerListenerPolicyRulePrototype']] = None,
        target: Optional['LoadBalancerListenerPolicyTargetPrototype'] = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        Create a policy for a load balancer listener.

        This request creates a new policy from a load balancer listener policy object. The
        prototype object is structured in the same way as a retrieved policy, and contains
        the information necessary to create the new policy. For this request to succeed,
        the listener must have a `protocol` of `http` or `https`.

        :param str load_balancer_id: The load balancer identifier.
        :param str listener_id: The listener identifier.
        :param str action: The policy action:
               - `forward`: Requests will be forwarded to the specified `target` pool
               - `https_redirect`: Requests will be redirected to the specified
               `target.listener`.
                  This listener must have a `protocol` of `http`, and the target listener
               must
                  have a `protocol` of `https`.
               - `redirect`: Requests will be redirected to the specified `target.url`
               - `reject`: Requests will be rejected with a `403` status code.
        :param int priority: Priority of the policy. The priority is unique across
               all policies for this load balancer listener. 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`, use `LoadBalancerPoolIdentity` to specify a pool in
               this
                 load balancer to forward to.
               - If `action` is `https_redirect`, use
                 `LoadBalancerListenerPolicyHTTPSRedirectPrototype` to specify a listener
               on this
                 load balancer to redirect to.
               - If `action` is `redirect`, use
               `LoadBalancerListenerPolicyRedirectURLPrototype`to
                 specify a URL to redirect 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 `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.

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

        :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 rules of a load balancer listener policy.

        This request lists 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: Optional[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 for 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: The value to be matched for the 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 to match for this rule. This
               property must be specified if the rule type is
               `header`, may be specified if the rule type is `body` or `query`, and must
               not be specified if the rule type is `hostname` or `path`.
               If the rule condition is not `matches_regex`, the value must be
               percent-encoded.
        :param dict headers: 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 pools of a load balancer.

        This request lists 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: Optional[List['LoadBalancerPoolMemberPrototype']] = None,
        name: Optional[str] = None,
        proxy_protocol: Optional[str] = None,
        session_persistence: Optional['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. The `least_connections`
               algorithm is only supported for load balancers that have `availability`
               with value `subnet` in the profile.
        :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
               For load balancers in the `network` family, this property must be
               `disabled`.
        :param LoadBalancerPoolSessionPersistencePrototype session_persistence:
               (optional) The session persistence of this pool. If specified, the load
               balancer must have
               `source_ip_session_persistence_supported` set to `true` in its profile. If
               unspecified, session persistence will be disabled, and traffic will be
               distributed
               across backend server members of the 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 members of a load balancer pool.

        This request lists 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: Optional[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) The weight of the server member.
               If specified, the pool algorithm must be `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: Optional[str] = None,
        start: Optional[str] = None,
        limit: Optional[int] = None,
        resource_group_id: Optional[str] = None,
        lifecycle_state: Optional[List[str]] = None,
        vpc_id: Optional[str] = None,
        vpc_crn: Optional[str] = None,
        vpc_name: Optional[str] = None,
        allow_dns_resolution_binding: Optional[bool] = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        List endpoint gateways.

        This request lists 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 List[str] lifecycle_state: (optional) Filters the collection to
               resources with a `lifecycle_state` property matching one of the specified
               comma-separated values.
        :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,
            'lifecycle_state': convert_list(lifecycle_state),
            '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: Optional[bool] = None,
        ips: Optional[List['EndpointGatewayReservedIP']] = None,
        name: Optional[str] = None,
        resource_group: Optional['ResourceGroupIdentity'] = None,
        security_groups: Optional[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. The target:
               - Must not already be the target of another endpoint gateway in the VPC
               - Must not have a service endpoint that duplicates or overlaps with any
               `service_endpoints`
                 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: Optional[str] = None,
        limit: Optional[int] = None,
        sort: Optional[str] = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        List reserved IPs bound to an endpoint gateway.

        This request lists 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, or not required by its target
        - 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: Optional[str] = None,
        limit: Optional[int] = None,
        resource_group_id: Optional[str] = None,
        name: Optional[str] = None,
        vpc_id: Optional[str] = None,
        vpc_crn: Optional[str] = None,
        vpc_name: Optional[str] = None,
        target_id: Optional[str] = None,
        target_resource_type: Optional[str] = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        List flow log collectors.

        This request lists flow log collectors in the region. A [flow log
        collector](https://cloud.ibm.com/docs/vpc?topic=vpc-flow-logs) summarizes data
        sent over the instance network interfaces and instance network attachments
        contained within its target. The collected flow logs are written to a cloud object
        storage bucket, where they can be
        [viewed](https://cloud.ibm.com/docs/vpc?topic=vpc-fl-analyze).

        :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: Optional[bool] = None,
        name: Optional[str] = None,
        resource_group: Optional['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 attachments, virtual network interfaces or instance
               network interfaces
               within the target that are themselves the target of a more specific flow
               log collector.
               The target must not be a virtual network interface that is attached to a
               bare metal server
               network attachment or to a file share mount target.
        :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

    #########################
    # Private path service gateways
    #########################

    def list_private_path_service_gateways(
        self,
        *,
        start: Optional[str] = None,
        limit: Optional[int] = None,
        resource_group_id: Optional[str] = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        List private path service gateways.

        This request lists private path service gateways in the region. Private path
        service gateways allow
        [service
        providers](https://cloud.ibm.com/docs/private-path?topic=private-path-private-path-service-architecture#private-path-service-components)
        to make their services available using
        [private path
        connectivity](https://cloud.ibm.com/docs/private-path?topic=private-path-private-path-service-architecture#private-path-service-components).
        Private path service gateways are used to facilitate and manage the private path
        connectivity between private path network load balancers and their associated
        endpoint gateways.

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

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

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

    def create_private_path_service_gateway(
        self,
        load_balancer: 'LoadBalancerIdentity',
        service_endpoints: List[str],
        *,
        default_access_policy: Optional[str] = None,
        name: Optional[str] = None,
        resource_group: Optional['ResourceGroupIdentity'] = None,
        zonal_affinity: Optional[bool] = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        Create a private path service gateway.

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

        :param LoadBalancerIdentity load_balancer: The load balancer for this
               private path service gateway. The load balancer must
               have `is_private_path` set to `true`.
               The private path service gateway will reside in the same VPC as the
               specified load
               balancer.
        :param List[str] service_endpoints: The fully qualified domain names for
               this private path service gateway. Any uppercase letters will be converted
               to lowercase.
        :param str default_access_policy: (optional) The policy to use for bindings
               from accounts without an explicit account policy.
        :param str name: (optional) The name for this private path service gateway.
               The name must not be used by another private path service 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 bool zonal_affinity: (optional) Indicates whether this private path
               service gateway has zonal affinity.
               - `true`:  Traffic to the service from a zone the service resides in will
               remain in
                          that zone.
               - `false`: Traffic to the service from a zone will be load balanced across
               all zones
                          in the region the service resides in.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `PrivatePathServiceGateway` object
        """

        if load_balancer is None:
            raise ValueError('load_balancer must be provided')
        if service_endpoints is None:
            raise ValueError('service_endpoints must be provided')
        load_balancer = convert_model(load_balancer)
        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_private_path_service_gateway',
        )
        headers.update(sdk_headers)

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

        data = {
            'load_balancer': load_balancer,
            'service_endpoints': service_endpoints,
            'default_access_policy': default_access_policy,
            'name': name,
            'resource_group': resource_group,
            'zonal_affinity': zonal_affinity,
        }
        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 = '/private_path_service_gateways'
        request = self.prepare_request(
            method='POST',
            url=url,
            headers=headers,
            params=params,
            data=data,
        )

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

    def delete_private_path_service_gateway(
        self,
        id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Delete a private path service gateway.

        This request deletes a private path service gateway.  For this request to succeed,
        the value of `endpoint_gateway_count` must be `0`. This operation cannot be
        reversed.

        :param str id: The private path service 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_private_path_service_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 = '/private_path_service_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_private_path_service_gateway(
        self,
        id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Retrieve a private path service gateway.

        This request retrieves the private path service gateway specified by the
        identifier in the URL.

        :param str id: The private path service 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 `PrivatePathServiceGateway` 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_private_path_service_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 = '/private_path_service_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_private_path_service_gateway(
        self,
        id: str,
        private_path_service_gateway_patch: 'PrivatePathServiceGatewayPatch',
        **kwargs,
    ) -> DetailedResponse:
        """
        Update a private path service gateway.

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

        :param str id: The private path service gateway identifier.
        :param PrivatePathServiceGatewayPatch private_path_service_gateway_patch:
               The private path service 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 `PrivatePathServiceGateway` object
        """

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

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

        data = json.dumps(private_path_service_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 = '/private_path_service_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_private_path_service_gateway_account_policies(
        self,
        private_path_service_gateway_id: str,
        *,
        start: Optional[str] = None,
        limit: Optional[int] = None,
        account_id: Optional[str] = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        List account policies for a private path service gateway.

        This request lists account policies for a private path service gateway. Each
        policy defines how requests to use the private path service gateway from that
        account will be handled.
        The account policies will be sorted by their `created_at` property values, with
        newest account policies first. Account policies with identical `created_at`
        property values will in turn be sorted by ascending `id` property values.

        :param str private_path_service_gateway_id: The private path service
               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 account_id: (optional) Filters the collection to resources with
               an `account.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 `PrivatePathServiceGatewayAccountPolicyCollection` object
        """

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

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

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

        path_param_keys = ['private_path_service_gateway_id']
        path_param_values = self.encode_path_vars(private_path_service_gateway_id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/private_path_service_gateways/{private_path_service_gateway_id}/account_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_private_path_service_gateway_account_policy(
        self,
        private_path_service_gateway_id: str,
        access_policy: str,
        account: 'AccountIdentity',
        **kwargs,
    ) -> DetailedResponse:
        """
        Create an account policy for a private path service gateway.

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

        :param str private_path_service_gateway_id: The private path service
               gateway identifier.
        :param str access_policy: The access policy for the account. Updating the
               access policy only affects pending and future endpoint gateway bindings.
               - permit: access will be permitted
               - deny: access will be denied
               - review: access will be manually reviewed
               - Updating to `review` sets the status of future endpoint gateway bindings
               from
                  this account to `pending`.
               - Updating to `permit` updates both the status of any `pending` and future
               endpoint
                 gateway bindings from this account to `permitted`.
               - Updating to `deny` updates both the status of any `pending` and future
               endpoint
                 gateway bindings from this account to `denied`.
        :param AccountIdentity account: The account for this access policy. The
               account must be unique across all account
               policies for this private path service gateway.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `PrivatePathServiceGatewayAccountPolicy` object
        """

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

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

        data = {
            'access_policy': access_policy,
            'account': account,
        }
        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 = ['private_path_service_gateway_id']
        path_param_values = self.encode_path_vars(private_path_service_gateway_id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/private_path_service_gateways/{private_path_service_gateway_id}/account_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_private_path_service_gateway_account_policy(
        self,
        private_path_service_gateway_id: str,
        id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Delete an account policy for a private path service gateway.

        This request deletes an account policy. This operation cannot be reversed and it
        does not affect the `status` of any existing endpoint gateway bindings.

        :param str private_path_service_gateway_id: The private path service
               gateway identifier.
        :param str id: The account 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 private_path_service_gateway_id:
            raise ValueError('private_path_service_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_private_path_service_gateway_account_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 = ['private_path_service_gateway_id', 'id']
        path_param_values = self.encode_path_vars(private_path_service_gateway_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/private_path_service_gateways/{private_path_service_gateway_id}/account_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_private_path_service_gateway_account_policy(
        self,
        private_path_service_gateway_id: str,
        id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Retrieve an account policy for a private path service gateway.

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

        :param str private_path_service_gateway_id: The private path service
               gateway identifier.
        :param str id: The account 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 `PrivatePathServiceGatewayAccountPolicy` object
        """

        if not private_path_service_gateway_id:
            raise ValueError('private_path_service_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_private_path_service_gateway_account_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 = ['private_path_service_gateway_id', 'id']
        path_param_values = self.encode_path_vars(private_path_service_gateway_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/private_path_service_gateways/{private_path_service_gateway_id}/account_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_private_path_service_gateway_account_policy(
        self,
        private_path_service_gateway_id: str,
        id: str,
        private_path_service_gateway_account_policy_patch: 'PrivatePathServiceGatewayAccountPolicyPatch',
        **kwargs,
    ) -> DetailedResponse:
        """
        Update an account policy for a private path service gateway.

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

        :param str private_path_service_gateway_id: The private path service
               gateway identifier.
        :param str id: The account policy identifier.
        :param PrivatePathServiceGatewayAccountPolicyPatch
               private_path_service_gateway_account_policy_patch: The account 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 `PrivatePathServiceGatewayAccountPolicy` object
        """

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

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

        data = json.dumps(private_path_service_gateway_account_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 = ['private_path_service_gateway_id', 'id']
        path_param_values = self.encode_path_vars(private_path_service_gateway_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/private_path_service_gateways/{private_path_service_gateway_id}/account_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_private_path_service_gateway_endpoint_gateway_bindings(
        self,
        private_path_service_gateway_id: str,
        *,
        start: Optional[str] = None,
        limit: Optional[int] = None,
        status: Optional[str] = None,
        account_id: Optional[str] = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        List endpoint gateway bindings for a private path service gateway.

        This request lists endpoint gateway bindings for a private path service gateway.
        Each endpoint gateway binding is implicitly created when an endpoint gateway is
        created targeting the private path service gateway. The associated account policy
        is applied to all new endpoint gateway bindings. If an associated account policy
        doesn't exist, the private path service gateway's `default_access_policy` is used.
        The endpoint gateway bindings will be sorted by their `created_at` property
        values, with newest endpoint gateway bindings first. Endpoint gateway bindings
        with identical
        `created_at` property values will in turn be sorted by ascending `name` property
        values.

        :param str private_path_service_gateway_id: The private path service
               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 status: (optional) Filters the collection to endpoint gateway
               bindings with a `status` property matching the specified value.
        :param str account_id: (optional) Filters the collection to resources with
               an `account.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 `PrivatePathServiceGatewayEndpointGatewayBindingCollection` object
        """

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

        params = {
            'version': self.version,
            'generation': self.generation,
            'start': start,
            'limit': limit,
            'status': status,
            'account.id': account_id,
        }

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

        path_param_keys = ['private_path_service_gateway_id']
        path_param_values = self.encode_path_vars(private_path_service_gateway_id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/private_path_service_gateways/{private_path_service_gateway_id}/endpoint_gateway_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 get_private_path_service_gateway_endpoint_gateway_binding(
        self,
        private_path_service_gateway_id: str,
        id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Retrieve an endpoint gateway binding for a private path service gateway.

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

        :param str private_path_service_gateway_id: The private path service
               gateway identifier.
        :param str id: The endpoint gateway 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 `PrivatePathServiceGatewayEndpointGatewayBinding` object
        """

        if not private_path_service_gateway_id:
            raise ValueError('private_path_service_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_private_path_service_gateway_endpoint_gateway_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 = ['private_path_service_gateway_id', 'id']
        path_param_values = self.encode_path_vars(private_path_service_gateway_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/private_path_service_gateways/{private_path_service_gateway_id}/endpoint_gateway_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 deny_private_path_service_gateway_endpoint_gateway_binding(
        self,
        private_path_service_gateway_id: str,
        id: str,
        *,
        set_account_policy: Optional[bool] = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        Deny an endpoint gateway binding for a private path service gateway.

        This request denies a `pending` endpoint gateway request, and optionally sets the
        policy to deny future requests from the same account.

        :param str private_path_service_gateway_id: The private path service
               gateway identifier.
        :param str id: The endpoint gateway binding identifier.
        :param bool set_account_policy: (optional) Indicates whether this will
               become the access policy for any `pending` and future endpoint gateway
               bindings from the same account.
               If set to `true`:
               - If the account has an existing access policy, that policy will be updated
               to `deny`.
                 Otherwise, a new `deny` access policy will be created for the account.
               - All `pending` endpoint gateway bindings for the account will be denied.
               If set to `false`:
               - No access policies will be created or updated
               - All `pending` endpoint gateway bindings for the account will remain
               `pending`.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse
        """

        if not private_path_service_gateway_id:
            raise ValueError('private_path_service_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='deny_private_path_service_gateway_endpoint_gateway_binding',
        )
        headers.update(sdk_headers)

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

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

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

        path_param_keys = ['private_path_service_gateway_id', 'id']
        path_param_values = self.encode_path_vars(private_path_service_gateway_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/private_path_service_gateways/{private_path_service_gateway_id}/endpoint_gateway_bindings/{id}/deny'.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 permit_private_path_service_gateway_endpoint_gateway_binding(
        self,
        private_path_service_gateway_id: str,
        id: str,
        *,
        set_account_policy: Optional[bool] = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        Permit an endpoint gateway binding for a private path service gateway.

        This request permits a `pending` endpoint gateway request, and optionally sets the
        policy to permit future requests from the same account.

        :param str private_path_service_gateway_id: The private path service
               gateway identifier.
        :param str id: The endpoint gateway binding identifier.
        :param bool set_account_policy: (optional) Indicates whether this will
               become the access policy for any `pending` and future endpoint gateway
               bindings from the same account.
               If set to `true`:
               - If the account has an existing access policy, that policy will be updated
               to
                 `permit`. Otherwise, a new `permit` access policy will be created for the
               account.
               - All `pending` endpoint gateway bindings for the account will be
               permitted.
               If set to `false`:
               - No access policies will be created or updated
               - All `pending` endpoint gateway bindings for the account will remain
               `pending`.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse
        """

        if not private_path_service_gateway_id:
            raise ValueError('private_path_service_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='permit_private_path_service_gateway_endpoint_gateway_binding',
        )
        headers.update(sdk_headers)

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

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

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

        path_param_keys = ['private_path_service_gateway_id', 'id']
        path_param_values = self.encode_path_vars(private_path_service_gateway_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/private_path_service_gateways/{private_path_service_gateway_id}/endpoint_gateway_bindings/{id}/permit'.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 publish_private_path_service_gateway(
        self,
        private_path_service_gateway_id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Publish a private path service gateway.

        This request publishes a private path service gateway, allowing any account to
        request access to it.

        :param str private_path_service_gateway_id: The private path service
               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 private_path_service_gateway_id:
            raise ValueError('private_path_service_gateway_id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='publish_private_path_service_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 = ['private_path_service_gateway_id']
        path_param_values = self.encode_path_vars(private_path_service_gateway_id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/private_path_service_gateways/{private_path_service_gateway_id}/publish'.format(**path_param_dict)
        request = self.prepare_request(
            method='POST',
            url=url,
            headers=headers,
            params=params,
        )

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

    def revoke_account_for_private_path_service_gateway(
        self,
        private_path_service_gateway_id: str,
        account: 'AccountIdentity',
        **kwargs,
    ) -> DetailedResponse:
        """
        Revoke access to a private path service gateway for an account.

        This request revokes a consumer account. This operation cannot be reversed. The
        `status` of all endpoint gateway bindings associated with the specified private
        path service gateway become `denied`. If the specified account has an existing
        access policy, that policy will be updated to `denied`. Otherwise, a new `deny`
        access policy will be created for the account.

        :param str private_path_service_gateway_id: The private path service
               gateway identifier.
        :param AccountIdentity account: The account that will be revoked access to
               the private path service gateway.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse
        """

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

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

        data = {
            'account': account,
        }
        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 = ['private_path_service_gateway_id']
        path_param_values = self.encode_path_vars(private_path_service_gateway_id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/private_path_service_gateways/{private_path_service_gateway_id}/revoke_account'.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 unpublish_private_path_service_gateway(
        self,
        private_path_service_gateway_id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Unpublish a private path service gateway.

        This request unpublishes a private path service gateway. For this request to
        succeed, any existing access from other accounts must first be revoked. Once
        unpublished, access will again be restricted to the account that created this
        private path service gateway.

        :param str private_path_service_gateway_id: The private path service
               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 private_path_service_gateway_id:
            raise ValueError('private_path_service_gateway_id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='unpublish_private_path_service_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 = ['private_path_service_gateway_id']
        path_param_values = self.encode_path_vars(private_path_service_gateway_id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/private_path_service_gateways/{private_path_service_gateway_id}/unpublish'.format(**path_param_dict)
        request = self.prepare_request(
            method='POST',
            url=url,
            headers=headers,
            params=params,
        )

        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 UserDataFormat(str, Enum):
        """
        Filters the collection to images with a `user_data_format` property matching one
        of the specified comma-separated values.
        """

        CLOUD_INIT = 'cloud_init'
        ESXI_KICKSTART = 'esxi_kickstart'
        IPXE = 'ipxe'


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 ListSnapshotConsistencyGroupsEnums:
    """
    Enums for list_snapshot_consistency_groups 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 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 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 ListNetworkInterfaceFloatingIpsEnums:
    """
    Enums for list_network_interface_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
        `-name` sorts the collection by the `name` property in descending order, and the
        value `name` sorts it by the `name` property in ascending order.
        """

        ADDRESS = 'address'
        NAME = 'name'


class ListVirtualNetworkInterfaceIpsEnums:
    """
    Enums for list_virtual_network_interface_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
        `-name` sorts the collection by the `name` property in descending order, and the
        value `name` sorts it by the `name` property in ascending order.
        """

        ADDRESS = 'address'
        NAME = 'name'


class ListClusterNetworksEnums:
    """
    Enums for list_cluster_networks 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 ListClusterNetworkInterfacesEnums:
    """
    Enums for list_cluster_network_interfaces 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 ListClusterNetworkSubnetsEnums:
    """
    Enums for list_cluster_network_subnets 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 ListClusterNetworkSubnetReservedIpsEnums:
    """
    Enums for list_cluster_network_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 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 ListEndpointGatewaysEnums:
    """
    Enums for list_endpoint_gateways parameters.
    """

    class LifecycleState(str, Enum):
        """
        Filters the collection to resources with a `lifecycle_state` property matching one
        of the specified comma-separated values.
        """

        DELETING = 'deleting'
        FAILED = 'failed'
        PENDING = 'pending'
        STABLE = 'stable'
        SUSPENDED = 'suspended'
        UPDATING = 'updating'
        WAITING = 'waiting'


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'


class ListPrivatePathServiceGatewayEndpointGatewayBindingsEnums:
    """
    Enums for list_private_path_service_gateway_endpoint_gateway_bindings parameters.
    """

    class Status(str, Enum):
        """
        Filters the collection to endpoint gateway bindings with a `status` property
        matching the specified value.
        """

        ABANDONED = 'abandoned'
        DENIED = 'denied'
        EXPIRED = 'expired'
        PENDING = 'pending'
        PERMITTED = 'permitted'


##############################################################################
# Models
##############################################################################


class AccountIdentity:
    """
    Identifies an account by a unique property.

    """

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

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


class AccountReference:
    """
    AccountReference.

    :param str id: The unique identifier for this account.
    :param 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 := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in AccountReference JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = 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.

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

    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 := _dict.get('cidr')) is not None:
            args['cidr'] = cidr
        else:
            raise ValueError('Required property \'cidr\' not present in AddressPrefix JSON')
        if (created_at := _dict.get('created_at')) is not None:
            args['created_at'] = string_to_datetime(created_at)
        else:
            raise ValueError('Required property \'created_at\' not present in AddressPrefix JSON')
        if (has_subnets := _dict.get('has_subnets')) is not None:
            args['has_subnets'] = has_subnets
        else:
            raise ValueError('Required property \'has_subnets\' not present in AddressPrefix JSON')
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in AddressPrefix JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in AddressPrefix JSON')
        if (is_default := _dict.get('is_default')) is not None:
            args['is_default'] = is_default
        else:
            raise ValueError('Required property \'is_default\' not present in AddressPrefix JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in AddressPrefix JSON')
        if (zone := _dict.get('zone')) is not None:
            args['zone'] = ZoneReference.from_dict(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.

    :param List[AddressPrefix] address_prefixes: A page of address prefixes for the
          VPC.
    :param PageLink 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 PageLink next: (optional) A link to the next page of resources. This
          property is present for all pages
          except the last page.
    :param int total_count: The total number of resources across all pages.
    """

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

        :param List[AddressPrefix] address_prefixes: A page of address prefixes for
               the VPC.
        :param PageLink 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 PageLink 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 := _dict.get('address_prefixes')) is not None:
            args['address_prefixes'] = [AddressPrefix.from_dict(v) for v in address_prefixes]
        else:
            raise ValueError('Required property \'address_prefixes\' not present in AddressPrefixCollection JSON')
        if (first := _dict.get('first')) is not None:
            args['first'] = PageLink.from_dict(first)
        else:
            raise ValueError('Required property \'first\' not present in AddressPrefixCollection JSON')
        if (limit := _dict.get('limit')) is not None:
            args['limit'] = limit
        else:
            raise ValueError('Required property \'limit\' not present in AddressPrefixCollection JSON')
        if (next := _dict.get('next')) is not None:
            args['next'] = PageLink.from_dict(next)
        if (total_count := _dict.get('total_count')) is not None:
            args['total_count'] = 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 AddressPrefixPatch:
    """
    AddressPrefixPatch.

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

    def __init__(
        self,
        *,
        is_default: Optional[bool] = None,
        name: Optional[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 := _dict.get('is_default')) is not None:
            args['is_default'] = is_default
        if (name := _dict.get('name')) is not None:
            args['name'] = 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.

    :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).
    :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 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.
    :param str lifecycle_state: The lifecycle state of the backup policy.
    :param str match_resource_type: The resource type 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 may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :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.
    """

    def __init__(
        self,
        created_at: datetime,
        crn: str,
        health_reasons: List['BackupPolicyHealthReason'],
        health_state: str,
        href: str,
        id: str,
        lifecycle_state: str,
        match_resource_type: str,
        match_user_tags: List[str],
        name: str,
        plans: List['BackupPolicyPlanReference'],
        resource_group: 'ResourceGroupReference',
        resource_type: str,
        scope: 'BackupPolicyScope',
        *,
        last_job_completed_at: Optional[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).
        :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 str match_resource_type: The resource type 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 may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :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.
        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['BackupPolicyMatchResourceTypeInstance', 'BackupPolicyMatchResourceTypeVolume'])
        )
        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 backup policy.
        """

        DELETING = 'deleting'
        FAILED = 'failed'
        PENDING = 'pending'
        STABLE = 'stable'
        SUSPENDED = 'suspended'
        UPDATING = 'updating'
        WAITING = 'waiting'


    class MatchResourceTypeEnum(str, Enum):
        """
        The resource type 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 may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        INSTANCE = 'instance'
        VOLUME = 'volume'


    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        BACKUP_POLICY = 'backup_policy'



class BackupPolicyCollection:
    """
    BackupPolicyCollection.

    :param List[BackupPolicy] backup_policies: A page of backup policies.
    :param PageLink 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 PageLink next: (optional) A link to the next page of resources. This
          property is present for all pages
          except the last page.
    :param int total_count: The total number of resources across all pages.
    """

    def __init__(
        self,
        backup_policies: List['BackupPolicy'],
        first: 'PageLink',
        limit: int,
        total_count: int,
        *,
        next: Optional['PageLink'] = None,
    ) -> None:
        """
        Initialize a BackupPolicyCollection object.

        :param List[BackupPolicy] backup_policies: A page of backup policies.
        :param PageLink 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 PageLink 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 := _dict.get('backup_policies')) is not None:
            args['backup_policies'] = backup_policies
        else:
            raise ValueError('Required property \'backup_policies\' not present in BackupPolicyCollection JSON')
        if (first := _dict.get('first')) is not None:
            args['first'] = PageLink.from_dict(first)
        else:
            raise ValueError('Required property \'first\' not present in BackupPolicyCollection JSON')
        if (limit := _dict.get('limit')) is not None:
            args['limit'] = limit
        else:
            raise ValueError('Required property \'limit\' not present in BackupPolicyCollection JSON')
        if (next := _dict.get('next')) is not None:
            args['next'] = PageLink.from_dict(next)
        if (total_count := _dict.get('total_count')) is not None:
            args['total_count'] = 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 BackupPolicyHealthReason:
    """
    BackupPolicyHealthReason.

    :param str code: A reason code 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.
    """

    def __init__(
        self,
        code: str,
        message: str,
        *,
        more_info: Optional[str] = None,
    ) -> None:
        """
        Initialize a BackupPolicyHealthReason object.

        :param str code: A reason code 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 := _dict.get('code')) is not None:
            args['code'] = code
        else:
            raise ValueError('Required property \'code\' not present in BackupPolicyHealthReason JSON')
        if (message := _dict.get('message')) is not None:
            args['message'] = message
        else:
            raise ValueError('Required property \'message\' not present in BackupPolicyHealthReason JSON')
        if (more_info := _dict.get('more_info')) is not None:
            args['more_info'] = 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 reason code for this health state.
        """

        MISSING_SERVICE_AUTHORIZATION_POLICIES = 'missing_service_authorization_policies'



class BackupPolicyJob:
    """
    BackupPolicyJob.

    :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 completed_at: (optional) The date and time that the backup
          policy job was completed.
          If absent, the backup policy job has not yet completed.
    :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 may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :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 may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :param List[BackupPolicyJobStatusReason] status_reasons: The reasons for the
          current status (if any).
    :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)).
    """

    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: Optional[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 may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :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 may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :param List[BackupPolicyJobStatusReason] status_reasons: The reasons for
               the current status (if any).
        :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 := _dict.get('auto_delete')) is not None:
            args['auto_delete'] = auto_delete
        else:
            raise ValueError('Required property \'auto_delete\' not present in BackupPolicyJob JSON')
        if (auto_delete_after := _dict.get('auto_delete_after')) is not None:
            args['auto_delete_after'] = auto_delete_after
        else:
            raise ValueError('Required property \'auto_delete_after\' not present in BackupPolicyJob JSON')
        if (backup_policy_plan := _dict.get('backup_policy_plan')) is not None:
            args['backup_policy_plan'] = BackupPolicyPlanReference.from_dict(backup_policy_plan)
        else:
            raise ValueError('Required property \'backup_policy_plan\' not present in BackupPolicyJob JSON')
        if (completed_at := _dict.get('completed_at')) is not None:
            args['completed_at'] = string_to_datetime(completed_at)
        if (created_at := _dict.get('created_at')) is not None:
            args['created_at'] = string_to_datetime(created_at)
        else:
            raise ValueError('Required property \'created_at\' not present in BackupPolicyJob JSON')
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in BackupPolicyJob JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in BackupPolicyJob JSON')
        if (job_type := _dict.get('job_type')) is not None:
            args['job_type'] = job_type
        else:
            raise ValueError('Required property \'job_type\' not present in BackupPolicyJob JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = resource_type
        else:
            raise ValueError('Required property \'resource_type\' not present in BackupPolicyJob JSON')
        if (source := _dict.get('source')) is not None:
            args['source'] = source
        else:
            raise ValueError('Required property \'source\' not present in BackupPolicyJob JSON')
        if (status := _dict.get('status')) is not None:
            args['status'] = status
        else:
            raise ValueError('Required property \'status\' not present in BackupPolicyJob JSON')
        if (status_reasons := _dict.get('status_reasons')) is not None:
            args['status_reasons'] = [BackupPolicyJobStatusReason.from_dict(v) for v in status_reasons]
        else:
            raise ValueError('Required property \'status_reasons\' not present in BackupPolicyJob JSON')
        if (target_snapshots := _dict.get('target_snapshots')) is not None:
            args['target_snapshots'] = [SnapshotReference.from_dict(v) for v in 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 may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        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 may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        FAILED = 'failed'
        RUNNING = 'running'
        SUCCEEDED = 'succeeded'



class BackupPolicyJobCollection:
    """
    BackupPolicyJobCollection.

    :param PageLink first: A link to the first page of resources.
    :param List[BackupPolicyJob] jobs: A page of jobs for the backup policy.
    :param int limit: The maximum number of resources that can be returned by the
          request.
    :param PageLink next: (optional) A link to the next page of resources. This
          property is present for all pages
          except the last page.
    :param int total_count: The total number of resources across all pages.
    """

    def __init__(
        self,
        first: 'PageLink',
        jobs: List['BackupPolicyJob'],
        limit: int,
        total_count: int,
        *,
        next: Optional['PageLink'] = None,
    ) -> None:
        """
        Initialize a BackupPolicyJobCollection object.

        :param PageLink first: A link to the first page of resources.
        :param List[BackupPolicyJob] jobs: A page of jobs for the backup policy.
        :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 PageLink 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 := _dict.get('first')) is not None:
            args['first'] = PageLink.from_dict(first)
        else:
            raise ValueError('Required property \'first\' not present in BackupPolicyJobCollection JSON')
        if (jobs := _dict.get('jobs')) is not None:
            args['jobs'] = [BackupPolicyJob.from_dict(v) for v in jobs]
        else:
            raise ValueError('Required property \'jobs\' not present in BackupPolicyJobCollection JSON')
        if (limit := _dict.get('limit')) is not None:
            args['limit'] = limit
        else:
            raise ValueError('Required property \'limit\' not present in BackupPolicyJobCollection JSON')
        if (next := _dict.get('next')) is not None:
            args['next'] = PageLink.from_dict(next)
        if (total_count := _dict.get('total_count')) is not None:
            args['total_count'] = 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 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', 'BackupPolicyJobSourceInstanceReference'])
        )
        raise Exception(msg)


class BackupPolicyJobStatusReason:
    """
    BackupPolicyJobStatusReason.

    :param str code: A reason code for the status:
          - `internal_error`: Internal error (contact IBM support)
          - `snapshot_encryption_key_invalid`: The provided encryption key is unavailable
          - `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)
          - `source_volume_too_large`: The source volume exceeds the [maximum supported
          size](https://cloud.ibm.com/docs/vpc?topic=vpc-snapshots-vpc-about&interface=api#snapshots-vpc-limitations)
          - `source_volume_unavailable`: The source volume is not attached to a running
          instance
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :param str message: An explanation of the status reason.
    :param str more_info: (optional) Link to documentation about this status reason.
    """

    def __init__(
        self,
        code: str,
        message: str,
        *,
        more_info: Optional[str] = None,
    ) -> None:
        """
        Initialize a BackupPolicyJobStatusReason object.

        :param str code: A reason code for the status:
               - `internal_error`: Internal error (contact IBM support)
               - `snapshot_encryption_key_invalid`: The provided encryption key is
               unavailable
               - `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)
               - `source_volume_too_large`: The source volume exceeds the [maximum
               supported
               size](https://cloud.ibm.com/docs/vpc?topic=vpc-snapshots-vpc-about&interface=api#snapshots-vpc-limitations)
               - `source_volume_unavailable`: The source volume is not attached to a
               running instance
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :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 := _dict.get('code')) is not None:
            args['code'] = code
        else:
            raise ValueError('Required property \'code\' not present in BackupPolicyJobStatusReason JSON')
        if (message := _dict.get('message')) is not None:
            args['message'] = message
        else:
            raise ValueError('Required property \'message\' not present in BackupPolicyJobStatusReason JSON')
        if (more_info := _dict.get('more_info')) is not None:
            args['more_info'] = 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 reason code for the status:
        - `internal_error`: Internal error (contact IBM support)
        - `snapshot_encryption_key_invalid`: The provided encryption key is unavailable
        - `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)
        - `source_volume_too_large`: The source volume exceeds the [maximum supported
        size](https://cloud.ibm.com/docs/vpc?topic=vpc-snapshots-vpc-about&interface=api#snapshots-vpc-limitations)
        - `source_volume_unavailable`: The source volume is not attached to a running
        instance
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        INTERNAL_ERROR = 'internal_error'
        SNAPSHOT_ENCRYPTION_KEY_INVALID = 'snapshot_encryption_key_invalid'
        SNAPSHOT_PENDING = 'snapshot_pending'
        SNAPSHOT_VOLUME_LIMIT = 'snapshot_volume_limit'
        SOURCE_VOLUME_BUSY = 'source_volume_busy'
        SOURCE_VOLUME_TOO_LARGE = 'source_volume_too_large'
        SOURCE_VOLUME_UNAVAILABLE = 'source_volume_unavailable'



class BackupPolicyPatch:
    """
    BackupPolicyPatch.

    :param List[str] included_content: (optional) The included content for backups
          created using this policy:
          - `boot_volume`: Include the instance's boot volume.
          - `data_volumes`: Include the instance's data volumes.
    :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.
    """

    def __init__(
        self,
        *,
        included_content: Optional[List[str]] = None,
        match_user_tags: Optional[List[str]] = None,
        name: Optional[str] = None,
    ) -> None:
        """
        Initialize a BackupPolicyPatch object.

        :param List[str] included_content: (optional) The included content for
               backups created using this policy:
               - `boot_volume`: Include the instance's boot volume.
               - `data_volumes`: Include the instance's data volumes.
        :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.included_content = included_content
        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 (included_content := _dict.get('included_content')) is not None:
            args['included_content'] = included_content
        if (match_user_tags := _dict.get('match_user_tags')) is not None:
            args['match_user_tags'] = match_user_tags
        if (name := _dict.get('name')) is not None:
            args['name'] = 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, 'included_content') and self.included_content is not None:
            _dict['included_content'] = self.included_content
        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 IncludedContentEnum(str, Enum):
        """
        An item to include.
        """

        BOOT_VOLUME = 'boot_volume'
        DATA_VOLUMES = 'data_volumes'



class BackupPolicyPlan:
    """
    BackupPolicyPlan.

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

    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 := _dict.get('active')) is not None:
            args['active'] = active
        else:
            raise ValueError('Required property \'active\' not present in BackupPolicyPlan JSON')
        if (attach_user_tags := _dict.get('attach_user_tags')) is not None:
            args['attach_user_tags'] = attach_user_tags
        else:
            raise ValueError('Required property \'attach_user_tags\' not present in BackupPolicyPlan JSON')
        if (clone_policy := _dict.get('clone_policy')) is not None:
            args['clone_policy'] = BackupPolicyPlanClonePolicy.from_dict(clone_policy)
        else:
            raise ValueError('Required property \'clone_policy\' not present in BackupPolicyPlan JSON')
        if (copy_user_tags := _dict.get('copy_user_tags')) is not None:
            args['copy_user_tags'] = copy_user_tags
        else:
            raise ValueError('Required property \'copy_user_tags\' not present in BackupPolicyPlan JSON')
        if (created_at := _dict.get('created_at')) is not None:
            args['created_at'] = string_to_datetime(created_at)
        else:
            raise ValueError('Required property \'created_at\' not present in BackupPolicyPlan JSON')
        if (cron_spec := _dict.get('cron_spec')) is not None:
            args['cron_spec'] = cron_spec
        else:
            raise ValueError('Required property \'cron_spec\' not present in BackupPolicyPlan JSON')
        if (deletion_trigger := _dict.get('deletion_trigger')) is not None:
            args['deletion_trigger'] = BackupPolicyPlanDeletionTrigger.from_dict(deletion_trigger)
        else:
            raise ValueError('Required property \'deletion_trigger\' not present in BackupPolicyPlan JSON')
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in BackupPolicyPlan JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in BackupPolicyPlan JSON')
        if (lifecycle_state := _dict.get('lifecycle_state')) is not None:
            args['lifecycle_state'] = lifecycle_state
        else:
            raise ValueError('Required property \'lifecycle_state\' not present in BackupPolicyPlan JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in BackupPolicyPlan JSON')
        if (remote_region_policies := _dict.get('remote_region_policies')) is not None:
            args['remote_region_policies'] = [BackupPolicyPlanRemoteRegionPolicy.from_dict(v) for v in remote_region_policies]
        else:
            raise ValueError('Required property \'remote_region_policies\' not present in BackupPolicyPlan JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = 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.

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

    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 := _dict.get('max_snapshots')) is not None:
            args['max_snapshots'] = max_snapshots
        else:
            raise ValueError('Required property \'max_snapshots\' not present in BackupPolicyPlanClonePolicy JSON')
        if (zones := _dict.get('zones')) is not None:
            args['zones'] = [ZoneReference.from_dict(v) for v in 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.

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

    def __init__(
        self,
        *,
        max_snapshots: Optional[int] = None,
        zones: Optional[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 := _dict.get('max_snapshots')) is not None:
            args['max_snapshots'] = max_snapshots
        if (zones := _dict.get('zones')) is not None:
            args['zones'] = 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.

    :param int max_snapshots: (optional) The maximum number of recent snapshots (per
          source) that will keep clones.
    :param List[ZoneIdentity] zones: The zone this backup policy plan will create
          snapshot clones in.
    """

    def __init__(
        self,
        zones: List['ZoneIdentity'],
        *,
        max_snapshots: Optional[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 := _dict.get('max_snapshots')) is not None:
            args['max_snapshots'] = max_snapshots
        if (zones := _dict.get('zones')) is not None:
            args['zones'] = 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.

    :param PageLink 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 PageLink next: (optional) A link to the next page of resources. This
          property is present for all pages
          except the last page.
    :param List[BackupPolicyPlan] plans: A page of plans for the backup policy.
    :param int total_count: The total number of resources across all pages.
    """

    def __init__(
        self,
        first: 'PageLink',
        limit: int,
        plans: List['BackupPolicyPlan'],
        total_count: int,
        *,
        next: Optional['PageLink'] = None,
    ) -> None:
        """
        Initialize a BackupPolicyPlanCollection object.

        :param PageLink 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[BackupPolicyPlan] plans: A page of plans for the backup policy.
        :param int total_count: The total number of resources across all pages.
        :param PageLink 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.plans = plans
        self.total_count = total_count

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'BackupPolicyPlanCollection':
        """Initialize a BackupPolicyPlanCollection object from a json dictionary."""
        args = {}
        if (first := _dict.get('first')) is not None:
            args['first'] = PageLink.from_dict(first)
        else:
            raise ValueError('Required property \'first\' not present in BackupPolicyPlanCollection JSON')
        if (limit := _dict.get('limit')) is not None:
            args['limit'] = limit
        else:
            raise ValueError('Required property \'limit\' not present in BackupPolicyPlanCollection JSON')
        if (next := _dict.get('next')) is not None:
            args['next'] = PageLink.from_dict(next)
        if (plans := _dict.get('plans')) is not None:
            args['plans'] = [BackupPolicyPlan.from_dict(v) for v in plans]
        else:
            raise ValueError('Required property \'plans\' not present in BackupPolicyPlanCollection JSON')
        if (total_count := _dict.get('total_count')) is not None:
            args['total_count'] = total_count
        else:
            raise ValueError('Required property \'total_count\' 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, '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, '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, '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 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.

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

    def __init__(
        self,
        delete_after: int,
        *,
        delete_over_count: Optional[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 := _dict.get('delete_after')) is not None:
            args['delete_after'] = delete_after
        else:
            raise ValueError('Required property \'delete_after\' not present in BackupPolicyPlanDeletionTrigger JSON')
        if (delete_over_count := _dict.get('delete_over_count')) is not None:
            args['delete_over_count'] = 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.

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

    def __init__(
        self,
        *,
        delete_after: Optional[int] = None,
        delete_over_count: Optional[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 := _dict.get('delete_after')) is not None:
            args['delete_after'] = delete_after
        if (delete_over_count := _dict.get('delete_over_count')) is not None:
            args['delete_over_count'] = 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.

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

    def __init__(
        self,
        *,
        delete_after: Optional[int] = None,
        delete_over_count: Optional[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 := _dict.get('delete_after')) is not None:
            args['delete_after'] = delete_after
        if (delete_over_count := _dict.get('delete_over_count')) is not None:
            args['delete_over_count'] = 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.

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

    def __init__(
        self,
        *,
        active: Optional[bool] = None,
        attach_user_tags: Optional[List[str]] = None,
        clone_policy: Optional['BackupPolicyPlanClonePolicyPatch'] = None,
        copy_user_tags: Optional[bool] = None,
        cron_spec: Optional[str] = None,
        deletion_trigger: Optional['BackupPolicyPlanDeletionTriggerPatch'] = None,
        name: Optional[str] = None,
        remote_region_policies: Optional[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 := _dict.get('active')) is not None:
            args['active'] = active
        if (attach_user_tags := _dict.get('attach_user_tags')) is not None:
            args['attach_user_tags'] = attach_user_tags
        if (clone_policy := _dict.get('clone_policy')) is not None:
            args['clone_policy'] = BackupPolicyPlanClonePolicyPatch.from_dict(clone_policy)
        if (copy_user_tags := _dict.get('copy_user_tags')) is not None:
            args['copy_user_tags'] = copy_user_tags
        if (cron_spec := _dict.get('cron_spec')) is not None:
            args['cron_spec'] = cron_spec
        if (deletion_trigger := _dict.get('deletion_trigger')) is not None:
            args['deletion_trigger'] = BackupPolicyPlanDeletionTriggerPatch.from_dict(deletion_trigger)
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        if (remote_region_policies := _dict.get('remote_region_policies')) is not None:
            args['remote_region_policies'] = [BackupPolicyPlanRemoteRegionPolicyPrototype.from_dict(v) for v in 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.

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

    def __init__(
        self,
        cron_spec: str,
        *,
        active: Optional[bool] = None,
        attach_user_tags: Optional[List[str]] = None,
        clone_policy: Optional['BackupPolicyPlanClonePolicyPrototype'] = None,
        copy_user_tags: Optional[bool] = None,
        deletion_trigger: Optional['BackupPolicyPlanDeletionTriggerPrototype'] = None,
        name: Optional[str] = None,
        remote_region_policies: Optional[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 := _dict.get('active')) is not None:
            args['active'] = active
        if (attach_user_tags := _dict.get('attach_user_tags')) is not None:
            args['attach_user_tags'] = attach_user_tags
        if (clone_policy := _dict.get('clone_policy')) is not None:
            args['clone_policy'] = BackupPolicyPlanClonePolicyPrototype.from_dict(clone_policy)
        if (copy_user_tags := _dict.get('copy_user_tags')) is not None:
            args['copy_user_tags'] = copy_user_tags
        if (cron_spec := _dict.get('cron_spec')) is not None:
            args['cron_spec'] = cron_spec
        else:
            raise ValueError('Required property \'cron_spec\' not present in BackupPolicyPlanPrototype JSON')
        if (deletion_trigger := _dict.get('deletion_trigger')) is not None:
            args['deletion_trigger'] = BackupPolicyPlanDeletionTriggerPrototype.from_dict(deletion_trigger)
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        if (remote_region_policies := _dict.get('remote_region_policies')) is not None:
            args['remote_region_policies'] = [BackupPolicyPlanRemoteRegionPolicyPrototype.from_dict(v) for v in 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.

    :param Deleted deleted: (optional) If present, this property indicates the
          referenced resource has been deleted, and provides
          some supplementary information.
    :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 BackupPolicyPlanRemote remote: (optional) If present, this property
          indicates that the resource associated with this reference
          is remote and therefore may not be directly retrievable.
    :param str resource_type: The resource type.
    """

    def __init__(
        self,
        href: str,
        id: str,
        name: str,
        resource_type: str,
        *,
        deleted: Optional['Deleted'] = None,
        remote: Optional['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 Deleted 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 := _dict.get('deleted')) is not None:
            args['deleted'] = Deleted.from_dict(deleted)
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in BackupPolicyPlanReference JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in BackupPolicyPlanReference JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in BackupPolicyPlanReference JSON')
        if (remote := _dict.get('remote')) is not None:
            args['remote'] = BackupPolicyPlanRemote.from_dict(remote)
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = 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 BackupPolicyPlanRemote:
    """
    If present, this property indicates that the resource associated with this reference
    is remote and therefore may not be directly retrievable.

    :param 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: Optional['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 := _dict.get('region')) is not None:
            args['region'] = RegionReference.from_dict(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.

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

    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 := _dict.get('delete_over_count')) is not None:
            args['delete_over_count'] = delete_over_count
        else:
            raise ValueError('Required property \'delete_over_count\' not present in BackupPolicyPlanRemoteRegionPolicy JSON')
        if (encryption_key := _dict.get('encryption_key')) is not None:
            args['encryption_key'] = EncryptionKeyReference.from_dict(encryption_key)
        else:
            raise ValueError('Required property \'encryption_key\' not present in BackupPolicyPlanRemoteRegionPolicy JSON')
        if (region := _dict.get('region')) is not None:
            args['region'] = RegionReference.from_dict(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.

    :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.
    :param RegionIdentity region: The region this backup policy plan will create
          backups in.
    """

    def __init__(
        self,
        region: 'RegionIdentity',
        *,
        delete_over_count: Optional[int] = None,
        encryption_key: Optional['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 := _dict.get('delete_over_count')) is not None:
            args['delete_over_count'] = delete_over_count
        if (encryption_key := _dict.get('encryption_key')) is not None:
            args['encryption_key'] = encryption_key
        if (region := _dict.get('region')) is not None:
            args['region'] = 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 BackupPolicyPrototype:
    """
    BackupPolicyPrototype.

    :param str match_resource_type: The resource type 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 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 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.
    """

    def __init__(
        self,
        match_resource_type: str,
        match_user_tags: List[str],
        *,
        name: Optional[str] = None,
        plans: Optional[List['BackupPolicyPlanPrototype']] = None,
        resource_group: Optional['ResourceGroupIdentity'] = None,
        scope: Optional['BackupPolicyScopePrototype'] = None,
    ) -> None:
        """
        Initialize a BackupPolicyPrototype object.

        :param str match_resource_type: The resource type 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 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 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.
        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['BackupPolicyPrototypeBackupPolicyMatchResourceTypeVolumePrototype', 'BackupPolicyPrototypeBackupPolicyMatchResourceTypeInstancePrototype'])
        )
        raise Exception(msg)

    class MatchResourceTypeEnum(str, Enum):
        """
        The resource type 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.
        """

        INSTANCE = 'instance'
        VOLUME = 'volume'



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.

    :param int bandwidth: The total bandwidth (in megabits per second) shared across
          the bare metal server network attachments or bare metal server network
          interfaces.
    :param BareMetalServerBootTarget boot_target: The resource from which this bare
          metal server is booted.
          The resources supported by this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) 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 BareMetalServerFirmware firmware: Firmware information for the bare metal
          server.
    :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).
    :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[BareMetalServerNetworkAttachmentReference] network_attachments:
          (optional) The network attachments for this bare metal server, including the
          primary network attachment.
    :param List[NetworkInterfaceBareMetalServerContextReference] network_interfaces:
          The network interfaces for this bare metal server, including the primary network
          interface.
          If this bare metal server has network attachments, each network interface is a
          [read-only
          representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
          of its corresponding network attachment and its attached virtual network
          interface.
    :param BareMetalServerNetworkAttachmentReference primary_network_attachment:
          (optional) The primary network attachment for this bare metal server.
    :param NetworkInterfaceBareMetalServerContextReference
          primary_network_interface: The primary network interface for this bare metal
          server.
          If this bare metal server has network attachments, this primary network
          interface is
          a [read-only
          representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
          of the primary network attachment and its attached virtual network interface.
    :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 this bare metal server:
          - `deleting`: server is undergoing deletion
          - `failed`: server is failed and not usable (see `status_reasons`)
          - `maintenance`: server is undergoing maintenance (not usable)
          - `pending`: server is being provisioned and not yet usable
          - `reinitializing`: server is reinitializing and not yet usable
          - `restarting`: server is restarting and not yet usable
          - `running`: server is powered on
          - `starting`: server is starting and not yet usable
          - `stopped`: server is powered off
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :param List[BareMetalServerStatusReason] status_reasons: The reasons for the
          current status (if any).
    :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.
    """

    def __init__(
        self,
        bandwidth: int,
        boot_target: 'BareMetalServerBootTarget',
        cpu: 'BareMetalServerCPU',
        created_at: datetime,
        crn: str,
        disks: List['BareMetalServerDisk'],
        enable_secure_boot: bool,
        firmware: 'BareMetalServerFirmware',
        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',
        *,
        network_attachments: Optional[List['BareMetalServerNetworkAttachmentReference']] = None,
        primary_network_attachment: Optional['BareMetalServerNetworkAttachmentReference'] = None,
    ) -> None:
        """
        Initialize a BareMetalServer object.

        :param int bandwidth: The total bandwidth (in megabits per second) shared
               across the bare metal server network attachments or bare metal server
               network interfaces.
        :param BareMetalServerBootTarget boot_target: The resource from which this
               bare metal server is booted.
               The resources supported by this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) 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 BareMetalServerFirmware firmware: Firmware information for the bare
               metal server.
        :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).
        :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.
               If this bare metal server has network attachments, each network interface
               is a
               [read-only
               representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
               of its corresponding network attachment and its attached virtual network
               interface.
        :param NetworkInterfaceBareMetalServerContextReference
               primary_network_interface: The primary network interface for this bare
               metal server.
               If this bare metal server has network attachments, this primary network
               interface is
               a [read-only
               representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
               of the primary network attachment and its attached virtual network
               interface.
        :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 this bare metal server:
               - `deleting`: server is undergoing deletion
               - `failed`: server is failed and not usable (see `status_reasons`)
               - `maintenance`: server is undergoing maintenance (not usable)
               - `pending`: server is being provisioned and not yet usable
               - `reinitializing`: server is reinitializing and not yet usable
               - `restarting`: server is restarting and not yet usable
               - `running`: server is powered on
               - `starting`: server is starting and not yet usable
               - `stopped`: server is powered off
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :param List[BareMetalServerStatusReason] status_reasons: The reasons for
               the current status (if any).
        :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.
        :param List[BareMetalServerNetworkAttachmentReference] network_attachments:
               (optional) The network attachments for this bare metal server, including
               the primary network attachment.
        :param BareMetalServerNetworkAttachmentReference
               primary_network_attachment: (optional) The primary network attachment for
               this bare metal server.
        """
        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.firmware = firmware
        self.href = href
        self.id = id
        self.lifecycle_reasons = lifecycle_reasons
        self.lifecycle_state = lifecycle_state
        self.memory = memory
        self.name = name
        self.network_attachments = network_attachments
        self.network_interfaces = network_interfaces
        self.primary_network_attachment = primary_network_attachment
        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 := _dict.get('bandwidth')) is not None:
            args['bandwidth'] = bandwidth
        else:
            raise ValueError('Required property \'bandwidth\' not present in BareMetalServer JSON')
        if (boot_target := _dict.get('boot_target')) is not None:
            args['boot_target'] = boot_target
        else:
            raise ValueError('Required property \'boot_target\' not present in BareMetalServer JSON')
        if (cpu := _dict.get('cpu')) is not None:
            args['cpu'] = BareMetalServerCPU.from_dict(cpu)
        else:
            raise ValueError('Required property \'cpu\' not present in BareMetalServer JSON')
        if (created_at := _dict.get('created_at')) is not None:
            args['created_at'] = string_to_datetime(created_at)
        else:
            raise ValueError('Required property \'created_at\' not present in BareMetalServer JSON')
        if (crn := _dict.get('crn')) is not None:
            args['crn'] = crn
        else:
            raise ValueError('Required property \'crn\' not present in BareMetalServer JSON')
        if (disks := _dict.get('disks')) is not None:
            args['disks'] = [BareMetalServerDisk.from_dict(v) for v in disks]
        else:
            raise ValueError('Required property \'disks\' not present in BareMetalServer JSON')
        if (enable_secure_boot := _dict.get('enable_secure_boot')) is not None:
            args['enable_secure_boot'] = enable_secure_boot
        else:
            raise ValueError('Required property \'enable_secure_boot\' not present in BareMetalServer JSON')
        if (firmware := _dict.get('firmware')) is not None:
            args['firmware'] = BareMetalServerFirmware.from_dict(firmware)
        else:
            raise ValueError('Required property \'firmware\' not present in BareMetalServer JSON')
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in BareMetalServer JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in BareMetalServer JSON')
        if (lifecycle_reasons := _dict.get('lifecycle_reasons')) is not None:
            args['lifecycle_reasons'] = [BareMetalServerLifecycleReason.from_dict(v) for v in lifecycle_reasons]
        else:
            raise ValueError('Required property \'lifecycle_reasons\' not present in BareMetalServer JSON')
        if (lifecycle_state := _dict.get('lifecycle_state')) is not None:
            args['lifecycle_state'] = lifecycle_state
        else:
            raise ValueError('Required property \'lifecycle_state\' not present in BareMetalServer JSON')
        if (memory := _dict.get('memory')) is not None:
            args['memory'] = memory
        else:
            raise ValueError('Required property \'memory\' not present in BareMetalServer JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in BareMetalServer JSON')
        if (network_attachments := _dict.get('network_attachments')) is not None:
            args['network_attachments'] = [BareMetalServerNetworkAttachmentReference.from_dict(v) for v in network_attachments]
        if (network_interfaces := _dict.get('network_interfaces')) is not None:
            args['network_interfaces'] = [NetworkInterfaceBareMetalServerContextReference.from_dict(v) for v in network_interfaces]
        else:
            raise ValueError('Required property \'network_interfaces\' not present in BareMetalServer JSON')
        if (primary_network_attachment := _dict.get('primary_network_attachment')) is not None:
            args['primary_network_attachment'] = BareMetalServerNetworkAttachmentReference.from_dict(primary_network_attachment)
        if (primary_network_interface := _dict.get('primary_network_interface')) is not None:
            args['primary_network_interface'] = NetworkInterfaceBareMetalServerContextReference.from_dict(primary_network_interface)
        else:
            raise ValueError('Required property \'primary_network_interface\' not present in BareMetalServer JSON')
        if (profile := _dict.get('profile')) is not None:
            args['profile'] = BareMetalServerProfileReference.from_dict(profile)
        else:
            raise ValueError('Required property \'profile\' not present in BareMetalServer JSON')
        if (resource_group := _dict.get('resource_group')) is not None:
            args['resource_group'] = ResourceGroupReference.from_dict(resource_group)
        else:
            raise ValueError('Required property \'resource_group\' not present in BareMetalServer JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = resource_type
        else:
            raise ValueError('Required property \'resource_type\' not present in BareMetalServer JSON')
        if (status := _dict.get('status')) is not None:
            args['status'] = status
        else:
            raise ValueError('Required property \'status\' not present in BareMetalServer JSON')
        if (status_reasons := _dict.get('status_reasons')) is not None:
            args['status_reasons'] = [BareMetalServerStatusReason.from_dict(v) for v in status_reasons]
        else:
            raise ValueError('Required property \'status_reasons\' not present in BareMetalServer JSON')
        if (trusted_platform_module := _dict.get('trusted_platform_module')) is not None:
            args['trusted_platform_module'] = BareMetalServerTrustedPlatformModule.from_dict(trusted_platform_module)
        else:
            raise ValueError('Required property \'trusted_platform_module\' not present in BareMetalServer JSON')
        if (vpc := _dict.get('vpc')) is not None:
            args['vpc'] = VPCReference.from_dict(vpc)
        else:
            raise ValueError('Required property \'vpc\' not present in BareMetalServer JSON')
        if (zone := _dict.get('zone')) is not None:
            args['zone'] = ZoneReference.from_dict(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, 'firmware') and self.firmware is not None:
            if isinstance(self.firmware, dict):
                _dict['firmware'] = self.firmware
            else:
                _dict['firmware'] = self.firmware.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_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_attachments') and self.network_attachments is not None:
            network_attachments_list = []
            for v in self.network_attachments:
                if isinstance(v, dict):
                    network_attachments_list.append(v)
                else:
                    network_attachments_list.append(v.to_dict())
            _dict['network_attachments'] = network_attachments_list
        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_attachment') and self.primary_network_attachment is not None:
            if isinstance(self.primary_network_attachment, dict):
                _dict['primary_network_attachment'] = self.primary_network_attachment
            else:
                _dict['primary_network_attachment'] = self.primary_network_attachment.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, '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 this bare metal server:
        - `deleting`: server is undergoing deletion
        - `failed`: server is failed and not usable (see `status_reasons`)
        - `maintenance`: server is undergoing maintenance (not usable)
        - `pending`: server is being provisioned and not yet usable
        - `reinitializing`: server is reinitializing and not yet usable
        - `restarting`: server is restarting and not yet usable
        - `running`: server is powered on
        - `starting`: server is starting and not yet usable
        - `stopped`: server is powered off
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        DELETING = 'deleting'
        FAILED = 'failed'
        MAINTENANCE = 'maintenance'
        PENDING = 'pending'
        REINITIALIZING = 'reinitializing'
        RESTARTING = 'restarting'
        RUNNING = 'running'
        STARTING = 'starting'
        STOPPED = 'stopped'



class BareMetalServerBootTarget:
    """
    The resource from which this bare metal server is booted.
    The resources supported by this property may
    [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) 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.

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

    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 := _dict.get('architecture')) is not None:
            args['architecture'] = architecture
        else:
            raise ValueError('Required property \'architecture\' not present in BareMetalServerCPU JSON')
        if (core_count := _dict.get('core_count')) is not None:
            args['core_count'] = core_count
        else:
            raise ValueError('Required property \'core_count\' not present in BareMetalServerCPU JSON')
        if (socket_count := _dict.get('socket_count')) is not None:
            args['socket_count'] = socket_count
        else:
            raise ValueError('Required property \'socket_count\' not present in BareMetalServerCPU JSON')
        if (threads_per_core := _dict.get('threads_per_core')) is not None:
            args['threads_per_core'] = 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.

    :param List[BareMetalServer] bare_metal_servers: A page of bare metal servers.
    :param PageLink 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 PageLink next: (optional) A link to the next page of resources. This
          property is present for all pages
          except the last page.
    :param int total_count: The total number of resources across all pages.
    """

    def __init__(
        self,
        bare_metal_servers: List['BareMetalServer'],
        first: 'PageLink',
        limit: int,
        total_count: int,
        *,
        next: Optional['PageLink'] = None,
    ) -> None:
        """
        Initialize a BareMetalServerCollection object.

        :param List[BareMetalServer] bare_metal_servers: A page of bare metal
               servers.
        :param PageLink 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 PageLink 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 := _dict.get('bare_metal_servers')) is not None:
            args['bare_metal_servers'] = [BareMetalServer.from_dict(v) for v in bare_metal_servers]
        else:
            raise ValueError('Required property \'bare_metal_servers\' not present in BareMetalServerCollection JSON')
        if (first := _dict.get('first')) is not None:
            args['first'] = PageLink.from_dict(first)
        else:
            raise ValueError('Required property \'first\' not present in BareMetalServerCollection JSON')
        if (limit := _dict.get('limit')) is not None:
            args['limit'] = limit
        else:
            raise ValueError('Required property \'limit\' not present in BareMetalServerCollection JSON')
        if (next := _dict.get('next')) is not None:
            args['next'] = PageLink.from_dict(next)
        if (total_count := _dict.get('total_count')) is not None:
            args['total_count'] = 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 BareMetalServerConsoleAccessToken:
    """
    The bare metal server console access token information.

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

    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 := _dict.get('access_token')) is not None:
            args['access_token'] = access_token
        else:
            raise ValueError('Required property \'access_token\' not present in BareMetalServerConsoleAccessToken JSON')
        if (console_type := _dict.get('console_type')) is not None:
            args['console_type'] = console_type
        else:
            raise ValueError('Required property \'console_type\' not present in BareMetalServerConsoleAccessToken JSON')
        if (created_at := _dict.get('created_at')) is not None:
            args['created_at'] = string_to_datetime(created_at)
        else:
            raise ValueError('Required property \'created_at\' not present in BareMetalServerConsoleAccessToken JSON')
        if (expires_at := _dict.get('expires_at')) is not None:
            args['expires_at'] = string_to_datetime(expires_at)
        else:
            raise ValueError('Required property \'expires_at\' not present in BareMetalServerConsoleAccessToken JSON')
        if (force := _dict.get('force')) is not None:
            args['force'] = force
        else:
            raise ValueError('Required property \'force\' not present in BareMetalServerConsoleAccessToken JSON')
        if (href := _dict.get('href')) is not None:
            args['href'] = 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.

    :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 attachment interface used:
          - `fcp`: Fiber Channel Protocol
          - `sata`: Serial Advanced Technology Attachment
          - `nvme`: Non-Volatile Memory Express
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :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).
    """

    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 attachment interface used:
               - `fcp`: Fiber Channel Protocol
               - `sata`: Serial Advanced Technology Attachment
               - `nvme`: Non-Volatile Memory Express
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :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 := _dict.get('created_at')) is not None:
            args['created_at'] = string_to_datetime(created_at)
        else:
            raise ValueError('Required property \'created_at\' not present in BareMetalServerDisk JSON')
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in BareMetalServerDisk JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in BareMetalServerDisk JSON')
        if (interface_type := _dict.get('interface_type')) is not None:
            args['interface_type'] = interface_type
        else:
            raise ValueError('Required property \'interface_type\' not present in BareMetalServerDisk JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in BareMetalServerDisk JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = resource_type
        else:
            raise ValueError('Required property \'resource_type\' not present in BareMetalServerDisk JSON')
        if (size := _dict.get('size')) is not None:
            args['size'] = 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 attachment interface used:
        - `fcp`: Fiber Channel Protocol
        - `sata`: Serial Advanced Technology Attachment
        - `nvme`: Non-Volatile Memory Express
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        FCP = 'fcp'
        NVME = 'nvme'
        SATA = 'sata'


    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        BARE_METAL_SERVER_DISK = 'bare_metal_server_disk'



class BareMetalServerDiskCollection:
    """
    BareMetalServerDiskCollection.

    :param List[BareMetalServerDisk] disks: The disks for the bare metal server.
    """

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

        :param List[BareMetalServerDisk] disks: The disks for the bare metal
               server.
        """
        self.disks = disks

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'BareMetalServerDiskCollection':
        """Initialize a BareMetalServerDiskCollection object from a json dictionary."""
        args = {}
        if (disks := _dict.get('disks')) is not None:
            args['disks'] = [BareMetalServerDisk.from_dict(v) for v in 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.

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

    def __init__(
        self,
        *,
        name: Optional[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 := _dict.get('name')) is not None:
            args['name'] = 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 BareMetalServerFirmware:
    """
    Firmware information for the bare metal server.

    :param str update: The type of update available.
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    """

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

        :param str update: The type of update available.
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        """
        self.update = update

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

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

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

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

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

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

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

    class UpdateEnum(str, Enum):
        """
        The type of update available.
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        NONE = 'none'
        OPTIONAL = 'optional'
        REQUIRED = 'required'



class BareMetalServerInitialization:
    """
    BareMetalServerInitialization.

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

    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 := _dict.get('image')) is not None:
            args['image'] = ImageReference.from_dict(image)
        else:
            raise ValueError('Required property \'image\' not present in BareMetalServerInitialization JSON')
        if (keys := _dict.get('keys')) is not None:
            args['keys'] = [KeyReference.from_dict(v) for v in keys]
        else:
            raise ValueError('Required property \'keys\' not present in BareMetalServerInitialization JSON')
        if (user_accounts := _dict.get('user_accounts')) is not None:
            args['user_accounts'] = 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.

    :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.
          If unspecified, no user data will be made available.
    """

    def __init__(
        self,
        image: 'ImageIdentity',
        keys: List['KeyIdentity'],
        *,
        user_data: Optional[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.
               If unspecified, no user data will be made available.
        """
        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 := _dict.get('image')) is not None:
            args['image'] = image
        else:
            raise ValueError('Required property \'image\' not present in BareMetalServerInitializationPrototype JSON')
        if (keys := _dict.get('keys')) is not None:
            args['keys'] = keys
        else:
            raise ValueError('Required property \'keys\' not present in BareMetalServerInitializationPrototype JSON')
        if (user_data := _dict.get('user_data')) is not None:
            args['user_data'] = 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.

    :param str code: A reason code for this lifecycle state:
          - `internal_error`: internal error (contact IBM support)
          - `resource_suspended_by_provider`: The resource has been suspended (contact IBM
            support)
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :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.
    """

    def __init__(
        self,
        code: str,
        message: str,
        *,
        more_info: Optional[str] = None,
    ) -> None:
        """
        Initialize a BareMetalServerLifecycleReason object.

        :param str code: A reason code for this lifecycle state:
               - `internal_error`: internal error (contact IBM support)
               - `resource_suspended_by_provider`: The resource has been suspended
               (contact IBM
                 support)
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :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 := _dict.get('code')) is not None:
            args['code'] = code
        else:
            raise ValueError('Required property \'code\' not present in BareMetalServerLifecycleReason JSON')
        if (message := _dict.get('message')) is not None:
            args['message'] = message
        else:
            raise ValueError('Required property \'message\' not present in BareMetalServerLifecycleReason JSON')
        if (more_info := _dict.get('more_info')) is not None:
            args['more_info'] = 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 reason code for this lifecycle state:
        - `internal_error`: internal error (contact IBM support)
        - `resource_suspended_by_provider`: The resource has been suspended (contact IBM
          support)
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        INTERNAL_ERROR = 'internal_error'
        RESOURCE_SUSPENDED_BY_PROVIDER = 'resource_suspended_by_provider'



class BareMetalServerNetworkAttachment:
    """
    BareMetalServerNetworkAttachment.

    :param datetime created_at: The date and time that the bare metal server network
          attachment was created.
    :param str href: The URL for this bare metal server network attachment.
    :param str id: The unique identifier for this bare metal server network
          attachment.
    :param str interface_type: The network attachment's 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 attachment
            - 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.
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :param str lifecycle_state: The lifecycle state of the bare metal server network
          attachment.
    :param str name: The name for this bare metal server network attachment. The
          name is unique across all network attachments for the bare metal server.
    :param int port_speed: The port speed for this bare metal server network
          attachment in Mbps.
    :param ReservedIPReference primary_ip: The primary IP address of the virtual
          network interface for the bare metal server
          network attachment.
    :param str resource_type: The resource type.
    :param SubnetReference subnet: The subnet of the virtual network interface for
          the bare metal server network
          attachment.
    :param str type: The bare metal server network attachment type.
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :param VirtualNetworkInterfaceReferenceAttachmentContext
          virtual_network_interface: The virtual network interface for this bare metal
          server network attachment.
    """

    def __init__(
        self,
        created_at: datetime,
        href: str,
        id: str,
        interface_type: str,
        lifecycle_state: str,
        name: str,
        port_speed: int,
        primary_ip: 'ReservedIPReference',
        resource_type: str,
        subnet: 'SubnetReference',
        type: str,
        virtual_network_interface: 'VirtualNetworkInterfaceReferenceAttachmentContext',
    ) -> None:
        """
        Initialize a BareMetalServerNetworkAttachment object.

        :param datetime created_at: The date and time that the bare metal server
               network attachment was created.
        :param str href: The URL for this bare metal server network attachment.
        :param str id: The unique identifier for this bare metal server network
               attachment.
        :param str interface_type: The network attachment's 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 attachment
                 - 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.
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :param str lifecycle_state: The lifecycle state of the bare metal server
               network attachment.
        :param str name: The name for this bare metal server network attachment.
               The name is unique across all network attachments for the bare metal
               server.
        :param int port_speed: The port speed for this bare metal server network
               attachment in Mbps.
        :param ReservedIPReference primary_ip: The primary IP address of the
               virtual network interface for the bare metal server
               network attachment.
        :param str resource_type: The resource type.
        :param SubnetReference subnet: The subnet of the virtual network interface
               for the bare metal server network
               attachment.
        :param str type: The bare metal server network attachment type.
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :param VirtualNetworkInterfaceReferenceAttachmentContext
               virtual_network_interface: The virtual network interface for this bare
               metal server network attachment.
        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['BareMetalServerNetworkAttachmentByPCI', 'BareMetalServerNetworkAttachmentByVLAN'])
        )
        raise Exception(msg)

    class InterfaceTypeEnum(str, Enum):
        """
        The network attachment's 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 attachment
          - 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.
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        PCI = 'pci'
        VLAN = 'vlan'


    class LifecycleStateEnum(str, Enum):
        """
        The lifecycle state of the bare metal server network attachment.
        """

        DELETING = 'deleting'
        FAILED = 'failed'
        PENDING = 'pending'
        STABLE = 'stable'
        SUSPENDED = 'suspended'
        UPDATING = 'updating'
        WAITING = 'waiting'


    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        BARE_METAL_SERVER_NETWORK_ATTACHMENT = 'bare_metal_server_network_attachment'


    class TypeEnum(str, Enum):
        """
        The bare metal server network attachment type.
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        PRIMARY = 'primary'
        SECONDARY = 'secondary'



class BareMetalServerNetworkAttachmentCollection:
    """
    BareMetalServerNetworkAttachmentCollection.

    :param PageLink 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[BareMetalServerNetworkAttachment] network_attachments: The network
          attachments for the bare metal server.
    :param PageLink next: (optional) A link to the next page of resources. This
          property is present for all pages
          except the last page.
    :param int total_count: The total number of resources across all pages.
    """

    def __init__(
        self,
        first: 'PageLink',
        limit: int,
        network_attachments: List['BareMetalServerNetworkAttachment'],
        total_count: int,
        *,
        next: Optional['PageLink'] = None,
    ) -> None:
        """
        Initialize a BareMetalServerNetworkAttachmentCollection object.

        :param PageLink 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[BareMetalServerNetworkAttachment] network_attachments: The
               network attachments for the bare metal server.
        :param int total_count: The total number of resources across all pages.
        :param PageLink 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_attachments = network_attachments
        self.next = next
        self.total_count = total_count

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'BareMetalServerNetworkAttachmentCollection':
        """Initialize a BareMetalServerNetworkAttachmentCollection object from a json dictionary."""
        args = {}
        if (first := _dict.get('first')) is not None:
            args['first'] = PageLink.from_dict(first)
        else:
            raise ValueError('Required property \'first\' not present in BareMetalServerNetworkAttachmentCollection JSON')
        if (limit := _dict.get('limit')) is not None:
            args['limit'] = limit
        else:
            raise ValueError('Required property \'limit\' not present in BareMetalServerNetworkAttachmentCollection JSON')
        if (network_attachments := _dict.get('network_attachments')) is not None:
            args['network_attachments'] = network_attachments
        else:
            raise ValueError('Required property \'network_attachments\' not present in BareMetalServerNetworkAttachmentCollection JSON')
        if (next := _dict.get('next')) is not None:
            args['next'] = PageLink.from_dict(next)
        if (total_count := _dict.get('total_count')) is not None:
            args['total_count'] = total_count
        else:
            raise ValueError('Required property \'total_count\' not present in BareMetalServerNetworkAttachmentCollection JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a BareMetalServerNetworkAttachmentCollection object from 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_attachments') and self.network_attachments is not None:
            network_attachments_list = []
            for v in self.network_attachments:
                if isinstance(v, dict):
                    network_attachments_list.append(v)
                else:
                    network_attachments_list.append(v.to_dict())
            _dict['network_attachments'] = network_attachments_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 BareMetalServerNetworkAttachmentCollection object."""
        return json.dumps(self.to_dict(), indent=2)

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

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


class BareMetalServerNetworkAttachmentPatch:
    """
    BareMetalServerNetworkAttachmentPatch.

    :param List[int] allowed_vlans: (optional) The VLAN IDs to allow for `vlan`
          attachments using this PCI attachment, replacing any existing VLAN IDs. The
          specified values must include IDs for all `vlan` attachments currently using
          this PCI attachment.
    :param str name: (optional) The name for this network attachment. The name must
          not be used by another network attachment for the bare metal server.
    """

    def __init__(
        self,
        *,
        allowed_vlans: Optional[List[int]] = None,
        name: Optional[str] = None,
    ) -> None:
        """
        Initialize a BareMetalServerNetworkAttachmentPatch object.

        :param List[int] allowed_vlans: (optional) The VLAN IDs to allow for `vlan`
               attachments using this PCI attachment, replacing any existing VLAN IDs. The
               specified values must include IDs for all `vlan` attachments currently
               using this PCI attachment.
        :param str name: (optional) The name for this network attachment. The name
               must not be used by another network attachment for the bare metal server.
        """
        self.allowed_vlans = allowed_vlans
        self.name = name

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

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

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

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

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


class BareMetalServerNetworkAttachmentPrototype:
    """
    BareMetalServerNetworkAttachmentPrototype.

    :param str interface_type: The network attachment's 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 attachment
            - 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.
            - Not supported on bare metal servers with a `cpu.architecture` of `s390x`.
    :param str name: (optional) The name for this bare metal server network
          attachment. Names must be unique within the bare metal server the network
          attachment resides in. If unspecified, the name will be a hyphenated list of
          randomly-selected words.
    :param BareMetalServerNetworkAttachmentPrototypeVirtualNetworkInterface
          virtual_network_interface: A virtual network interface for the bare metal server
          network attachment. This can be
          specified using an existing virtual network interface, or a prototype object for
          a new
          virtual network interface.
          If an existing virtual network interface is specified, it must not be the target
          of a flow
          log collector.
    """

    def __init__(
        self,
        interface_type: str,
        virtual_network_interface: 'BareMetalServerNetworkAttachmentPrototypeVirtualNetworkInterface',
        *,
        name: Optional[str] = None,
    ) -> None:
        """
        Initialize a BareMetalServerNetworkAttachmentPrototype object.

        :param str interface_type: The network attachment's 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 attachment
                 - 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.
                 - Not supported on bare metal servers with a `cpu.architecture` of
               `s390x`.
        :param BareMetalServerNetworkAttachmentPrototypeVirtualNetworkInterface
               virtual_network_interface: A virtual network interface for the bare metal
               server network attachment. This can be
               specified using an existing virtual network interface, or a prototype
               object for a new
               virtual network interface.
               If an existing virtual network interface is specified, it must not be the
               target of a flow
               log collector.
        :param str name: (optional) The name for this bare metal server network
               attachment. Names must be unique within the bare metal server the network
               attachment resides in. If unspecified, the name will be a hyphenated list
               of randomly-selected words.
        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['BareMetalServerNetworkAttachmentPrototypeBareMetalServerNetworkAttachmentByPCIPrototype', 'BareMetalServerNetworkAttachmentPrototypeBareMetalServerNetworkAttachmentByVLANPrototype'])
        )
        raise Exception(msg)

    class InterfaceTypeEnum(str, Enum):
        """
        The network attachment's 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 attachment
          - 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.
          - Not supported on bare metal servers with a `cpu.architecture` of `s390x`.
        """

        PCI = 'pci'
        VLAN = 'vlan'



class BareMetalServerNetworkAttachmentPrototypeVirtualNetworkInterface:
    """
    A virtual network interface for the bare metal server network attachment. This can be
    specified using an existing virtual network interface, or a prototype object for a new
    virtual network interface.
    If an existing virtual network interface is specified, it must not be the target of a
    flow log collector.

    """

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

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


class BareMetalServerNetworkAttachmentReference:
    """
    BareMetalServerNetworkAttachmentReference.

    :param Deleted deleted: (optional) If present, this property indicates the
          referenced resource has been deleted, and provides
          some supplementary information.
    :param str href: The URL for this bare metal server network attachment.
    :param str id: The unique identifier for this bare metal server network
          attachment.
    :param str name: The name for this bare metal server network attachment. The
          name is unique across all network attachments for the bare metal server.
    :param ReservedIPReference primary_ip: The primary IP address of the virtual
          network interface for the bare metal server
          network attachment.
    :param str resource_type: The resource type.
    :param SubnetReference subnet: The subnet of the virtual network interface for
          the bare metal server network
          attachment.
    :param VirtualNetworkInterfaceReferenceAttachmentContext
          virtual_network_interface: The virtual network interface for this bare metal
          server network attachment.
    """

    def __init__(
        self,
        href: str,
        id: str,
        name: str,
        primary_ip: 'ReservedIPReference',
        resource_type: str,
        subnet: 'SubnetReference',
        virtual_network_interface: 'VirtualNetworkInterfaceReferenceAttachmentContext',
        *,
        deleted: Optional['Deleted'] = None,
    ) -> None:
        """
        Initialize a BareMetalServerNetworkAttachmentReference object.

        :param str href: The URL for this bare metal server network attachment.
        :param str id: The unique identifier for this bare metal server network
               attachment.
        :param str name: The name for this bare metal server network attachment.
               The name is unique across all network attachments for the bare metal
               server.
        :param ReservedIPReference primary_ip: The primary IP address of the
               virtual network interface for the bare metal server
               network attachment.
        :param str resource_type: The resource type.
        :param SubnetReference subnet: The subnet of the virtual network interface
               for the bare metal server network
               attachment.
        :param VirtualNetworkInterfaceReferenceAttachmentContext
               virtual_network_interface: The virtual network interface for this bare
               metal server network attachment.
        :param Deleted 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
        self.virtual_network_interface = virtual_network_interface

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'BareMetalServerNetworkAttachmentReference':
        """Initialize a BareMetalServerNetworkAttachmentReference object from a json dictionary."""
        args = {}
        if (deleted := _dict.get('deleted')) is not None:
            args['deleted'] = Deleted.from_dict(deleted)
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in BareMetalServerNetworkAttachmentReference JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in BareMetalServerNetworkAttachmentReference JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in BareMetalServerNetworkAttachmentReference JSON')
        if (primary_ip := _dict.get('primary_ip')) is not None:
            args['primary_ip'] = ReservedIPReference.from_dict(primary_ip)
        else:
            raise ValueError('Required property \'primary_ip\' not present in BareMetalServerNetworkAttachmentReference JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = resource_type
        else:
            raise ValueError('Required property \'resource_type\' not present in BareMetalServerNetworkAttachmentReference JSON')
        if (subnet := _dict.get('subnet')) is not None:
            args['subnet'] = SubnetReference.from_dict(subnet)
        else:
            raise ValueError('Required property \'subnet\' not present in BareMetalServerNetworkAttachmentReference JSON')
        if (virtual_network_interface := _dict.get('virtual_network_interface')) is not None:
            args['virtual_network_interface'] = VirtualNetworkInterfaceReferenceAttachmentContext.from_dict(virtual_network_interface)
        else:
            raise ValueError('Required property \'virtual_network_interface\' not present in BareMetalServerNetworkAttachmentReference JSON')
        return cls(**args)

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

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

    def __ne__(self, other: 'BareMetalServerNetworkAttachmentReference') -> 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_NETWORK_ATTACHMENT = 'bare_metal_server_network_attachment'



class BareMetalServerNetworkInterface:
    """
    BareMetalServerNetworkInterface.

    :param bool allow_ip_spoofing: Indicates whether source IP spoofing is allowed
          on this bare metal server network interface.
          If this bare metal server has network attachments, this network interface is a
          [read-only
          representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
          of its corresponding network attachment and its attached virtual network
          interface, and source IP spoofing is managed on the attached virtual network
          interface.
    :param datetime created_at: The date and time that the bare metal server network
          interface was created.
          If this bare metal server has network attachments, this network interface was
          created as a [read-only
          representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
          when its corresponding network attachment 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`.
          If this bare metal server has network attachments, this network interface is a
          [read-only
          representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
          of its corresponding network attachment and its attached virtual network
          interface, and infrastructure NAT is managed on the attached virtual network
          interface.
    :param List[FloatingIPReference] floating_ips: The floating IPs associated with
          this bare metal server network interface.
          If this bare metal server has network attachments, this network interface is a
          [read-only
          representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
          of its corresponding network attachment and its attached virtual network
          interface, and the floating IPs are associated with the attached virtual network
          interface.
    :param str href: The URL for this bare metal server network interface.
          If this bare metal server has network attachments, this network interface is a
          [read-only
          representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
          of its corresponding network attachment.
    :param str id: The unique identifier for this bare metal server network
          interface.
          If this bare metal server has network attachments, this network interface is a
          [read-only
          representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
          of its corresponding network attachment and its attached virtual network
          interface, and the identifier is that of the corresponding network attachment.
    :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.
          If this bare metal server has network attachments, this network interface is a
          [read-only
          representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
          of its corresponding network attachment and its attached virtual network
          interface, and the interface type is that of the corresponding network
          attachment.
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :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
          empty.
          If this bare metal server has network attachments, this network interface is a
          [read-only
          representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
          of its corresponding network attachment and its attached virtual network
          interface, and the MAC address is that of the attached virtual network
          interface.
    :param str name: The name for this bare metal server network interface.
          If this bare metal server has network attachments, this network interface is a
          [read-only
          representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
          of its corresponding network attachment and its attached virtual network
          interface, and the name matches its corresponding network attachment.
    :param int port_speed: The bare metal server network interface port speed in
          Mbps.
          If this bare metal server has network attachments, this network interface is a
          [read-only
          representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
          of its corresponding network attachment and its attached virtual network
          interface, and the port speed is that of its corresponding network attachment.
    :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.
          If this bare metal server has network attachments, this network interface is a
          [read-only
          representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
          of its corresponding network attachment and its attached virtual network
          interface, and the security groups are associated with the attached virtual
          network interface.
    :param str status: The status of the bare metal server network interface.
          If this bare metal server has network attachments, this network interface is a
          read-only representation of its corresponding network attachment and its
          attached virtual network interface, and the status is [computed from
          them](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients).
    :param SubnetReference subnet: The associated subnet.
    :param str type: The bare metal server network interface type.
          If this bare metal server has network attachments, this network interface is a
          [read-only
          representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
          of its corresponding network attachment and its attached virtual network
          interface, and the type is that of its corresponding network attachment.
    """

    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.
               If this bare metal server has network attachments, this network interface
               is a
               [read-only
               representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
               of its corresponding network attachment and its attached virtual network
               interface, and source IP spoofing is managed on the attached virtual
               network interface.
        :param datetime created_at: The date and time that the bare metal server
               network interface was created.
               If this bare metal server has network attachments, this network interface
               was created as a [read-only
               representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
               when its corresponding network attachment 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`.
               If this bare metal server has network attachments, this network interface
               is a
               [read-only
               representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
               of its corresponding network attachment and its attached virtual network
               interface, and infrastructure NAT is managed on the attached virtual
               network interface.
        :param List[FloatingIPReference] floating_ips: The floating IPs associated
               with this bare metal server network interface.
               If this bare metal server has network attachments, this network interface
               is a
               [read-only
               representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
               of its corresponding network attachment and its attached virtual network
               interface, and the floating IPs are associated with the attached virtual
               network interface.
        :param str href: The URL for this bare metal server network interface.
               If this bare metal server has network attachments, this network interface
               is a
               [read-only
               representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
               of its corresponding network attachment.
        :param str id: The unique identifier for this bare metal server network
               interface.
               If this bare metal server has network attachments, this network interface
               is a
               [read-only
               representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
               of its corresponding network attachment and its attached virtual network
               interface, and the identifier is that of the corresponding network
               attachment.
        :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.
               If this bare metal server has network attachments, this network interface
               is a
               [read-only
               representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
               of its corresponding network attachment and its attached virtual network
               interface, and the interface type is that of the corresponding network
               attachment.
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :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
               empty.
               If this bare metal server has network attachments, this network interface
               is a
               [read-only
               representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
               of its corresponding network attachment and its attached virtual network
               interface, and the MAC address is that of the attached virtual network
               interface.
        :param str name: The name for this bare metal server network interface.
               If this bare metal server has network attachments, this network interface
               is a
               [read-only
               representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
               of its corresponding network attachment and its attached virtual network
               interface, and the name matches its corresponding network attachment.
        :param int port_speed: The bare metal server network interface port speed
               in Mbps.
               If this bare metal server has network attachments, this network interface
               is a
               [read-only
               representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
               of its corresponding network attachment and its attached virtual network
               interface, and the port speed is that of its corresponding network
               attachment.
        :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.
               If this bare metal server has network attachments, this network interface
               is a
               [read-only
               representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
               of its corresponding network attachment and its attached virtual network
               interface, and the security groups are associated with the attached virtual
               network interface.
        :param str status: The status of the bare metal server network interface.
               If this bare metal server has network attachments, this network interface
               is a read-only representation of its corresponding network attachment and
               its attached virtual network interface, and the status is [computed from
               them](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients).
        :param SubnetReference subnet: The associated subnet.
        :param str type: The bare metal server network interface type.
               If this bare metal server has network attachments, this network interface
               is a
               [read-only
               representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
               of its corresponding network attachment and its attached virtual network
               interface, and the type is that of its corresponding network attachment.
        """
        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.
        If this bare metal server has network attachments, this network interface is a
        [read-only
        representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
        of its corresponding network attachment and its attached virtual network
        interface, and the interface type is that of the corresponding network attachment.
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        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.
        If this bare metal server has network attachments, this network interface is a
        read-only representation of its corresponding network attachment and its attached
        virtual network interface, and the status is [computed from
        them](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients).
        """

        AVAILABLE = 'available'
        DELETING = 'deleting'
        FAILED = 'failed'
        PENDING = 'pending'


    class TypeEnum(str, Enum):
        """
        The bare metal server network interface type.
        If this bare metal server has network attachments, this network interface is a
        [read-only
        representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
        of its corresponding network attachment and its attached virtual network
        interface, and the type is that of its corresponding network attachment.
        """

        PRIMARY = 'primary'
        SECONDARY = 'secondary'



class BareMetalServerNetworkInterfaceCollection:
    """
    BareMetalServerNetworkInterfaceCollection.

    :param PageLink 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: The network
          interfaces for the bare metal server.
    :param PageLink next: (optional) A link to the next page of resources. This
          property is present for all pages
          except the last page.
    :param int total_count: The total number of resources across all pages.
    """

    def __init__(
        self,
        first: 'PageLink',
        limit: int,
        network_interfaces: List['BareMetalServerNetworkInterface'],
        total_count: int,
        *,
        next: Optional['PageLink'] = None,
    ) -> None:
        """
        Initialize a BareMetalServerNetworkInterfaceCollection object.

        :param PageLink 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: The
               network interfaces for the bare metal server.
        :param int total_count: The total number of resources across all pages.
        :param PageLink 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 := _dict.get('first')) is not None:
            args['first'] = PageLink.from_dict(first)
        else:
            raise ValueError('Required property \'first\' not present in BareMetalServerNetworkInterfaceCollection JSON')
        if (limit := _dict.get('limit')) is not None:
            args['limit'] = limit
        else:
            raise ValueError('Required property \'limit\' not present in BareMetalServerNetworkInterfaceCollection JSON')
        if (network_interfaces := _dict.get('network_interfaces')) is not None:
            args['network_interfaces'] = [BareMetalServerNetworkInterface.from_dict(v) for v in network_interfaces]
        else:
            raise ValueError('Required property \'network_interfaces\' not present in BareMetalServerNetworkInterfaceCollection JSON')
        if (next := _dict.get('next')) is not None:
            args['next'] = PageLink.from_dict(next)
        if (total_count := _dict.get('total_count')) is not None:
            args['total_count'] = 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 BareMetalServerNetworkInterfacePatch:
    """
    BareMetalServerNetworkInterfacePatch.

    :param bool allow_ip_spoofing: (optional) Indicates whether source IP spoofing
          is allowed on this bare metal server network interface.
          If this bare metal server has network attachments, this network interface is a
          [read-only
          representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
          of its corresponding network attachment and its attached virtual network
          interface, and source IP spoofing is managed on the attached virtual 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`.
          If this bare metal server has network attachments, this network interface is a
          [read-only
          representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
          of its corresponding network attachment and its attached virtual network
          interface, and infrastructure NAT is managed on the attached virtual network
          interface.
    :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.
    """

    def __init__(
        self,
        *,
        allow_ip_spoofing: Optional[bool] = None,
        allowed_vlans: Optional[List[int]] = None,
        enable_infrastructure_nat: Optional[bool] = None,
        name: Optional[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.
               If this bare metal server has network attachments, this network interface
               is a
               [read-only
               representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
               of its corresponding network attachment and its attached virtual network
               interface, and source IP spoofing is managed on the attached virtual
               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`.
               If this bare metal server has network attachments, this network interface
               is a
               [read-only
               representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
               of its corresponding network attachment and its attached virtual network
               interface, and infrastructure NAT is managed on the attached virtual
               network interface.
        :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 := _dict.get('allow_ip_spoofing')) is not None:
            args['allow_ip_spoofing'] = allow_ip_spoofing
        if (allowed_vlans := _dict.get('allowed_vlans')) is not None:
            args['allowed_vlans'] = allowed_vlans
        if (enable_infrastructure_nat := _dict.get('enable_infrastructure_nat')) is not None:
            args['enable_infrastructure_nat'] = enable_infrastructure_nat
        if (name := _dict.get('name')) is not None:
            args['name'] = 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.

    :param bool allow_ip_spoofing: (optional) Indicates whether source IP spoofing
          is allowed on this bare metal server network interface.
          If this bare metal server has network attachments, this network interface is a
          [read-only
          representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
          of its corresponding network attachment and its attached virtual network
          interface, and source IP spoofing is managed on the attached virtual 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`.
          If this bare metal server has network attachments, this network interface is a
          [read-only
          representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
          of its corresponding network attachment and its attached virtual network
          interface, and infrastructure NAT is managed on the attached virtual 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
            - 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 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 SubnetIdentity subnet: The associated subnet.
    """

    def __init__(
        self,
        interface_type: str,
        subnet: 'SubnetIdentity',
        *,
        allow_ip_spoofing: Optional[bool] = None,
        enable_infrastructure_nat: Optional[bool] = None,
        name: Optional[str] = None,
        primary_ip: Optional['NetworkInterfaceIPPrototype'] = None,
        security_groups: Optional[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.
               If this bare metal server has network attachments, this network interface
               is a
               [read-only
               representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
               of its corresponding network attachment and its attached virtual network
               interface, and source IP spoofing is managed on the attached virtual
               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`.
               If this bare metal server has network attachments, this network interface
               is a
               [read-only
               representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
               of its corresponding network attachment and its attached virtual network
               interface, and infrastructure NAT is managed on the attached virtual
               network interface.
        :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 BareMetalServerPatch:
    """
    BareMetalServerPatch.

    :param int bandwidth: (optional) The total bandwidth (in megabits per second)
          shared across the bare metal server's network interfaces. The specified value
          must match one of the bandwidth values in the bare metal server's profile.
    :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)
    """

    def __init__(
        self,
        *,
        bandwidth: Optional[int] = None,
        enable_secure_boot: Optional[bool] = None,
        name: Optional[str] = None,
        trusted_platform_module: Optional['BareMetalServerTrustedPlatformModulePatch'] = None,
    ) -> None:
        """
        Initialize a BareMetalServerPatch object.

        :param int bandwidth: (optional) The total bandwidth (in megabits per
               second) shared across the bare metal server's network interfaces. The
               specified value must match one of the bandwidth values in the bare metal
               server's profile.
        :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.bandwidth = bandwidth
        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 (bandwidth := _dict.get('bandwidth')) is not None:
            args['bandwidth'] = bandwidth
        if (enable_secure_boot := _dict.get('enable_secure_boot')) is not None:
            args['enable_secure_boot'] = enable_secure_boot
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        if (trusted_platform_module := _dict.get('trusted_platform_module')) is not None:
            args['trusted_platform_module'] = BareMetalServerTrustedPlatformModulePatch.from_dict(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, 'bandwidth') and self.bandwidth is not None:
            _dict['bandwidth'] = self.bandwidth
        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 BareMetalServerPrimaryNetworkAttachmentPrototype:
    """
    BareMetalServerPrimaryNetworkAttachmentPrototype.

    :param str interface_type: (optional) The network attachment's 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 attachment
            - 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
          attachment. Names must be unique within the bare metal server the network
          attachment resides in. If unspecified, the name will be a hyphenated list of
          randomly-selected words.
    :param BareMetalServerNetworkAttachmentPrototypeVirtualNetworkInterface
          virtual_network_interface: A virtual network interface for the bare metal server
          network attachment. This can be
          specified using an existing virtual network interface, or a prototype object for
          a new
          virtual network interface.
          If an existing virtual network interface is specified, it must not be the target
          of a flow
          log collector.
    """

    def __init__(
        self,
        virtual_network_interface: 'BareMetalServerNetworkAttachmentPrototypeVirtualNetworkInterface',
        *,
        interface_type: Optional[str] = None,
        name: Optional[str] = None,
    ) -> None:
        """
        Initialize a BareMetalServerPrimaryNetworkAttachmentPrototype object.

        :param BareMetalServerNetworkAttachmentPrototypeVirtualNetworkInterface
               virtual_network_interface: A virtual network interface for the bare metal
               server network attachment. This can be
               specified using an existing virtual network interface, or a prototype
               object for a new
               virtual network interface.
               If an existing virtual network interface is specified, it must not be the
               target of a flow
               log collector.
        :param str interface_type: (optional) The network attachment's 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 attachment
                 - 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
               attachment. Names must be unique within the bare metal server the network
               attachment resides in. If unspecified, the name will be a hyphenated list
               of randomly-selected words.
        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['BareMetalServerPrimaryNetworkAttachmentPrototypeBareMetalServerPrimaryNetworkAttachmentByPCIPrototype'])
        )
        raise Exception(msg)

    class InterfaceTypeEnum(str, Enum):
        """
        The network attachment's 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 attachment
          - Cannot directly use an IEEE 802.1Q tag.
          - Not supported on bare metal servers with a `cpu.architecture` of `s390x`.
        """

        PCI = 'pci'



class BareMetalServerPrimaryNetworkInterfacePrototype:
    """
    BareMetalServerPrimaryNetworkInterfacePrototype.

    :param bool allow_ip_spoofing: (optional) Indicates whether source IP spoofing
          is allowed on this bare metal server network interface.
          If this bare metal server has network attachments, this network interface is a
          [read-only
          representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
          of its corresponding network attachment and its attached virtual network
          interface, and source IP spoofing is managed on the attached virtual network
          interface.
    :param List[int] allowed_vlans: (optional) The VLAN IDs allowed for `vlan`
          interfaces using this PCI interface.
          If this bare metal server has network attachments, this network interface is a
          [read-only
          representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
          of its corresponding network attachment and its attached virtual network
          interface, and the VLAN IDs match the `allow_vlans` of the corresponding network
          attachment.
    :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`.
          If this bare metal server has network attachments, this network interface is a
          [read-only
          representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
          of its corresponding network attachment and its attached virtual network
          interface, and infrastructure NAT is managed on the attached virtual network
          interface.
    :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.
    :param SubnetIdentity subnet: The associated subnet.
    """

    def __init__(
        self,
        subnet: 'SubnetIdentity',
        *,
        allow_ip_spoofing: Optional[bool] = None,
        allowed_vlans: Optional[List[int]] = None,
        enable_infrastructure_nat: Optional[bool] = None,
        interface_type: Optional[str] = None,
        name: Optional[str] = None,
        primary_ip: Optional['NetworkInterfaceIPPrototype'] = None,
        security_groups: Optional[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.
               If this bare metal server has network attachments, this network interface
               is a
               [read-only
               representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
               of its corresponding network attachment and its attached virtual network
               interface, and source IP spoofing is managed on the attached virtual
               network interface.
        :param List[int] allowed_vlans: (optional) The VLAN IDs allowed for `vlan`
               interfaces using this PCI interface.
               If this bare metal server has network attachments, this network interface
               is a
               [read-only
               representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
               of its corresponding network attachment and its attached virtual network
               interface, and the VLAN IDs match the `allow_vlans` of the corresponding
               network attachment.
        :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`.
               If this bare metal server has network attachments, this network interface
               is a
               [read-only
               representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
               of its corresponding network attachment and its attached virtual network
               interface, and infrastructure NAT is managed on the attached virtual
               network interface.
        :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 := _dict.get('allow_ip_spoofing')) is not None:
            args['allow_ip_spoofing'] = allow_ip_spoofing
        if (allowed_vlans := _dict.get('allowed_vlans')) is not None:
            args['allowed_vlans'] = allowed_vlans
        if (enable_infrastructure_nat := _dict.get('enable_infrastructure_nat')) is not None:
            args['enable_infrastructure_nat'] = enable_infrastructure_nat
        if (interface_type := _dict.get('interface_type')) is not None:
            args['interface_type'] = interface_type
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        if (primary_ip := _dict.get('primary_ip')) is not None:
            args['primary_ip'] = primary_ip
        if (security_groups := _dict.get('security_groups')) is not None:
            args['security_groups'] = security_groups
        if (subnet := _dict.get('subnet')) is not None:
            args['subnet'] = 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.

    :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: The disks for a bare metal server
          with this profile.
    :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 BareMetalServerProfileNetworkAttachmentCount network_attachment_count:
    :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.
    :param BareMetalServerProfileVirtualNetworkInterfacesSupported
          virtual_network_interfaces_supported: Indicates whether this profile supports
          virtual network interfaces.
    """

    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_attachment_count: 'BareMetalServerProfileNetworkAttachmentCount',
        network_interface_count: 'BareMetalServerProfileNetworkInterfaceCount',
        os_architecture: 'BareMetalServerProfileOSArchitecture',
        resource_type: str,
        supported_trusted_platform_module_modes: 'BareMetalServerProfileSupportedTrustedPlatformModuleModes',
        virtual_network_interfaces_supported: 'BareMetalServerProfileVirtualNetworkInterfacesSupported',
    ) -> 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: The disks for a bare metal
               server with this profile.
        :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 BareMetalServerProfileNetworkAttachmentCount
               network_attachment_count:
        :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.
        :param BareMetalServerProfileVirtualNetworkInterfacesSupported
               virtual_network_interfaces_supported: Indicates whether this profile
               supports virtual network interfaces.
        """
        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_attachment_count = network_attachment_count
        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
        self.virtual_network_interfaces_supported = virtual_network_interfaces_supported

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'BareMetalServerProfile':
        """Initialize a BareMetalServerProfile object from a json dictionary."""
        args = {}
        if (bandwidth := _dict.get('bandwidth')) is not None:
            args['bandwidth'] = bandwidth
        else:
            raise ValueError('Required property \'bandwidth\' not present in BareMetalServerProfile JSON')
        if (console_types := _dict.get('console_types')) is not None:
            args['console_types'] = BareMetalServerProfileConsoleTypes.from_dict(console_types)
        else:
            raise ValueError('Required property \'console_types\' not present in BareMetalServerProfile JSON')
        if (cpu_architecture := _dict.get('cpu_architecture')) is not None:
            args['cpu_architecture'] = BareMetalServerProfileCPUArchitecture.from_dict(cpu_architecture)
        else:
            raise ValueError('Required property \'cpu_architecture\' not present in BareMetalServerProfile JSON')
        if (cpu_core_count := _dict.get('cpu_core_count')) is not None:
            args['cpu_core_count'] = cpu_core_count
        else:
            raise ValueError('Required property \'cpu_core_count\' not present in BareMetalServerProfile JSON')
        if (cpu_socket_count := _dict.get('cpu_socket_count')) is not None:
            args['cpu_socket_count'] = cpu_socket_count
        else:
            raise ValueError('Required property \'cpu_socket_count\' not present in BareMetalServerProfile JSON')
        if (disks := _dict.get('disks')) is not None:
            args['disks'] = [BareMetalServerProfileDisk.from_dict(v) for v in disks]
        else:
            raise ValueError('Required property \'disks\' not present in BareMetalServerProfile JSON')
        if (family := _dict.get('family')) is not None:
            args['family'] = family
        else:
            raise ValueError('Required property \'family\' not present in BareMetalServerProfile JSON')
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in BareMetalServerProfile JSON')
        if (memory := _dict.get('memory')) is not None:
            args['memory'] = memory
        else:
            raise ValueError('Required property \'memory\' not present in BareMetalServerProfile JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in BareMetalServerProfile JSON')
        if (network_attachment_count := _dict.get('network_attachment_count')) is not None:
            args['network_attachment_count'] = network_attachment_count
        else:
            raise ValueError('Required property \'network_attachment_count\' not present in BareMetalServerProfile JSON')
        if (network_interface_count := _dict.get('network_interface_count')) is not None:
            args['network_interface_count'] = network_interface_count
        else:
            raise ValueError('Required property \'network_interface_count\' not present in BareMetalServerProfile JSON')
        if (os_architecture := _dict.get('os_architecture')) is not None:
            args['os_architecture'] = BareMetalServerProfileOSArchitecture.from_dict(os_architecture)
        else:
            raise ValueError('Required property \'os_architecture\' not present in BareMetalServerProfile JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = resource_type
        else:
            raise ValueError('Required property \'resource_type\' not present in BareMetalServerProfile JSON')
        if (supported_trusted_platform_module_modes := _dict.get('supported_trusted_platform_module_modes')) is not None:
            args['supported_trusted_platform_module_modes'] = BareMetalServerProfileSupportedTrustedPlatformModuleModes.from_dict(supported_trusted_platform_module_modes)
        else:
            raise ValueError('Required property \'supported_trusted_platform_module_modes\' not present in BareMetalServerProfile JSON')
        if (virtual_network_interfaces_supported := _dict.get('virtual_network_interfaces_supported')) is not None:
            args['virtual_network_interfaces_supported'] = BareMetalServerProfileVirtualNetworkInterfacesSupported.from_dict(virtual_network_interfaces_supported)
        else:
            raise ValueError('Required property \'virtual_network_interfaces_supported\' 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_attachment_count') and self.network_attachment_count is not None:
            if isinstance(self.network_attachment_count, dict):
                _dict['network_attachment_count'] = self.network_attachment_count
            else:
                _dict['network_attachment_count'] = self.network_attachment_count.to_dict()
        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()
        if hasattr(self, 'virtual_network_interfaces_supported') and self.virtual_network_interfaces_supported is not None:
            if isinstance(self.virtual_network_interfaces_supported, dict):
                _dict['virtual_network_interfaces_supported'] = self.virtual_network_interfaces_supported
            else:
                _dict['virtual_network_interfaces_supported'] = self.virtual_network_interfaces_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 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.

    :param str default: (optional) The default CPU architecture for a bare metal
          server with this profile.
    :param str type: The type for this profile field.
    :param str value: The CPU architecture for a bare metal server with this
          profile.
    """

    def __init__(
        self,
        type: str,
        value: str,
        *,
        default: Optional[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 := _dict.get('default')) is not None:
            args['default'] = default
        if (type := _dict.get('type')) is not None:
            args['type'] = type
        else:
            raise ValueError('Required property \'type\' not present in BareMetalServerProfileCPUArchitecture JSON')
        if (value := _dict.get('value')) is not None:
            args['value'] = 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.

    :param PageLink 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 PageLink next: (optional) A link to the next page of resources. This
          property is present for all pages
          except the last page.
    :param List[BareMetalServerProfile] profiles: A page of bare metal server
          profiles.
    :param int total_count: The total number of resources across all pages.
    """

    def __init__(
        self,
        first: 'PageLink',
        limit: int,
        profiles: List['BareMetalServerProfile'],
        total_count: int,
        *,
        next: Optional['PageLink'] = None,
    ) -> None:
        """
        Initialize a BareMetalServerProfileCollection object.

        :param PageLink 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: A page of bare metal server
               profiles.
        :param int total_count: The total number of resources across all pages.
        :param PageLink 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 := _dict.get('first')) is not None:
            args['first'] = PageLink.from_dict(first)
        else:
            raise ValueError('Required property \'first\' not present in BareMetalServerProfileCollection JSON')
        if (limit := _dict.get('limit')) is not None:
            args['limit'] = limit
        else:
            raise ValueError('Required property \'limit\' not present in BareMetalServerProfileCollection JSON')
        if (next := _dict.get('next')) is not None:
            args['next'] = PageLink.from_dict(next)
        if (profiles := _dict.get('profiles')) is not None:
            args['profiles'] = [BareMetalServerProfile.from_dict(v) for v in profiles]
        else:
            raise ValueError('Required property \'profiles\' not present in BareMetalServerProfileCollection JSON')
        if (total_count := _dict.get('total_count')) is not None:
            args['total_count'] = 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 BareMetalServerProfileConsoleTypes:
    """
    The console type configuration for a bare metal server with this profile.

    :param str type: The type for this profile field.
    :param 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 := _dict.get('type')) is not None:
            args['type'] = type
        else:
            raise ValueError('Required property \'type\' not present in BareMetalServerProfileConsoleTypes JSON')
        if (values := _dict.get('values')) is not None:
            args['values'] = 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.

    :param BareMetalServerProfileDiskQuantity quantity:
    :param BareMetalServerProfileDiskSize size:
    :param 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 := _dict.get('quantity')) is not None:
            args['quantity'] = quantity
        else:
            raise ValueError('Required property \'quantity\' not present in BareMetalServerProfileDisk JSON')
        if (size := _dict.get('size')) is not None:
            args['size'] = size
        else:
            raise ValueError('Required property \'size\' not present in BareMetalServerProfileDisk JSON')
        if (supported_interface_types := _dict.get('supported_interface_types')) is not None:
            args['supported_interface_types'] = BareMetalServerProfileDiskSupportedInterfaces.from_dict(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.

    :param str default: The default value for this profile field.
    :param str type: The type for this profile field.
    :param 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 default value for this profile field.
        :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 := _dict.get('default')) is not None:
            args['default'] = default
        else:
            raise ValueError('Required property \'default\' not present in BareMetalServerProfileDiskSupportedInterfaces JSON')
        if (type := _dict.get('type')) is not None:
            args['type'] = type
        else:
            raise ValueError('Required property \'type\' not present in BareMetalServerProfileDiskSupportedInterfaces JSON')
        if (values := _dict.get('values')) is not None:
            args['values'] = 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 default value for this profile field.
        """

        FCP = 'fcp'
        NVME = 'nvme'
        SATA = 'sata'


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

        ENUM = 'enum'


    class ValuesEnum(str, Enum):
        """
        The disk attachment interface used:
        - `fcp`: Fiber Channel Protocol
        - `sata`: Serial Advanced Technology Attachment
        - `nvme`: Non-Volatile Memory Express
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        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 BareMetalServerProfileNetworkAttachmentCount:
    """
    BareMetalServerProfileNetworkAttachmentCount.

    """

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

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['BareMetalServerProfileNetworkAttachmentCountRange', 'BareMetalServerProfileNetworkAttachmentCountDependent'])
        )
        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.

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

    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 := _dict.get('default')) is not None:
            args['default'] = default
        else:
            raise ValueError('Required property \'default\' not present in BareMetalServerProfileOSArchitecture JSON')
        if (type := _dict.get('type')) is not None:
            args['type'] = type
        else:
            raise ValueError('Required property \'type\' not present in BareMetalServerProfileOSArchitecture JSON')
        if (values := _dict.get('values')) is not None:
            args['values'] = 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.

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

    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 := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in BareMetalServerProfileReference JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in BareMetalServerProfileReference JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = 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.

    :param str default: (optional) The default trusted platform module for a bare
          metal server with this profile.
    :param str type: The type for this profile field.
    :param List[str] values: The supported trusted platform module modes.
    """

    def __init__(
        self,
        type: str,
        values: List[str],
        *,
        default: Optional[str] = None,
    ) -> None:
        """
        Initialize a BareMetalServerProfileSupportedTrustedPlatformModuleModes object.

        :param str type: The type for this profile field.
        :param List[str] values: The supported trusted platform module modes.
        :param str default: (optional) The default trusted platform module for a
               bare metal server with this profile.
        """
        self.default = default
        self.type = type
        self.values = values

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'BareMetalServerProfileSupportedTrustedPlatformModuleModes':
        """Initialize a BareMetalServerProfileSupportedTrustedPlatformModuleModes object from a json dictionary."""
        args = {}
        if (default := _dict.get('default')) is not None:
            args['default'] = default
        if (type := _dict.get('type')) is not None:
            args['type'] = type
        else:
            raise ValueError('Required property \'type\' not present in BareMetalServerProfileSupportedTrustedPlatformModuleModes JSON')
        if (values := _dict.get('values')) is not None:
            args['values'] = 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, '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 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 DefaultEnum(str, Enum):
        """
        The default trusted platform module for a bare metal server with this profile.
        """

        DISABLED = 'disabled'
        TPM_2 = 'tpm_2'


    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 may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        DISABLED = 'disabled'
        TPM_2 = 'tpm_2'



class BareMetalServerProfileVirtualNetworkInterfacesSupported:
    """
    Indicates whether this profile supports virtual network interfaces.

    :param str type: The type for this profile field.
    :param bool value: The value for this profile field.
    """

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

        :param str type: The type for this profile field.
        :param bool value: The value for this profile field.
        """
        self.type = type
        self.value = value

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

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

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

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

    :param int bandwidth: (optional) The total bandwidth (in megabits per second)
          shared across the bare metal server's network interfaces. The specified value
          must match one of the bandwidth values in the bare metal server's profile. If
          unspecified, the default value from the profile will be used.
    :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 BareMetalServerInitializationPrototype initialization:
    :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 BareMetalServerProfileIdentity profile: The
          [profile](https://cloud.ibm.com/docs/vpc?topic=vpc-bare-metal-servers-profile)
          to use for this bare metal 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 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 attachments
          or
          network interfaces of the bare metal server are attached to.
    :param ZoneIdentity zone: The zone this bare metal server will reside in.
    """

    def __init__(
        self,
        initialization: 'BareMetalServerInitializationPrototype',
        profile: 'BareMetalServerProfileIdentity',
        zone: 'ZoneIdentity',
        *,
        bandwidth: Optional[int] = None,
        enable_secure_boot: Optional[bool] = None,
        name: Optional[str] = None,
        resource_group: Optional['ResourceGroupIdentity'] = None,
        trusted_platform_module: Optional['BareMetalServerTrustedPlatformModulePrototype'] = None,
        vpc: Optional['VPCIdentity'] = None,
    ) -> None:
        """
        Initialize a BareMetalServerPrototype object.

        :param BareMetalServerInitializationPrototype initialization:
        :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 int bandwidth: (optional) The total bandwidth (in megabits per
               second) shared across the bare metal server's network interfaces. The
               specified value must match one of the bandwidth values in the bare metal
               server's profile. If unspecified, the default value from the profile will
               be used.
        :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 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
               attachments or
               network interfaces of the bare metal server are attached to.
        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['BareMetalServerPrototypeBareMetalServerByNetworkAttachment', 'BareMetalServerPrototypeBareMetalServerByNetworkInterface'])
        )
        raise Exception(msg)


class BareMetalServerStatusReason:
    """
    BareMetalServerStatusReason.

    :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
          - `cannot_update_firmware`: An error occurred while updating bare metal server
          firmware
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :param str message: An explanation of the status reason.
    :param str more_info: (optional) Link to documentation about this status reason.
    """

    def __init__(
        self,
        code: str,
        message: str,
        *,
        more_info: Optional[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
               - `cannot_update_firmware`: An error occurred while updating bare metal
               server firmware
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :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 := _dict.get('code')) is not None:
            args['code'] = code
        else:
            raise ValueError('Required property \'code\' not present in BareMetalServerStatusReason JSON')
        if (message := _dict.get('message')) is not None:
            args['message'] = message
        else:
            raise ValueError('Required property \'message\' not present in BareMetalServerStatusReason JSON')
        if (more_info := _dict.get('more_info')) is not None:
            args['more_info'] = 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_update_firmware`: An error occurred while updating bare metal server
        firmware
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        CANNOT_REINITIALIZE = 'cannot_reinitialize'
        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_UPDATE_FIRMWARE = 'cannot_update_firmware'



class BareMetalServerTrustedPlatformModule:
    """
    BareMetalServerTrustedPlatformModule.

    :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 may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :param 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 may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :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 := _dict.get('enabled')) is not None:
            args['enabled'] = enabled
        else:
            raise ValueError('Required property \'enabled\' not present in BareMetalServerTrustedPlatformModule JSON')
        if (mode := _dict.get('mode')) is not None:
            args['mode'] = mode
        else:
            raise ValueError('Required property \'mode\' not present in BareMetalServerTrustedPlatformModule JSON')
        if (supported_modes := _dict.get('supported_modes')) is not None:
            args['supported_modes'] = 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 may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        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 may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        DISABLED = 'disabled'
        TPM_2 = 'tpm_2'



class BareMetalServerTrustedPlatformModulePatch:
    """
    BareMetalServerTrustedPlatformModulePatch.

    :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`.
    """

    def __init__(
        self,
        *,
        mode: Optional[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 := _dict.get('mode')) is not None:
            args['mode'] = 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.

    :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`.
          If unspecified, the default trusted platform module mode from the profile will
          be used.
    """

    def __init__(
        self,
        *,
        mode: Optional[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`.
               If unspecified, the default trusted platform module mode from the profile
               will be used.
        """
        self.mode = mode

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'BareMetalServerTrustedPlatformModulePrototype':
        """Initialize a BareMetalServerTrustedPlatformModulePrototype object from a json dictionary."""
        args = {}
        if (mode := _dict.get('mode')) is not None:
            args['mode'] = 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`.
        If unspecified, the default trusted platform module mode from the profile will be
        used.
        """

        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 CatalogOfferingVersionPlanIdentity:
    """
    Identifies a catalog offering version's billing plan by a unique property.

    """

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

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


class CatalogOfferingVersionPlanReference:
    """
    CatalogOfferingVersionPlanReference.

    :param str crn: The CRN for this
          [catalog](https://cloud.ibm.com/docs/account?topic=account-restrict-by-user)
          offering version's billing plan.
    :param Deleted deleted: (optional) If present, this property indicates the
          referenced resource has been deleted, and provides
          some supplementary information.
    """

    def __init__(
        self,
        crn: str,
        *,
        deleted: Optional['Deleted'] = None,
    ) -> None:
        """
        Initialize a CatalogOfferingVersionPlanReference object.

        :param str crn: The CRN for this
               [catalog](https://cloud.ibm.com/docs/account?topic=account-restrict-by-user)
               offering version's billing plan.
        :param Deleted deleted: (optional) If present, this property indicates the
               referenced resource has been deleted, and provides
               some supplementary information.
        """
        self.crn = crn
        self.deleted = deleted

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

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

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

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

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

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


class CatalogOfferingVersionReference:
    """
    CatalogOfferingVersionReference.

    :param 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 := _dict.get('crn')) is not None:
            args['crn'] = 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.

    :param 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 := _dict.get('crn')) is not None:
            args['crn'] = 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.

    :param str crn: The CRN of this Cloud Object Storage bucket.
    :param 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 := _dict.get('crn')) is not None:
            args['crn'] = crn
        else:
            raise ValueError('Required property \'crn\' not present in CloudObjectStorageBucketReference JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = 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.

    :param 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 := _dict.get('name')) is not None:
            args['name'] = 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 ClusterNetwork:
    """
    ClusterNetwork.

    :param datetime created_at: The date and time that the cluster network was
          created.
    :param str crn: The CRN for this cluster network.
    :param str href: The URL for this cluster network.
    :param str id: The unique identifier for this cluster network.
    :param List[ClusterNetworkLifecycleReason] lifecycle_reasons: The reasons for
          the current `lifecycle_state` (if any).
    :param str lifecycle_state: The lifecycle state of the cluster network.
    :param str name: The name for this cluster network. The name must not be used by
          another cluster network in the region.
    :param ClusterNetworkProfileReference profile: The profile for this cluster
          network.
    :param ResourceGroupReference resource_group: The resource group for this
          cluster network.
    :param str resource_type: The resource type.
    :param List[ClusterNetworkSubnetPrefix] subnet_prefixes: The IP address ranges
          available for subnets for this cluster network.
    :param VPCReference vpc: The VPC this cluster network resides in.
    :param ZoneReference zone: The zone this cluster network resides in.
    """

    def __init__(
        self,
        created_at: datetime,
        crn: str,
        href: str,
        id: str,
        lifecycle_reasons: List['ClusterNetworkLifecycleReason'],
        lifecycle_state: str,
        name: str,
        profile: 'ClusterNetworkProfileReference',
        resource_group: 'ResourceGroupReference',
        resource_type: str,
        subnet_prefixes: List['ClusterNetworkSubnetPrefix'],
        vpc: 'VPCReference',
        zone: 'ZoneReference',
    ) -> None:
        """
        Initialize a ClusterNetwork object.

        :param datetime created_at: The date and time that the cluster network was
               created.
        :param str crn: The CRN for this cluster network.
        :param str href: The URL for this cluster network.
        :param str id: The unique identifier for this cluster network.
        :param List[ClusterNetworkLifecycleReason] lifecycle_reasons: The reasons
               for the current `lifecycle_state` (if any).
        :param str lifecycle_state: The lifecycle state of the cluster network.
        :param str name: The name for this cluster network. The name must not be
               used by another cluster network in the region.
        :param ClusterNetworkProfileReference profile: The profile for this cluster
               network.
        :param ResourceGroupReference resource_group: The resource group for this
               cluster network.
        :param str resource_type: The resource type.
        :param List[ClusterNetworkSubnetPrefix] subnet_prefixes: The IP address
               ranges available for subnets for this cluster network.
        :param VPCReference vpc: The VPC this cluster network resides in.
        :param ZoneReference zone: The zone this cluster network resides in.
        """
        self.created_at = created_at
        self.crn = crn
        self.href = href
        self.id = id
        self.lifecycle_reasons = lifecycle_reasons
        self.lifecycle_state = lifecycle_state
        self.name = name
        self.profile = profile
        self.resource_group = resource_group
        self.resource_type = resource_type
        self.subnet_prefixes = subnet_prefixes
        self.vpc = vpc
        self.zone = zone

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ClusterNetwork':
        """Initialize a ClusterNetwork object from a json dictionary."""
        args = {}
        if (created_at := _dict.get('created_at')) is not None:
            args['created_at'] = string_to_datetime(created_at)
        else:
            raise ValueError('Required property \'created_at\' not present in ClusterNetwork JSON')
        if (crn := _dict.get('crn')) is not None:
            args['crn'] = crn
        else:
            raise ValueError('Required property \'crn\' not present in ClusterNetwork JSON')
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in ClusterNetwork JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in ClusterNetwork JSON')
        if (lifecycle_reasons := _dict.get('lifecycle_reasons')) is not None:
            args['lifecycle_reasons'] = [ClusterNetworkLifecycleReason.from_dict(v) for v in lifecycle_reasons]
        else:
            raise ValueError('Required property \'lifecycle_reasons\' not present in ClusterNetwork JSON')
        if (lifecycle_state := _dict.get('lifecycle_state')) is not None:
            args['lifecycle_state'] = lifecycle_state
        else:
            raise ValueError('Required property \'lifecycle_state\' not present in ClusterNetwork JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in ClusterNetwork JSON')
        if (profile := _dict.get('profile')) is not None:
            args['profile'] = ClusterNetworkProfileReference.from_dict(profile)
        else:
            raise ValueError('Required property \'profile\' not present in ClusterNetwork JSON')
        if (resource_group := _dict.get('resource_group')) is not None:
            args['resource_group'] = ResourceGroupReference.from_dict(resource_group)
        else:
            raise ValueError('Required property \'resource_group\' not present in ClusterNetwork JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = resource_type
        else:
            raise ValueError('Required property \'resource_type\' not present in ClusterNetwork JSON')
        if (subnet_prefixes := _dict.get('subnet_prefixes')) is not None:
            args['subnet_prefixes'] = [ClusterNetworkSubnetPrefix.from_dict(v) for v in subnet_prefixes]
        else:
            raise ValueError('Required property \'subnet_prefixes\' not present in ClusterNetwork JSON')
        if (vpc := _dict.get('vpc')) is not None:
            args['vpc'] = VPCReference.from_dict(vpc)
        else:
            raise ValueError('Required property \'vpc\' not present in ClusterNetwork JSON')
        if (zone := _dict.get('zone')) is not None:
            args['zone'] = ZoneReference.from_dict(zone)
        else:
            raise ValueError('Required property \'zone\' not present in ClusterNetwork JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ClusterNetwork object from 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_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, '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, 'subnet_prefixes') and self.subnet_prefixes is not None:
            subnet_prefixes_list = []
            for v in self.subnet_prefixes:
                if isinstance(v, dict):
                    subnet_prefixes_list.append(v)
                else:
                    subnet_prefixes_list.append(v.to_dict())
            _dict['subnet_prefixes'] = subnet_prefixes_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 ClusterNetwork object."""
        return json.dumps(self.to_dict(), indent=2)

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

    def __ne__(self, other: 'ClusterNetwork') -> 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 cluster network.
        """

        DELETING = 'deleting'
        FAILED = 'failed'
        PENDING = 'pending'
        STABLE = 'stable'
        SUSPENDED = 'suspended'
        UPDATING = 'updating'
        WAITING = 'waiting'


    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        CLUSTER_NETWORK = 'cluster_network'



class ClusterNetworkCollection:
    """
    ClusterNetworkCollection.

    :param List[ClusterNetwork] cluster_networks: A page of cluster networks.
    :param PageLink 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 PageLink next: (optional) A link to the next page of resources. This
          property is present for all pages
          except the last page.
    :param int total_count: The total number of resources across all pages.
    """

    def __init__(
        self,
        cluster_networks: List['ClusterNetwork'],
        first: 'PageLink',
        limit: int,
        total_count: int,
        *,
        next: Optional['PageLink'] = None,
    ) -> None:
        """
        Initialize a ClusterNetworkCollection object.

        :param List[ClusterNetwork] cluster_networks: A page of cluster networks.
        :param PageLink 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 PageLink next: (optional) A link to the next page of resources. This
               property is present for all pages
               except the last page.
        """
        self.cluster_networks = cluster_networks
        self.first = first
        self.limit = limit
        self.next = next
        self.total_count = total_count

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ClusterNetworkCollection':
        """Initialize a ClusterNetworkCollection object from a json dictionary."""
        args = {}
        if (cluster_networks := _dict.get('cluster_networks')) is not None:
            args['cluster_networks'] = [ClusterNetwork.from_dict(v) for v in cluster_networks]
        else:
            raise ValueError('Required property \'cluster_networks\' not present in ClusterNetworkCollection JSON')
        if (first := _dict.get('first')) is not None:
            args['first'] = PageLink.from_dict(first)
        else:
            raise ValueError('Required property \'first\' not present in ClusterNetworkCollection JSON')
        if (limit := _dict.get('limit')) is not None:
            args['limit'] = limit
        else:
            raise ValueError('Required property \'limit\' not present in ClusterNetworkCollection JSON')
        if (next := _dict.get('next')) is not None:
            args['next'] = PageLink.from_dict(next)
        if (total_count := _dict.get('total_count')) is not None:
            args['total_count'] = total_count
        else:
            raise ValueError('Required property \'total_count\' not present in ClusterNetworkCollection JSON')
        return cls(**args)

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

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'cluster_networks') and self.cluster_networks is not None:
            cluster_networks_list = []
            for v in self.cluster_networks:
                if isinstance(v, dict):
                    cluster_networks_list.append(v)
                else:
                    cluster_networks_list.append(v.to_dict())
            _dict['cluster_networks'] = cluster_networks_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 ClusterNetworkCollection object."""
        return json.dumps(self.to_dict(), indent=2)

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

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


class ClusterNetworkInterface:
    """
    The associated cluster network subnet.

    :param bool allow_ip_spoofing: Indicates whether source IP spoofing is allowed
          on this cluster network interface. If `false`, source IP spoofing is prevented
          on this cluster network interface. If `true`, source IP spoofing is allowed on
          this cluster network interface.
    :param bool auto_delete: Indicates whether this cluster network interface will
          be automatically deleted when `target` is deleted.
    :param datetime created_at: The date and time that the cluster 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 virtual network interface,
            allowing the workload to perform any needed NAT operations.
    :param str href: The URL for this cluster network interface.
    :param str id: The unique identifier for this cluster network interface.
    :param List[ClusterNetworkInterfaceLifecycleReason] lifecycle_reasons: The
          reasons for the current `lifecycle_state` (if any).
    :param str lifecycle_state: The lifecycle state of the cluster network
          interface.
    :param str mac_address: (optional) The MAC address of the cluster network
          interface. May be absent if
          `lifecycle_state` is `pending`.
    :param str name: The name for this cluster network interface. The name is unique
          across all interfaces in the cluster network.
    :param ClusterNetworkSubnetReservedIPReference primary_ip: The cluster network
          subnet reserved IP for this cluster network interface.
    :param str resource_type: The resource type.
    :param ClusterNetworkSubnetReference subnet: (optional)
    :param ClusterNetworkInterfaceTarget target: (optional) The target of this
          cluster network interface.
          If absent, this cluster network interface is not attached to a target.
          The resources supported by this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :param VPCReference vpc: The VPC this cluster network interface resides in.
    :param ZoneReference zone: The zone this cluster network interface resides in.
    """

    def __init__(
        self,
        allow_ip_spoofing: bool,
        auto_delete: bool,
        created_at: datetime,
        enable_infrastructure_nat: bool,
        href: str,
        id: str,
        lifecycle_reasons: List['ClusterNetworkInterfaceLifecycleReason'],
        lifecycle_state: str,
        name: str,
        primary_ip: 'ClusterNetworkSubnetReservedIPReference',
        resource_type: str,
        vpc: 'VPCReference',
        zone: 'ZoneReference',
        *,
        mac_address: Optional[str] = None,
        subnet: Optional['ClusterNetworkSubnetReference'] = None,
        target: Optional['ClusterNetworkInterfaceTarget'] = None,
    ) -> None:
        """
        Initialize a ClusterNetworkInterface object.

        :param bool allow_ip_spoofing: Indicates whether source IP spoofing is
               allowed on this cluster network interface. If `false`, source IP spoofing
               is prevented on this cluster network interface. If `true`, source IP
               spoofing is allowed on this cluster network interface.
        :param bool auto_delete: Indicates whether this cluster network interface
               will be automatically deleted when `target` is deleted.
        :param datetime created_at: The date and time that the cluster 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 virtual network interface,
                 allowing the workload to perform any needed NAT operations.
        :param str href: The URL for this cluster network interface.
        :param str id: The unique identifier for this cluster network interface.
        :param List[ClusterNetworkInterfaceLifecycleReason] lifecycle_reasons: The
               reasons for the current `lifecycle_state` (if any).
        :param str lifecycle_state: The lifecycle state of the cluster network
               interface.
        :param str name: The name for this cluster network interface. The name is
               unique across all interfaces in the cluster network.
        :param ClusterNetworkSubnetReservedIPReference primary_ip: The cluster
               network subnet reserved IP for this cluster network interface.
        :param str resource_type: The resource type.
        :param VPCReference vpc: The VPC this cluster network interface resides in.
        :param ZoneReference zone: The zone this cluster network interface resides
               in.
        :param str mac_address: (optional) The MAC address of the cluster network
               interface. May be absent if
               `lifecycle_state` is `pending`.
        :param ClusterNetworkSubnetReference subnet: (optional)
        :param ClusterNetworkInterfaceTarget target: (optional) The target of this
               cluster network interface.
               If absent, this cluster network interface is not attached to a target.
               The resources supported by this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        """
        self.allow_ip_spoofing = allow_ip_spoofing
        self.auto_delete = auto_delete
        self.created_at = created_at
        self.enable_infrastructure_nat = enable_infrastructure_nat
        self.href = href
        self.id = id
        self.lifecycle_reasons = lifecycle_reasons
        self.lifecycle_state = lifecycle_state
        self.mac_address = mac_address
        self.name = name
        self.primary_ip = primary_ip
        self.resource_type = resource_type
        self.subnet = subnet
        self.target = target
        self.vpc = vpc
        self.zone = zone

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ClusterNetworkInterface':
        """Initialize a ClusterNetworkInterface object from a json dictionary."""
        args = {}
        if (allow_ip_spoofing := _dict.get('allow_ip_spoofing')) is not None:
            args['allow_ip_spoofing'] = allow_ip_spoofing
        else:
            raise ValueError('Required property \'allow_ip_spoofing\' not present in ClusterNetworkInterface JSON')
        if (auto_delete := _dict.get('auto_delete')) is not None:
            args['auto_delete'] = auto_delete
        else:
            raise ValueError('Required property \'auto_delete\' not present in ClusterNetworkInterface JSON')
        if (created_at := _dict.get('created_at')) is not None:
            args['created_at'] = string_to_datetime(created_at)
        else:
            raise ValueError('Required property \'created_at\' not present in ClusterNetworkInterface JSON')
        if (enable_infrastructure_nat := _dict.get('enable_infrastructure_nat')) is not None:
            args['enable_infrastructure_nat'] = enable_infrastructure_nat
        else:
            raise ValueError('Required property \'enable_infrastructure_nat\' not present in ClusterNetworkInterface JSON')
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in ClusterNetworkInterface JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in ClusterNetworkInterface JSON')
        if (lifecycle_reasons := _dict.get('lifecycle_reasons')) is not None:
            args['lifecycle_reasons'] = [ClusterNetworkInterfaceLifecycleReason.from_dict(v) for v in lifecycle_reasons]
        else:
            raise ValueError('Required property \'lifecycle_reasons\' not present in ClusterNetworkInterface JSON')
        if (lifecycle_state := _dict.get('lifecycle_state')) is not None:
            args['lifecycle_state'] = lifecycle_state
        else:
            raise ValueError('Required property \'lifecycle_state\' not present in ClusterNetworkInterface JSON')
        if (mac_address := _dict.get('mac_address')) is not None:
            args['mac_address'] = mac_address
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in ClusterNetworkInterface JSON')
        if (primary_ip := _dict.get('primary_ip')) is not None:
            args['primary_ip'] = ClusterNetworkSubnetReservedIPReference.from_dict(primary_ip)
        else:
            raise ValueError('Required property \'primary_ip\' not present in ClusterNetworkInterface JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = resource_type
        else:
            raise ValueError('Required property \'resource_type\' not present in ClusterNetworkInterface JSON')
        if (subnet := _dict.get('subnet')) is not None:
            args['subnet'] = ClusterNetworkSubnetReference.from_dict(subnet)
        if (target := _dict.get('target')) is not None:
            args['target'] = target
        if (vpc := _dict.get('vpc')) is not None:
            args['vpc'] = VPCReference.from_dict(vpc)
        else:
            raise ValueError('Required property \'vpc\' not present in ClusterNetworkInterface JSON')
        if (zone := _dict.get('zone')) is not None:
            args['zone'] = ZoneReference.from_dict(zone)
        else:
            raise ValueError('Required property \'zone\' not present in ClusterNetworkInterface JSON')
        return cls(**args)

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

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

    def __ne__(self, other: 'ClusterNetworkInterface') -> 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 cluster network interface.
        """

        DELETING = 'deleting'
        FAILED = 'failed'
        PENDING = 'pending'
        STABLE = 'stable'
        SUSPENDED = 'suspended'
        UPDATING = 'updating'
        WAITING = 'waiting'


    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        CLUSTER_NETWORK_INTERFACE = 'cluster_network_interface'



class ClusterNetworkInterfaceCollection:
    """
    ClusterNetworkInterfaceCollection.

    :param PageLink first: A link to the first page of resources.
    :param List[ClusterNetworkInterface] interfaces: A page of cluster network
          interfaces.
    :param int limit: The maximum number of resources that can be returned by the
          request.
    :param PageLink next: (optional) A link to the next page of resources. This
          property is present for all pages
          except the last page.
    :param int total_count: The total number of resources across all pages.
    """

    def __init__(
        self,
        first: 'PageLink',
        interfaces: List['ClusterNetworkInterface'],
        limit: int,
        total_count: int,
        *,
        next: Optional['PageLink'] = None,
    ) -> None:
        """
        Initialize a ClusterNetworkInterfaceCollection object.

        :param PageLink first: A link to the first page of resources.
        :param List[ClusterNetworkInterface] interfaces: A page of cluster network
               interfaces.
        :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 PageLink 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.interfaces = interfaces
        self.limit = limit
        self.next = next
        self.total_count = total_count

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ClusterNetworkInterfaceCollection':
        """Initialize a ClusterNetworkInterfaceCollection object from a json dictionary."""
        args = {}
        if (first := _dict.get('first')) is not None:
            args['first'] = PageLink.from_dict(first)
        else:
            raise ValueError('Required property \'first\' not present in ClusterNetworkInterfaceCollection JSON')
        if (interfaces := _dict.get('interfaces')) is not None:
            args['interfaces'] = [ClusterNetworkInterface.from_dict(v) for v in interfaces]
        else:
            raise ValueError('Required property \'interfaces\' not present in ClusterNetworkInterfaceCollection JSON')
        if (limit := _dict.get('limit')) is not None:
            args['limit'] = limit
        else:
            raise ValueError('Required property \'limit\' not present in ClusterNetworkInterfaceCollection JSON')
        if (next := _dict.get('next')) is not None:
            args['next'] = PageLink.from_dict(next)
        if (total_count := _dict.get('total_count')) is not None:
            args['total_count'] = total_count
        else:
            raise ValueError('Required property \'total_count\' not present in ClusterNetworkInterfaceCollection JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ClusterNetworkInterfaceCollection object from 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, 'interfaces') and self.interfaces is not None:
            interfaces_list = []
            for v in self.interfaces:
                if isinstance(v, dict):
                    interfaces_list.append(v)
                else:
                    interfaces_list.append(v.to_dict())
            _dict['interfaces'] = interfaces_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 ClusterNetworkInterfaceCollection object."""
        return json.dumps(self.to_dict(), indent=2)

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

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


class ClusterNetworkInterfaceLifecycleReason:
    """
    ClusterNetworkInterfaceLifecycleReason.

    :param str code: A reason code for this lifecycle state:
          - `internal_error`: internal error (contact IBM support)
          - `resource_suspended_by_provider`: The resource has been suspended (contact IBM
            support)
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :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.
    """

    def __init__(
        self,
        code: str,
        message: str,
        *,
        more_info: Optional[str] = None,
    ) -> None:
        """
        Initialize a ClusterNetworkInterfaceLifecycleReason object.

        :param str code: A reason code for this lifecycle state:
               - `internal_error`: internal error (contact IBM support)
               - `resource_suspended_by_provider`: The resource has been suspended
               (contact IBM
                 support)
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :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) -> 'ClusterNetworkInterfaceLifecycleReason':
        """Initialize a ClusterNetworkInterfaceLifecycleReason object from a json dictionary."""
        args = {}
        if (code := _dict.get('code')) is not None:
            args['code'] = code
        else:
            raise ValueError('Required property \'code\' not present in ClusterNetworkInterfaceLifecycleReason JSON')
        if (message := _dict.get('message')) is not None:
            args['message'] = message
        else:
            raise ValueError('Required property \'message\' not present in ClusterNetworkInterfaceLifecycleReason JSON')
        if (more_info := _dict.get('more_info')) is not None:
            args['more_info'] = more_info
        return cls(**args)

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

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

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

    class CodeEnum(str, Enum):
        """
        A reason code for this lifecycle state:
        - `internal_error`: internal error (contact IBM support)
        - `resource_suspended_by_provider`: The resource has been suspended (contact IBM
          support)
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        INTERNAL_ERROR = 'internal_error'
        RESOURCE_SUSPENDED_BY_PROVIDER = 'resource_suspended_by_provider'



class ClusterNetworkInterfacePatch:
    """
    ClusterNetworkInterfacePatch.

    :param bool auto_delete: (optional) Indicates whether this cluster network
          interface will be automatically deleted when `target` is deleted. Must be
          `false` if the cluster network interface is unbound.
    :param str name: (optional) The name for this cluster network interface. The
          name must not be used by another interface in the cluster network. Names
          beginning with `ibm-` are reserved for provider-owned resources, and are not
          allowed.
    """

    def __init__(
        self,
        *,
        auto_delete: Optional[bool] = None,
        name: Optional[str] = None,
    ) -> None:
        """
        Initialize a ClusterNetworkInterfacePatch object.

        :param bool auto_delete: (optional) Indicates whether this cluster network
               interface will be automatically deleted when `target` is deleted. Must be
               `false` if the cluster network interface is unbound.
        :param str name: (optional) The name for this cluster network interface.
               The name must not be used by another interface in the cluster network.
               Names beginning 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) -> 'ClusterNetworkInterfacePatch':
        """Initialize a ClusterNetworkInterfacePatch object from a json dictionary."""
        args = {}
        if (auto_delete := _dict.get('auto_delete')) is not None:
            args['auto_delete'] = auto_delete
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        return cls(**args)

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

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

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


class ClusterNetworkInterfacePrimaryIPPrototype:
    """
    ClusterNetworkInterfacePrimaryIPPrototype.

    """

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

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


class ClusterNetworkInterfaceReference:
    """
    The associated cluster network subnet.

    :param Deleted deleted: (optional) If present, this property indicates the
          referenced resource has been deleted, and provides
          some supplementary information.
    :param str href: The URL for this cluster network interface.
    :param str id: The unique identifier for this cluster network interface.
    :param str name: The name for this cluster network interface. The name is unique
          across all interfaces in the cluster network.
    :param ClusterNetworkSubnetReservedIPReference primary_ip: The primary IP for
          this cluster network interface.
    :param str resource_type: The resource type.
    :param ClusterNetworkSubnetReference subnet:
    """

    def __init__(
        self,
        href: str,
        id: str,
        name: str,
        primary_ip: 'ClusterNetworkSubnetReservedIPReference',
        resource_type: str,
        subnet: 'ClusterNetworkSubnetReference',
        *,
        deleted: Optional['Deleted'] = None,
    ) -> None:
        """
        Initialize a ClusterNetworkInterfaceReference object.

        :param str href: The URL for this cluster network interface.
        :param str id: The unique identifier for this cluster network interface.
        :param str name: The name for this cluster network interface. The name is
               unique across all interfaces in the cluster network.
        :param ClusterNetworkSubnetReservedIPReference primary_ip: The primary IP
               for this cluster network interface.
        :param str resource_type: The resource type.
        :param ClusterNetworkSubnetReference subnet:
        :param Deleted 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) -> 'ClusterNetworkInterfaceReference':
        """Initialize a ClusterNetworkInterfaceReference object from a json dictionary."""
        args = {}
        if (deleted := _dict.get('deleted')) is not None:
            args['deleted'] = Deleted.from_dict(deleted)
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in ClusterNetworkInterfaceReference JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in ClusterNetworkInterfaceReference JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in ClusterNetworkInterfaceReference JSON')
        if (primary_ip := _dict.get('primary_ip')) is not None:
            args['primary_ip'] = ClusterNetworkSubnetReservedIPReference.from_dict(primary_ip)
        else:
            raise ValueError('Required property \'primary_ip\' not present in ClusterNetworkInterfaceReference JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = resource_type
        else:
            raise ValueError('Required property \'resource_type\' not present in ClusterNetworkInterfaceReference JSON')
        if (subnet := _dict.get('subnet')) is not None:
            args['subnet'] = ClusterNetworkSubnetReference.from_dict(subnet)
        else:
            raise ValueError('Required property \'subnet\' not present in ClusterNetworkInterfaceReference JSON')
        return cls(**args)

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

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

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

    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        CLUSTER_NETWORK_INTERFACE = 'cluster_network_interface'



class ClusterNetworkInterfaceTarget:
    """
    The target of this cluster network interface.
    If absent, this cluster network interface is not attached to a target.
    The resources supported by this property may
    [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the future.

    """

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

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


class ClusterNetworkLifecycleReason:
    """
    ClusterNetworkLifecycleReason.

    :param str code: A reason code for this lifecycle state:
          - `internal_error`: internal error (contact IBM support)
          - `resource_suspended_by_provider`: The resource has been suspended (contact IBM
            support)
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :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.
    """

    def __init__(
        self,
        code: str,
        message: str,
        *,
        more_info: Optional[str] = None,
    ) -> None:
        """
        Initialize a ClusterNetworkLifecycleReason object.

        :param str code: A reason code for this lifecycle state:
               - `internal_error`: internal error (contact IBM support)
               - `resource_suspended_by_provider`: The resource has been suspended
               (contact IBM
                 support)
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :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) -> 'ClusterNetworkLifecycleReason':
        """Initialize a ClusterNetworkLifecycleReason object from a json dictionary."""
        args = {}
        if (code := _dict.get('code')) is not None:
            args['code'] = code
        else:
            raise ValueError('Required property \'code\' not present in ClusterNetworkLifecycleReason JSON')
        if (message := _dict.get('message')) is not None:
            args['message'] = message
        else:
            raise ValueError('Required property \'message\' not present in ClusterNetworkLifecycleReason JSON')
        if (more_info := _dict.get('more_info')) is not None:
            args['more_info'] = more_info
        return cls(**args)

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

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

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

    class CodeEnum(str, Enum):
        """
        A reason code for this lifecycle state:
        - `internal_error`: internal error (contact IBM support)
        - `resource_suspended_by_provider`: The resource has been suspended (contact IBM
          support)
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        INTERNAL_ERROR = 'internal_error'
        RESOURCE_SUSPENDED_BY_PROVIDER = 'resource_suspended_by_provider'



class ClusterNetworkPatch:
    """
    ClusterNetworkPatch.

    :param str name: (optional) The name for this cluster network. The name must not
          be used by another cluster network in the region. Names starting with `ibm-` are
          reserved for provider-owned resources, and are not allowed.
    """

    def __init__(
        self,
        *,
        name: Optional[str] = None,
    ) -> None:
        """
        Initialize a ClusterNetworkPatch object.

        :param str name: (optional) The name for this cluster network. The name
               must not be used by another cluster network in the region. Names starting
               with `ibm-` are reserved for provider-owned resources, and are not allowed.
        """
        self.name = name

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

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

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

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


class ClusterNetworkProfile:
    """
    ClusterNetworkProfile.

    :param str family: The product family this cluster network profile belongs to.
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :param str href: The URL for this cluster network profile.
    :param str name: The globally unique name for this cluster network profile.
    :param str resource_type: The resource type.
    :param List[InstanceProfileReference] supported_instance_profiles: The instance
          profiles that support this cluster network profile.
    :param List[ZoneReference] zones: Zones in this region that support this cluster
          network profile.
    """

    def __init__(
        self,
        family: str,
        href: str,
        name: str,
        resource_type: str,
        supported_instance_profiles: List['InstanceProfileReference'],
        zones: List['ZoneReference'],
    ) -> None:
        """
        Initialize a ClusterNetworkProfile object.

        :param str family: The product family this cluster network profile belongs
               to.
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :param str href: The URL for this cluster network profile.
        :param str name: The globally unique name for this cluster network profile.
        :param str resource_type: The resource type.
        :param List[InstanceProfileReference] supported_instance_profiles: The
               instance profiles that support this cluster network profile.
        :param List[ZoneReference] zones: Zones in this region that support this
               cluster network profile.
        """
        self.family = family
        self.href = href
        self.name = name
        self.resource_type = resource_type
        self.supported_instance_profiles = supported_instance_profiles
        self.zones = zones

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ClusterNetworkProfile':
        """Initialize a ClusterNetworkProfile object from a json dictionary."""
        args = {}
        if (family := _dict.get('family')) is not None:
            args['family'] = family
        else:
            raise ValueError('Required property \'family\' not present in ClusterNetworkProfile JSON')
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in ClusterNetworkProfile JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in ClusterNetworkProfile JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = resource_type
        else:
            raise ValueError('Required property \'resource_type\' not present in ClusterNetworkProfile JSON')
        if (supported_instance_profiles := _dict.get('supported_instance_profiles')) is not None:
            args['supported_instance_profiles'] = [InstanceProfileReference.from_dict(v) for v in supported_instance_profiles]
        else:
            raise ValueError('Required property \'supported_instance_profiles\' not present in ClusterNetworkProfile JSON')
        if (zones := _dict.get('zones')) is not None:
            args['zones'] = [ZoneReference.from_dict(v) for v in zones]
        else:
            raise ValueError('Required property \'zones\' not present in ClusterNetworkProfile JSON')
        return cls(**args)

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

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

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

    class FamilyEnum(str, Enum):
        """
        The product family this cluster network profile belongs to.
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        VELA = 'vela'


    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        CLUSTER_NETWORK_PROFILE = 'cluster_network_profile'



class ClusterNetworkProfileCollection:
    """
    ClusterNetworkProfileCollection.

    :param PageLink 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 PageLink next: (optional) A link to the next page of resources. This
          property is present for all pages
          except the last page.
    :param List[ClusterNetworkProfile] profiles: A page of cluster network profiles.
    :param int total_count: The total number of resources across all pages.
    """

    def __init__(
        self,
        first: 'PageLink',
        limit: int,
        profiles: List['ClusterNetworkProfile'],
        total_count: int,
        *,
        next: Optional['PageLink'] = None,
    ) -> None:
        """
        Initialize a ClusterNetworkProfileCollection object.

        :param PageLink 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[ClusterNetworkProfile] profiles: A page of cluster network
               profiles.
        :param int total_count: The total number of resources across all pages.
        :param PageLink 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) -> 'ClusterNetworkProfileCollection':
        """Initialize a ClusterNetworkProfileCollection object from a json dictionary."""
        args = {}
        if (first := _dict.get('first')) is not None:
            args['first'] = PageLink.from_dict(first)
        else:
            raise ValueError('Required property \'first\' not present in ClusterNetworkProfileCollection JSON')
        if (limit := _dict.get('limit')) is not None:
            args['limit'] = limit
        else:
            raise ValueError('Required property \'limit\' not present in ClusterNetworkProfileCollection JSON')
        if (next := _dict.get('next')) is not None:
            args['next'] = PageLink.from_dict(next)
        if (profiles := _dict.get('profiles')) is not None:
            args['profiles'] = [ClusterNetworkProfile.from_dict(v) for v in profiles]
        else:
            raise ValueError('Required property \'profiles\' not present in ClusterNetworkProfileCollection JSON')
        if (total_count := _dict.get('total_count')) is not None:
            args['total_count'] = total_count
        else:
            raise ValueError('Required property \'total_count\' not present in ClusterNetworkProfileCollection JSON')
        return cls(**args)

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

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

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


class ClusterNetworkProfileIdentity:
    """
    Identifies an cluster network profile by a unique property.

    """

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

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


class ClusterNetworkProfileReference:
    """
    ClusterNetworkProfileReference.

    :param str href: The URL for this cluster network profile.
    :param str name: The globally unique name for this cluster network profile.
    :param str resource_type: The resource type.
    """

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

        :param str href: The URL for this cluster network profile.
        :param str name: The globally unique name for this cluster network 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) -> 'ClusterNetworkProfileReference':
        """Initialize a ClusterNetworkProfileReference object from a json dictionary."""
        args = {}
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in ClusterNetworkProfileReference JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in ClusterNetworkProfileReference JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = resource_type
        else:
            raise ValueError('Required property \'resource_type\' not present in ClusterNetworkProfileReference JSON')
        return cls(**args)

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

    def to_dict(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 ClusterNetworkProfileReference object."""
        return json.dumps(self.to_dict(), indent=2)

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

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

    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        CLUSTER_NETWORK_PROFILE = 'cluster_network_profile'



class ClusterNetworkReference:
    """
    ClusterNetworkReference.

    :param str crn: The CRN for this cluster network.
    :param Deleted deleted: (optional) If present, this property indicates the
          referenced resource has been deleted, and provides
          some supplementary information.
    :param str href: The URL for this cluster network.
    :param str id: The unique identifier for this cluster network.
    :param str name: The name for this cluster network. The name must not be used by
          another cluster network in the region.
    :param str resource_type: The resource type.
    """

    def __init__(
        self,
        crn: str,
        href: str,
        id: str,
        name: str,
        resource_type: str,
        *,
        deleted: Optional['Deleted'] = None,
    ) -> None:
        """
        Initialize a ClusterNetworkReference object.

        :param str crn: The CRN for this cluster network.
        :param str href: The URL for this cluster network.
        :param str id: The unique identifier for this cluster network.
        :param str name: The name for this cluster network. The name must not be
               used by another cluster network in the region.
        :param str resource_type: The resource type.
        :param Deleted 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) -> 'ClusterNetworkReference':
        """Initialize a ClusterNetworkReference object from a json dictionary."""
        args = {}
        if (crn := _dict.get('crn')) is not None:
            args['crn'] = crn
        else:
            raise ValueError('Required property \'crn\' not present in ClusterNetworkReference JSON')
        if (deleted := _dict.get('deleted')) is not None:
            args['deleted'] = Deleted.from_dict(deleted)
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in ClusterNetworkReference JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in ClusterNetworkReference JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in ClusterNetworkReference JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = resource_type
        else:
            raise ValueError('Required property \'resource_type\' not present in ClusterNetworkReference JSON')
        return cls(**args)

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

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

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

    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        CLUSTER_NETWORK = 'cluster_network'



class ClusterNetworkSubnet:
    """
    ClusterNetworkSubnet.

    :param int available_ipv4_address_count: The number of IPv4 addresses in this
          cluster network 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 cluster network subnet
          was created.
    :param str href: The URL for this cluster network subnet.
    :param str id: The unique identifier for this cluster network subnet.
    :param str ip_version: The IP version for this cluster network subnet.
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :param str ipv4_cidr_block: The IPv4 range of this cluster network subnet,
          expressed in CIDR format.
    :param List[ClusterNetworkSubnetLifecycleReason] lifecycle_reasons: The reasons
          for the current `lifecycle_state` (if any).
    :param str lifecycle_state: The lifecycle state of the cluster network subnet.
    :param str name: The name for this cluster network subnet. The name is unique
          across all cluster network subnets in the cluster network.
    :param str resource_type: The resource type.
    :param int total_ipv4_address_count: The total number of IPv4 addresses in this
          cluster network 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.
    """

    def __init__(
        self,
        available_ipv4_address_count: int,
        created_at: datetime,
        href: str,
        id: str,
        ip_version: str,
        ipv4_cidr_block: str,
        lifecycle_reasons: List['ClusterNetworkSubnetLifecycleReason'],
        lifecycle_state: str,
        name: str,
        resource_type: str,
        total_ipv4_address_count: int,
    ) -> None:
        """
        Initialize a ClusterNetworkSubnet object.

        :param int available_ipv4_address_count: The number of IPv4 addresses in
               this cluster network 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 cluster network
               subnet was created.
        :param str href: The URL for this cluster network subnet.
        :param str id: The unique identifier for this cluster network subnet.
        :param str ip_version: The IP version for this cluster network subnet.
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :param str ipv4_cidr_block: The IPv4 range of this cluster network subnet,
               expressed in CIDR format.
        :param List[ClusterNetworkSubnetLifecycleReason] lifecycle_reasons: The
               reasons for the current `lifecycle_state` (if any).
        :param str lifecycle_state: The lifecycle state of the cluster network
               subnet.
        :param str name: The name for this cluster network subnet. The name is
               unique across all cluster network subnets in the cluster network.
        :param str resource_type: The resource type.
        :param int total_ipv4_address_count: The total number of IPv4 addresses in
               this cluster network 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.
        """
        self.available_ipv4_address_count = available_ipv4_address_count
        self.created_at = created_at
        self.href = href
        self.id = id
        self.ip_version = ip_version
        self.ipv4_cidr_block = ipv4_cidr_block
        self.lifecycle_reasons = lifecycle_reasons
        self.lifecycle_state = lifecycle_state
        self.name = name
        self.resource_type = resource_type
        self.total_ipv4_address_count = total_ipv4_address_count

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ClusterNetworkSubnet':
        """Initialize a ClusterNetworkSubnet object from a json dictionary."""
        args = {}
        if (available_ipv4_address_count := _dict.get('available_ipv4_address_count')) is not None:
            args['available_ipv4_address_count'] = available_ipv4_address_count
        else:
            raise ValueError('Required property \'available_ipv4_address_count\' not present in ClusterNetworkSubnet JSON')
        if (created_at := _dict.get('created_at')) is not None:
            args['created_at'] = string_to_datetime(created_at)
        else:
            raise ValueError('Required property \'created_at\' not present in ClusterNetworkSubnet JSON')
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in ClusterNetworkSubnet JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in ClusterNetworkSubnet JSON')
        if (ip_version := _dict.get('ip_version')) is not None:
            args['ip_version'] = ip_version
        else:
            raise ValueError('Required property \'ip_version\' not present in ClusterNetworkSubnet JSON')
        if (ipv4_cidr_block := _dict.get('ipv4_cidr_block')) is not None:
            args['ipv4_cidr_block'] = ipv4_cidr_block
        else:
            raise ValueError('Required property \'ipv4_cidr_block\' not present in ClusterNetworkSubnet JSON')
        if (lifecycle_reasons := _dict.get('lifecycle_reasons')) is not None:
            args['lifecycle_reasons'] = [ClusterNetworkSubnetLifecycleReason.from_dict(v) for v in lifecycle_reasons]
        else:
            raise ValueError('Required property \'lifecycle_reasons\' not present in ClusterNetworkSubnet JSON')
        if (lifecycle_state := _dict.get('lifecycle_state')) is not None:
            args['lifecycle_state'] = lifecycle_state
        else:
            raise ValueError('Required property \'lifecycle_state\' not present in ClusterNetworkSubnet JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in ClusterNetworkSubnet JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = resource_type
        else:
            raise ValueError('Required property \'resource_type\' not present in ClusterNetworkSubnet JSON')
        if (total_ipv4_address_count := _dict.get('total_ipv4_address_count')) is not None:
            args['total_ipv4_address_count'] = total_ipv4_address_count
        else:
            raise ValueError('Required property \'total_ipv4_address_count\' not present in ClusterNetworkSubnet JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ClusterNetworkSubnet object from 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, 'href') and self.href 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, '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
        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
        return _dict

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

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

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

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

    class IpVersionEnum(str, Enum):
        """
        The IP version for this cluster network subnet.
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        IPV4 = 'ipv4'


    class LifecycleStateEnum(str, Enum):
        """
        The lifecycle state of the cluster network subnet.
        """

        DELETING = 'deleting'
        FAILED = 'failed'
        PENDING = 'pending'
        STABLE = 'stable'
        SUSPENDED = 'suspended'
        UPDATING = 'updating'
        WAITING = 'waiting'


    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        CLUSTER_NETWORK_SUBNET = 'cluster_network_subnet'



class ClusterNetworkSubnetCollection:
    """
    ClusterNetworkSubnetCollection.

    :param PageLink 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 PageLink next: (optional) A link to the next page of resources. This
          property is present for all pages
          except the last page.
    :param List[ClusterNetworkSubnet] subnets: A page of subnets for the cluster
          network.
    :param int total_count: The total number of resources across all pages.
    """

    def __init__(
        self,
        first: 'PageLink',
        limit: int,
        subnets: List['ClusterNetworkSubnet'],
        total_count: int,
        *,
        next: Optional['PageLink'] = None,
    ) -> None:
        """
        Initialize a ClusterNetworkSubnetCollection object.

        :param PageLink 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[ClusterNetworkSubnet] subnets: A page of subnets for the
               cluster network.
        :param int total_count: The total number of resources across all pages.
        :param PageLink 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) -> 'ClusterNetworkSubnetCollection':
        """Initialize a ClusterNetworkSubnetCollection object from a json dictionary."""
        args = {}
        if (first := _dict.get('first')) is not None:
            args['first'] = PageLink.from_dict(first)
        else:
            raise ValueError('Required property \'first\' not present in ClusterNetworkSubnetCollection JSON')
        if (limit := _dict.get('limit')) is not None:
            args['limit'] = limit
        else:
            raise ValueError('Required property \'limit\' not present in ClusterNetworkSubnetCollection JSON')
        if (next := _dict.get('next')) is not None:
            args['next'] = PageLink.from_dict(next)
        if (subnets := _dict.get('subnets')) is not None:
            args['subnets'] = [ClusterNetworkSubnet.from_dict(v) for v in subnets]
        else:
            raise ValueError('Required property \'subnets\' not present in ClusterNetworkSubnetCollection JSON')
        if (total_count := _dict.get('total_count')) is not None:
            args['total_count'] = total_count
        else:
            raise ValueError('Required property \'total_count\' not present in ClusterNetworkSubnetCollection JSON')
        return cls(**args)

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

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

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


class ClusterNetworkSubnetIdentity:
    """
    Identifies a cluster network subnet by a unique property.

    """

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

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


class ClusterNetworkSubnetLifecycleReason:
    """
    ClusterNetworkSubnetLifecycleReason.

    :param str code: A reason code for this lifecycle state:
          - `internal_error`: internal error (contact IBM support)
          - `resource_suspended_by_provider`: The resource has been suspended (contact IBM
            support)
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :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.
    """

    def __init__(
        self,
        code: str,
        message: str,
        *,
        more_info: Optional[str] = None,
    ) -> None:
        """
        Initialize a ClusterNetworkSubnetLifecycleReason object.

        :param str code: A reason code for this lifecycle state:
               - `internal_error`: internal error (contact IBM support)
               - `resource_suspended_by_provider`: The resource has been suspended
               (contact IBM
                 support)
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :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) -> 'ClusterNetworkSubnetLifecycleReason':
        """Initialize a ClusterNetworkSubnetLifecycleReason object from a json dictionary."""
        args = {}
        if (code := _dict.get('code')) is not None:
            args['code'] = code
        else:
            raise ValueError('Required property \'code\' not present in ClusterNetworkSubnetLifecycleReason JSON')
        if (message := _dict.get('message')) is not None:
            args['message'] = message
        else:
            raise ValueError('Required property \'message\' not present in ClusterNetworkSubnetLifecycleReason JSON')
        if (more_info := _dict.get('more_info')) is not None:
            args['more_info'] = more_info
        return cls(**args)

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

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

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

    class CodeEnum(str, Enum):
        """
        A reason code for this lifecycle state:
        - `internal_error`: internal error (contact IBM support)
        - `resource_suspended_by_provider`: The resource has been suspended (contact IBM
          support)
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        INTERNAL_ERROR = 'internal_error'
        RESOURCE_SUSPENDED_BY_PROVIDER = 'resource_suspended_by_provider'



class ClusterNetworkSubnetPatch:
    """
    ClusterNetworkSubnetPatch.

    :param str name: (optional) The name for this cluster network subnet. The name
          must not be used by another cluster network subnet in the cluster network. Names
          starting with `ibm-` are reserved for provider-owned resources, and are not
          allowed.
    """

    def __init__(
        self,
        *,
        name: Optional[str] = None,
    ) -> None:
        """
        Initialize a ClusterNetworkSubnetPatch object.

        :param str name: (optional) The name for this cluster network subnet. The
               name must not be used by another cluster network subnet in the cluster
               network. Names starting with `ibm-` are reserved for provider-owned
               resources, and are not allowed.
        """
        self.name = name

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

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

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

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


class ClusterNetworkSubnetPrefix:
    """
    A range of addresses available for subnets for this cluster network.

    :param str allocation_policy: The allocation policy for this subnet prefix:
          - `auto`: Subnets created by total count in this cluster network can use this
          prefix.
    :param str cidr: The CIDR block for this prefix.
    """

    def __init__(
        self,
        allocation_policy: str,
        cidr: str,
    ) -> None:
        """
        Initialize a ClusterNetworkSubnetPrefix object.

        :param str allocation_policy: The allocation policy for this subnet prefix:
               - `auto`: Subnets created by total count in this cluster network can use
               this prefix.
        :param str cidr: The CIDR block for this prefix.
        """
        self.allocation_policy = allocation_policy
        self.cidr = cidr

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

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

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

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

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

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

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

    class AllocationPolicyEnum(str, Enum):
        """
        The allocation policy for this subnet prefix:
        - `auto`: Subnets created by total count in this cluster network can use this
        prefix.
        """

        AUTO = 'auto'



class ClusterNetworkSubnetPrefixPrototype:
    """
    ClusterNetworkSubnetPrefixPrototype.

    :param str cidr: (optional) The IPv4 range of the cluster network's subnet
          prefix, expressed in CIDR format.
          The CIDR prefix length must be less than `/29` (at least 8 addresses).
          If a range is specified that overlaps with address prefixes in the cluster
          network's VPC, the operating systems of any virtual server instances attaching
          to this cluster network must be [configured to avoid
          conflicts](https://cloud.ibm.com/docs/vpc?topic=vpc-planning-cluster-network#advanced-consideration).
    """

    def __init__(
        self,
        *,
        cidr: Optional[str] = None,
    ) -> None:
        """
        Initialize a ClusterNetworkSubnetPrefixPrototype object.

        :param str cidr: (optional) The IPv4 range of the cluster network's subnet
               prefix, expressed in CIDR format.
               The CIDR prefix length must be less than `/29` (at least 8 addresses).
               If a range is specified that overlaps with address prefixes in the cluster
               network's VPC, the operating systems of any virtual server instances
               attaching to this cluster network must be [configured to avoid
               conflicts](https://cloud.ibm.com/docs/vpc?topic=vpc-planning-cluster-network#advanced-consideration).
        """
        self.cidr = cidr

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

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

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

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

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

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


class ClusterNetworkSubnetPrototype:
    """
    ClusterNetworkSubnetPrototype.

    :param str ip_version: (optional) The IP version(s) to support for this cluster
          network subnet.
    :param str name: (optional) The name for this cluster network subnet. The name
          must not be used by another cluster network subnet in the cluster network. 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,
        *,
        ip_version: Optional[str] = None,
        name: Optional[str] = None,
    ) -> None:
        """
        Initialize a ClusterNetworkSubnetPrototype object.

        :param str ip_version: (optional) The IP version(s) to support for this
               cluster network subnet.
        :param str name: (optional) The name for this cluster network subnet. The
               name must not be used by another cluster network subnet in the cluster
               network. 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.
        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['ClusterNetworkSubnetPrototypeClusterNetworkSubnetByTotalCountPrototype', 'ClusterNetworkSubnetPrototypeClusterNetworkSubnetByIPv4CIDRBlockPrototype'])
        )
        raise Exception(msg)

    class IpVersionEnum(str, Enum):
        """
        The IP version(s) to support for this cluster network subnet.
        """

        IPV4 = 'ipv4'



class ClusterNetworkSubnetReference:
    """
    ClusterNetworkSubnetReference.

    :param Deleted deleted: (optional) If present, this property indicates the
          referenced resource has been deleted, and provides
          some supplementary information.
    :param str href: The URL for this cluster network subnet.
    :param str id: The unique identifier for this cluster network subnet.
    :param str name: The name for this cluster network subnet. The name is unique
          across all cluster network subnets in the cluster network.
    :param str resource_type: The resource type.
    """

    def __init__(
        self,
        href: str,
        id: str,
        name: str,
        resource_type: str,
        *,
        deleted: Optional['Deleted'] = None,
    ) -> None:
        """
        Initialize a ClusterNetworkSubnetReference object.

        :param str href: The URL for this cluster network subnet.
        :param str id: The unique identifier for this cluster network subnet.
        :param str name: The name for this cluster network subnet. The name is
               unique across all cluster network subnets in the cluster network.
        :param str resource_type: The resource type.
        :param Deleted 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) -> 'ClusterNetworkSubnetReference':
        """Initialize a ClusterNetworkSubnetReference object from a json dictionary."""
        args = {}
        if (deleted := _dict.get('deleted')) is not None:
            args['deleted'] = Deleted.from_dict(deleted)
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in ClusterNetworkSubnetReference JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in ClusterNetworkSubnetReference JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in ClusterNetworkSubnetReference JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = resource_type
        else:
            raise ValueError('Required property \'resource_type\' not present in ClusterNetworkSubnetReference JSON')
        return cls(**args)

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

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

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

    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        CLUSTER_NETWORK_SUBNET = 'cluster_network_subnet'



class ClusterNetworkSubnetReservedIP:
    """
    ClusterNetworkSubnetReservedIP.

    :param str address: The IP address.
          If the address is pending allocation, the value will be `0.0.0.0`.
          This property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) to support
          IPv6 addresses in the future.
    :param bool auto_delete: Indicates whether this cluster network subnet reserved
          IP member will be automatically deleted when either `target` is deleted, or the
          cluster network subnet reserved IP is unbound.
    :param datetime created_at: The date and time that the cluster network subnet
          reserved IP was created.
    :param str href: The URL for this cluster network subnet reserved IP.
    :param str id: The unique identifier for this cluster network subnet reserved
          IP.
    :param List[ClusterNetworkSubnetReservedIPLifecycleReason] lifecycle_reasons:
          The reasons for the current `lifecycle_state` (if any).
    :param str lifecycle_state: The lifecycle state of the cluster network subnet
          reserved IP.
    :param str name: The name for this cluster network subnet reserved IP. The name
          is unique across all reserved IPs in a cluster network subnet.
    :param str owner: The owner of the cluster network subnet reserved IP
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :param str resource_type: The resource type.
    :param ClusterNetworkSubnetReservedIPTarget target: (optional) The target this
          cluster network subnet reserved IP is bound to.
          If absent, this cluster network subnet reserved IP is provider-owned or unbound.
    """

    def __init__(
        self,
        address: str,
        auto_delete: bool,
        created_at: datetime,
        href: str,
        id: str,
        lifecycle_reasons: List['ClusterNetworkSubnetReservedIPLifecycleReason'],
        lifecycle_state: str,
        name: str,
        owner: str,
        resource_type: str,
        *,
        target: Optional['ClusterNetworkSubnetReservedIPTarget'] = None,
    ) -> None:
        """
        Initialize a ClusterNetworkSubnetReservedIP object.

        :param str address: The IP address.
               If the address is pending allocation, the value will be `0.0.0.0`.
               This property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) to
               support IPv6 addresses in the future.
        :param bool auto_delete: Indicates whether this cluster network subnet
               reserved IP member will be automatically deleted when either `target` is
               deleted, or the cluster network subnet reserved IP is unbound.
        :param datetime created_at: The date and time that the cluster network
               subnet reserved IP was created.
        :param str href: The URL for this cluster network subnet reserved IP.
        :param str id: The unique identifier for this cluster network subnet
               reserved IP.
        :param List[ClusterNetworkSubnetReservedIPLifecycleReason]
               lifecycle_reasons: The reasons for the current `lifecycle_state` (if any).
        :param str lifecycle_state: The lifecycle state of the cluster network
               subnet reserved IP.
        :param str name: The name for this cluster network subnet reserved IP. The
               name is unique across all reserved IPs in a cluster network subnet.
        :param str owner: The owner of the cluster network subnet reserved IP
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :param str resource_type: The resource type.
        :param ClusterNetworkSubnetReservedIPTarget target: (optional) The target
               this cluster network subnet reserved IP is bound to.
               If absent, this cluster network subnet 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_reasons = lifecycle_reasons
        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) -> 'ClusterNetworkSubnetReservedIP':
        """Initialize a ClusterNetworkSubnetReservedIP object from a json dictionary."""
        args = {}
        if (address := _dict.get('address')) is not None:
            args['address'] = address
        else:
            raise ValueError('Required property \'address\' not present in ClusterNetworkSubnetReservedIP JSON')
        if (auto_delete := _dict.get('auto_delete')) is not None:
            args['auto_delete'] = auto_delete
        else:
            raise ValueError('Required property \'auto_delete\' not present in ClusterNetworkSubnetReservedIP JSON')
        if (created_at := _dict.get('created_at')) is not None:
            args['created_at'] = string_to_datetime(created_at)
        else:
            raise ValueError('Required property \'created_at\' not present in ClusterNetworkSubnetReservedIP JSON')
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in ClusterNetworkSubnetReservedIP JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in ClusterNetworkSubnetReservedIP JSON')
        if (lifecycle_reasons := _dict.get('lifecycle_reasons')) is not None:
            args['lifecycle_reasons'] = [ClusterNetworkSubnetReservedIPLifecycleReason.from_dict(v) for v in lifecycle_reasons]
        else:
            raise ValueError('Required property \'lifecycle_reasons\' not present in ClusterNetworkSubnetReservedIP JSON')
        if (lifecycle_state := _dict.get('lifecycle_state')) is not None:
            args['lifecycle_state'] = lifecycle_state
        else:
            raise ValueError('Required property \'lifecycle_state\' not present in ClusterNetworkSubnetReservedIP JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in ClusterNetworkSubnetReservedIP JSON')
        if (owner := _dict.get('owner')) is not None:
            args['owner'] = owner
        else:
            raise ValueError('Required property \'owner\' not present in ClusterNetworkSubnetReservedIP JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = resource_type
        else:
            raise ValueError('Required property \'resource_type\' not present in ClusterNetworkSubnetReservedIP JSON')
        if (target := _dict.get('target')) is not None:
            args['target'] = target
        return cls(**args)

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

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

    def __ne__(self, other: 'ClusterNetworkSubnetReservedIP') -> 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 cluster network subnet reserved IP.
        """

        DELETING = 'deleting'
        FAILED = 'failed'
        PENDING = 'pending'
        STABLE = 'stable'
        SUSPENDED = 'suspended'
        UPDATING = 'updating'
        WAITING = 'waiting'


    class OwnerEnum(str, Enum):
        """
        The owner of the cluster network subnet reserved IP
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        PROVIDER = 'provider'
        USER = 'user'


    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        CLUSTER_NETWORK_SUBNET_RESERVED_IP = 'cluster_network_subnet_reserved_ip'



class ClusterNetworkSubnetReservedIPCollection:
    """
    ClusterNetworkSubnetReservedIPCollection.

    :param PageLink 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 PageLink next: (optional) A link to the next page of resources. This
          property is present for all pages
          except the last page.
    :param List[ClusterNetworkSubnetReservedIP] reserved_ips: A page of reserved IPs
          for the cluster network subnet.
    :param int total_count: The total number of resources across all pages.
    """

    def __init__(
        self,
        first: 'PageLink',
        limit: int,
        reserved_ips: List['ClusterNetworkSubnetReservedIP'],
        total_count: int,
        *,
        next: Optional['PageLink'] = None,
    ) -> None:
        """
        Initialize a ClusterNetworkSubnetReservedIPCollection object.

        :param PageLink 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[ClusterNetworkSubnetReservedIP] reserved_ips: A page of
               reserved IPs for the cluster network subnet.
        :param int total_count: The total number of resources across all pages.
        :param PageLink 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) -> 'ClusterNetworkSubnetReservedIPCollection':
        """Initialize a ClusterNetworkSubnetReservedIPCollection object from a json dictionary."""
        args = {}
        if (first := _dict.get('first')) is not None:
            args['first'] = PageLink.from_dict(first)
        else:
            raise ValueError('Required property \'first\' not present in ClusterNetworkSubnetReservedIPCollection JSON')
        if (limit := _dict.get('limit')) is not None:
            args['limit'] = limit
        else:
            raise ValueError('Required property \'limit\' not present in ClusterNetworkSubnetReservedIPCollection JSON')
        if (next := _dict.get('next')) is not None:
            args['next'] = PageLink.from_dict(next)
        if (reserved_ips := _dict.get('reserved_ips')) is not None:
            args['reserved_ips'] = [ClusterNetworkSubnetReservedIP.from_dict(v) for v in reserved_ips]
        else:
            raise ValueError('Required property \'reserved_ips\' not present in ClusterNetworkSubnetReservedIPCollection JSON')
        if (total_count := _dict.get('total_count')) is not None:
            args['total_count'] = total_count
        else:
            raise ValueError('Required property \'total_count\' not present in ClusterNetworkSubnetReservedIPCollection JSON')
        return cls(**args)

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

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

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


class ClusterNetworkSubnetReservedIPLifecycleReason:
    """
    ClusterNetworkSubnetReservedIPLifecycleReason.

    :param str code: A reason code for this lifecycle state:
          - `internal_error`: internal error (contact IBM support)
          - `resource_suspended_by_provider`: The resource has been suspended (contact IBM
            support)
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :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.
    """

    def __init__(
        self,
        code: str,
        message: str,
        *,
        more_info: Optional[str] = None,
    ) -> None:
        """
        Initialize a ClusterNetworkSubnetReservedIPLifecycleReason object.

        :param str code: A reason code for this lifecycle state:
               - `internal_error`: internal error (contact IBM support)
               - `resource_suspended_by_provider`: The resource has been suspended
               (contact IBM
                 support)
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :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) -> 'ClusterNetworkSubnetReservedIPLifecycleReason':
        """Initialize a ClusterNetworkSubnetReservedIPLifecycleReason object from a json dictionary."""
        args = {}
        if (code := _dict.get('code')) is not None:
            args['code'] = code
        else:
            raise ValueError('Required property \'code\' not present in ClusterNetworkSubnetReservedIPLifecycleReason JSON')
        if (message := _dict.get('message')) is not None:
            args['message'] = message
        else:
            raise ValueError('Required property \'message\' not present in ClusterNetworkSubnetReservedIPLifecycleReason JSON')
        if (more_info := _dict.get('more_info')) is not None:
            args['more_info'] = more_info
        return cls(**args)

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

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

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

    class CodeEnum(str, Enum):
        """
        A reason code for this lifecycle state:
        - `internal_error`: internal error (contact IBM support)
        - `resource_suspended_by_provider`: The resource has been suspended (contact IBM
          support)
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        INTERNAL_ERROR = 'internal_error'
        RESOURCE_SUSPENDED_BY_PROVIDER = 'resource_suspended_by_provider'



class ClusterNetworkSubnetReservedIPPatch:
    """
    ClusterNetworkSubnetReservedIPPatch.

    :param bool auto_delete: (optional) Indicates whether this cluster network
          subnet reserved IP member will be automatically deleted when either `target` is
          deleted, or the cluster network subnet reserved IP is unbound. Must be `false`
          if the cluster network subnet reserved IP is unbound.
    :param str name: (optional) The name for this cluster network subnet reserved
          IP. The name must not be used by another reserved IP in the cluster network
          subnet. Names starting with `ibm-` are reserved for provider-owned resources,
          and are not allowed.
    """

    def __init__(
        self,
        *,
        auto_delete: Optional[bool] = None,
        name: Optional[str] = None,
    ) -> None:
        """
        Initialize a ClusterNetworkSubnetReservedIPPatch object.

        :param bool auto_delete: (optional) Indicates whether this cluster network
               subnet reserved IP member will be automatically deleted when either
               `target` is deleted, or the cluster network subnet reserved IP is unbound.
               Must be `false` if the cluster network subnet reserved IP is unbound.
        :param str name: (optional) The name for this cluster network subnet
               reserved IP. The name must not be used by another reserved IP in the
               cluster network 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) -> 'ClusterNetworkSubnetReservedIPPatch':
        """Initialize a ClusterNetworkSubnetReservedIPPatch object from a json dictionary."""
        args = {}
        if (auto_delete := _dict.get('auto_delete')) is not None:
            args['auto_delete'] = auto_delete
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        return cls(**args)

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

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

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


class ClusterNetworkSubnetReservedIPReference:
    """
    ClusterNetworkSubnetReservedIPReference.

    :param str address: The IP address.
          If the address is pending allocation, the value will be `0.0.0.0`.
          This property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) to support
          IPv6 addresses in the future.
    :param Deleted deleted: (optional) If present, this property indicates the
          referenced resource has been deleted, and provides
          some supplementary information.
    :param str href: The URL for this cluster network subnet reserved IP.
    :param str id: The unique identifier for this cluster network subnet reserved
          IP.
    :param str name: The name for this cluster network subnet reserved IP. The name
          is unique across all reserved IPs in a cluster network subnet.
    :param str resource_type: The resource type.
    """

    def __init__(
        self,
        address: str,
        href: str,
        id: str,
        name: str,
        resource_type: str,
        *,
        deleted: Optional['Deleted'] = None,
    ) -> None:
        """
        Initialize a ClusterNetworkSubnetReservedIPReference object.

        :param str address: The IP address.
               If the address is pending allocation, the value will be `0.0.0.0`.
               This property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) to
               support IPv6 addresses in the future.
        :param str href: The URL for this cluster network subnet reserved IP.
        :param str id: The unique identifier for this cluster network subnet
               reserved IP.
        :param str name: The name for this cluster network subnet reserved IP. The
               name is unique across all reserved IPs in a cluster network subnet.
        :param str resource_type: The resource type.
        :param Deleted 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) -> 'ClusterNetworkSubnetReservedIPReference':
        """Initialize a ClusterNetworkSubnetReservedIPReference object from a json dictionary."""
        args = {}
        if (address := _dict.get('address')) is not None:
            args['address'] = address
        else:
            raise ValueError('Required property \'address\' not present in ClusterNetworkSubnetReservedIPReference JSON')
        if (deleted := _dict.get('deleted')) is not None:
            args['deleted'] = Deleted.from_dict(deleted)
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in ClusterNetworkSubnetReservedIPReference JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in ClusterNetworkSubnetReservedIPReference JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in ClusterNetworkSubnetReservedIPReference JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = resource_type
        else:
            raise ValueError('Required property \'resource_type\' not present in ClusterNetworkSubnetReservedIPReference JSON')
        return cls(**args)

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

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

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

    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        CLUSTER_NETWORK_SUBNET_RESERVED_IP = 'cluster_network_subnet_reserved_ip'



class ClusterNetworkSubnetReservedIPTarget:
    """
    The target this cluster network subnet reserved IP is bound to.
    If absent, this cluster network subnet reserved IP is provider-owned or unbound.

    """

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

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


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 DNSInstanceReferenceLoadBalancerDNSContext:
    """
    DNSInstanceReferenceLoadBalancerDNSContext.

    :param str crn: The CRN for this DNS instance.
    """

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

        :param str crn: The CRN for this DNS instance.
        """
        self.crn = crn

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

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

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

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


class DNSServer:
    """
    A DNS server.

    :param str address: The IP address.
          This property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) to support
          IPv6 addresses in the future.
    :param 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: Optional['ZoneReference'] = None,
    ) -> None:
        """
        Initialize a DNSServer object.

        :param str address: The IP address.
               This property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) to
               support IPv6 addresses in the future.
        :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 := _dict.get('address')) is not None:
            args['address'] = address
        else:
            raise ValueError('Required property \'address\' not present in DNSServer JSON')
        if (zone_affinity := _dict.get('zone_affinity')) is not None:
            args['zone_affinity'] = ZoneReference.from_dict(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.

    :param str address: (optional) The DNS server IPv4 address.
    :param ZoneIdentity zone_affinity: (optional) DHCP configuration for the
          specified zone will have this DNS server listed first.
    """

    def __init__(
        self,
        *,
        address: Optional[str] = None,
        zone_affinity: Optional['ZoneIdentity'] = None,
    ) -> None:
        """
        Initialize a DNSServerPrototype object.

        :param str address: (optional) The DNS server IPv4 address.
        :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 := _dict.get('address')) is not None:
            args['address'] = address
        if (zone_affinity := _dict.get('zone_affinity')) is not None:
            args['zone_affinity'] = 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.

    :param 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 := _dict.get('id')) is not None:
            args['id'] = 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.

    :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: The disks for the dedicated host.
    :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 may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :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.
    """

    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: The disks for the dedicated host.
        :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 may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :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 := _dict.get('available_memory')) is not None:
            args['available_memory'] = available_memory
        else:
            raise ValueError('Required property \'available_memory\' not present in DedicatedHost JSON')
        if (available_vcpu := _dict.get('available_vcpu')) is not None:
            args['available_vcpu'] = VCPU.from_dict(available_vcpu)
        else:
            raise ValueError('Required property \'available_vcpu\' not present in DedicatedHost JSON')
        if (created_at := _dict.get('created_at')) is not None:
            args['created_at'] = string_to_datetime(created_at)
        else:
            raise ValueError('Required property \'created_at\' not present in DedicatedHost JSON')
        if (crn := _dict.get('crn')) is not None:
            args['crn'] = crn
        else:
            raise ValueError('Required property \'crn\' not present in DedicatedHost JSON')
        if (disks := _dict.get('disks')) is not None:
            args['disks'] = [DedicatedHostDisk.from_dict(v) for v in disks]
        else:
            raise ValueError('Required property \'disks\' not present in DedicatedHost JSON')
        if (group := _dict.get('group')) is not None:
            args['group'] = DedicatedHostGroupReference.from_dict(group)
        else:
            raise ValueError('Required property \'group\' not present in DedicatedHost JSON')
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in DedicatedHost JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in DedicatedHost JSON')
        if (instance_placement_enabled := _dict.get('instance_placement_enabled')) is not None:
            args['instance_placement_enabled'] = instance_placement_enabled
        else:
            raise ValueError('Required property \'instance_placement_enabled\' not present in DedicatedHost JSON')
        if (instances := _dict.get('instances')) is not None:
            args['instances'] = [InstanceReference.from_dict(v) for v in instances]
        else:
            raise ValueError('Required property \'instances\' not present in DedicatedHost JSON')
        if (lifecycle_state := _dict.get('lifecycle_state')) is not None:
            args['lifecycle_state'] = lifecycle_state
        else:
            raise ValueError('Required property \'lifecycle_state\' not present in DedicatedHost JSON')
        if (memory := _dict.get('memory')) is not None:
            args['memory'] = memory
        else:
            raise ValueError('Required property \'memory\' not present in DedicatedHost JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in DedicatedHost JSON')
        if (numa := _dict.get('numa')) is not None:
            args['numa'] = DedicatedHostNUMA.from_dict(numa)
        else:
            raise ValueError('Required property \'numa\' not present in DedicatedHost JSON')
        if (profile := _dict.get('profile')) is not None:
            args['profile'] = DedicatedHostProfileReference.from_dict(profile)
        else:
            raise ValueError('Required property \'profile\' not present in DedicatedHost JSON')
        if (provisionable := _dict.get('provisionable')) is not None:
            args['provisionable'] = provisionable
        else:
            raise ValueError('Required property \'provisionable\' not present in DedicatedHost JSON')
        if (resource_group := _dict.get('resource_group')) is not None:
            args['resource_group'] = ResourceGroupReference.from_dict(resource_group)
        else:
            raise ValueError('Required property \'resource_group\' not present in DedicatedHost JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = resource_type
        else:
            raise ValueError('Required property \'resource_type\' not present in DedicatedHost JSON')
        if (socket_count := _dict.get('socket_count')) is not None:
            args['socket_count'] = socket_count
        else:
            raise ValueError('Required property \'socket_count\' not present in DedicatedHost JSON')
        if (state := _dict.get('state')) is not None:
            args['state'] = state
        else:
            raise ValueError('Required property \'state\' not present in DedicatedHost JSON')
        if (supported_instance_profiles := _dict.get('supported_instance_profiles')) is not None:
            args['supported_instance_profiles'] = [InstanceProfileReference.from_dict(v) for v in supported_instance_profiles]
        else:
            raise ValueError('Required property \'supported_instance_profiles\' not present in DedicatedHost JSON')
        if (vcpu := _dict.get('vcpu')) is not None:
            args['vcpu'] = VCPU.from_dict(vcpu)
        else:
            raise ValueError('Required property \'vcpu\' not present in DedicatedHost JSON')
        if (zone := _dict.get('zone')) is not None:
            args['zone'] = ZoneReference.from_dict(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 may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        AVAILABLE = 'available'
        DEGRADED = 'degraded'
        MIGRATING = 'migrating'
        UNAVAILABLE = 'unavailable'



class DedicatedHostCollection:
    """
    DedicatedHostCollection.

    :param List[DedicatedHost] dedicated_hosts: A page of dedicated hosts.
    :param PageLink 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 PageLink next: (optional) A link to the next page of resources. This
          property is present for all pages
          except the last page.
    :param int total_count: The total number of resources across all pages.
    """

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

        :param List[DedicatedHost] dedicated_hosts: A page of dedicated hosts.
        :param PageLink 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 PageLink 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 := _dict.get('dedicated_hosts')) is not None:
            args['dedicated_hosts'] = [DedicatedHost.from_dict(v) for v in dedicated_hosts]
        else:
            raise ValueError('Required property \'dedicated_hosts\' not present in DedicatedHostCollection JSON')
        if (first := _dict.get('first')) is not None:
            args['first'] = PageLink.from_dict(first)
        else:
            raise ValueError('Required property \'first\' not present in DedicatedHostCollection JSON')
        if (limit := _dict.get('limit')) is not None:
            args['limit'] = limit
        else:
            raise ValueError('Required property \'limit\' not present in DedicatedHostCollection JSON')
        if (next := _dict.get('next')) is not None:
            args['next'] = PageLink.from_dict(next)
        if (total_count := _dict.get('total_count')) is not None:
            args['total_count'] = 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 DedicatedHostDisk:
    """
    DedicatedHostDisk.

    :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.
    :param str lifecycle_state: (optional) The lifecycle state of this dedicated
          host disk.
    :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.
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    """

    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: Optional[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.
        :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.
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :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 := _dict.get('available')) is not None:
            args['available'] = available
        else:
            raise ValueError('Required property \'available\' not present in DedicatedHostDisk JSON')
        if (created_at := _dict.get('created_at')) is not None:
            args['created_at'] = string_to_datetime(created_at)
        else:
            raise ValueError('Required property \'created_at\' not present in DedicatedHostDisk JSON')
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in DedicatedHostDisk JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in DedicatedHostDisk JSON')
        if (instance_disks := _dict.get('instance_disks')) is not None:
            args['instance_disks'] = [InstanceDiskReference.from_dict(v) for v in instance_disks]
        else:
            raise ValueError('Required property \'instance_disks\' not present in DedicatedHostDisk JSON')
        if (interface_type := _dict.get('interface_type')) is not None:
            args['interface_type'] = interface_type
        else:
            raise ValueError('Required property \'interface_type\' not present in DedicatedHostDisk JSON')
        if (lifecycle_state := _dict.get('lifecycle_state')) is not None:
            args['lifecycle_state'] = lifecycle_state
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in DedicatedHostDisk JSON')
        if (provisionable := _dict.get('provisionable')) is not None:
            args['provisionable'] = provisionable
        else:
            raise ValueError('Required property \'provisionable\' not present in DedicatedHostDisk JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = resource_type
        else:
            raise ValueError('Required property \'resource_type\' not present in DedicatedHostDisk JSON')
        if (size := _dict.get('size')) is not None:
            args['size'] = size
        else:
            raise ValueError('Required property \'size\' not present in DedicatedHostDisk JSON')
        if (supported_instance_interface_types := _dict.get('supported_instance_interface_types')) is not None:
            args['supported_instance_interface_types'] = 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.
        """

        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 may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        NVME = 'nvme'
        VIRTIO_BLK = 'virtio_blk'



class DedicatedHostDiskCollection:
    """
    DedicatedHostDiskCollection.

    :param List[DedicatedHostDisk] disks: The disks for the dedicated host.
    """

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

        :param List[DedicatedHostDisk] disks: The disks for the dedicated host.
        """
        self.disks = disks

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'DedicatedHostDiskCollection':
        """Initialize a DedicatedHostDiskCollection object from a json dictionary."""
        args = {}
        if (disks := _dict.get('disks')) is not None:
            args['disks'] = [DedicatedHostDisk.from_dict(v) for v in 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.

    :param 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: Optional[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 := _dict.get('name')) is not None:
            args['name'] = 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.

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

    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_ := _dict.get('class')) is not None:
            args['class_'] = class_
        else:
            raise ValueError('Required property \'class\' not present in DedicatedHostGroup JSON')
        if (created_at := _dict.get('created_at')) is not None:
            args['created_at'] = string_to_datetime(created_at)
        else:
            raise ValueError('Required property \'created_at\' not present in DedicatedHostGroup JSON')
        if (crn := _dict.get('crn')) is not None:
            args['crn'] = crn
        else:
            raise ValueError('Required property \'crn\' not present in DedicatedHostGroup JSON')
        if (dedicated_hosts := _dict.get('dedicated_hosts')) is not None:
            args['dedicated_hosts'] = [DedicatedHostReference.from_dict(v) for v in dedicated_hosts]
        else:
            raise ValueError('Required property \'dedicated_hosts\' not present in DedicatedHostGroup JSON')
        if (family := _dict.get('family')) is not None:
            args['family'] = family
        else:
            raise ValueError('Required property \'family\' not present in DedicatedHostGroup JSON')
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in DedicatedHostGroup JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in DedicatedHostGroup JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in DedicatedHostGroup JSON')
        if (resource_group := _dict.get('resource_group')) is not None:
            args['resource_group'] = ResourceGroupReference.from_dict(resource_group)
        else:
            raise ValueError('Required property \'resource_group\' not present in DedicatedHostGroup JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = resource_type
        else:
            raise ValueError('Required property \'resource_type\' not present in DedicatedHostGroup JSON')
        if (supported_instance_profiles := _dict.get('supported_instance_profiles')) is not None:
            args['supported_instance_profiles'] = [InstanceProfileReference.from_dict(v) for v in supported_instance_profiles]
        else:
            raise ValueError('Required property \'supported_instance_profiles\' not present in DedicatedHostGroup JSON')
        if (zone := _dict.get('zone')) is not None:
            args['zone'] = ZoneReference.from_dict(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.

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

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

        :param PageLink first: A link to the first page of resources.
        :param List[DedicatedHostGroup] groups: A page 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 PageLink 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 := _dict.get('first')) is not None:
            args['first'] = PageLink.from_dict(first)
        else:
            raise ValueError('Required property \'first\' not present in DedicatedHostGroupCollection JSON')
        if (groups := _dict.get('groups')) is not None:
            args['groups'] = [DedicatedHostGroup.from_dict(v) for v in groups]
        else:
            raise ValueError('Required property \'groups\' not present in DedicatedHostGroupCollection JSON')
        if (limit := _dict.get('limit')) is not None:
            args['limit'] = limit
        else:
            raise ValueError('Required property \'limit\' not present in DedicatedHostGroupCollection JSON')
        if (next := _dict.get('next')) is not None:
            args['next'] = PageLink.from_dict(next)
        if (total_count := _dict.get('total_count')) is not None:
            args['total_count'] = 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 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.

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

    def __init__(
        self,
        *,
        name: Optional[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 := _dict.get('name')) is not None:
            args['name'] = 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.

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

    def __init__(
        self,
        *,
        name: Optional[str] = None,
        resource_group: Optional['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 := _dict.get('name')) is not None:
            args['name'] = name
        if (resource_group := _dict.get('resource_group')) is not None:
            args['resource_group'] = 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.

    :param str crn: The CRN for this dedicated host group.
    :param Deleted deleted: (optional) If present, this property indicates the
          referenced resource has been deleted, and provides
          some supplementary information.
    :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.
    """

    def __init__(
        self,
        crn: str,
        href: str,
        id: str,
        name: str,
        resource_type: str,
        *,
        deleted: Optional['Deleted'] = 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 Deleted 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 := _dict.get('crn')) is not None:
            args['crn'] = crn
        else:
            raise ValueError('Required property \'crn\' not present in DedicatedHostGroupReference JSON')
        if (deleted := _dict.get('deleted')) is not None:
            args['deleted'] = Deleted.from_dict(deleted)
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in DedicatedHostGroupReference JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in DedicatedHostGroupReference JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in DedicatedHostGroupReference JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = 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 DedicatedHostNUMA:
    """
    The dedicated host NUMA configuration.

    :param int count: The total number of NUMA nodes for this dedicated host.
    :param 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 := _dict.get('count')) is not None:
            args['count'] = count
        else:
            raise ValueError('Required property \'count\' not present in DedicatedHostNUMA JSON')
        if (nodes := _dict.get('nodes')) is not None:
            args['nodes'] = [DedicatedHostNUMANode.from_dict(v) for v in 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.

    :param int available_vcpu: The available VCPU for this NUMA node.
    :param 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 := _dict.get('available_vcpu')) is not None:
            args['available_vcpu'] = available_vcpu
        else:
            raise ValueError('Required property \'available_vcpu\' not present in DedicatedHostNUMANode JSON')
        if (vcpu := _dict.get('vcpu')) is not None:
            args['vcpu'] = 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.

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

    def __init__(
        self,
        *,
        instance_placement_enabled: Optional[bool] = None,
        name: Optional[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 := _dict.get('instance_placement_enabled')) is not None:
            args['instance_placement_enabled'] = instance_placement_enabled
        if (name := _dict.get('name')) is not None:
            args['name'] = 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.

    :param str class_: The product class this dedicated host profile belongs to.
    :param List[DedicatedHostProfileDisk] disks: The disks for a dedicated host with
          this profile.
    :param str family: The product family this dedicated host profile belongs to
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :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 dedicated host profile is the latest revision.
          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 may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :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:
    """

    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: The disks for a dedicated host
               with this profile.
        :param str family: The product family this dedicated host profile belongs
               to
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :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 dedicated host profile is the latest revision.
               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 may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :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_ := _dict.get('class')) is not None:
            args['class_'] = class_
        else:
            raise ValueError('Required property \'class\' not present in DedicatedHostProfile JSON')
        if (disks := _dict.get('disks')) is not None:
            args['disks'] = [DedicatedHostProfileDisk.from_dict(v) for v in disks]
        else:
            raise ValueError('Required property \'disks\' not present in DedicatedHostProfile JSON')
        if (family := _dict.get('family')) is not None:
            args['family'] = family
        else:
            raise ValueError('Required property \'family\' not present in DedicatedHostProfile JSON')
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in DedicatedHostProfile JSON')
        if (memory := _dict.get('memory')) is not None:
            args['memory'] = memory
        else:
            raise ValueError('Required property \'memory\' not present in DedicatedHostProfile JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in DedicatedHostProfile JSON')
        if (socket_count := _dict.get('socket_count')) is not None:
            args['socket_count'] = socket_count
        else:
            raise ValueError('Required property \'socket_count\' not present in DedicatedHostProfile JSON')
        if (status := _dict.get('status')) is not None:
            args['status'] = status
        else:
            raise ValueError('Required property \'status\' not present in DedicatedHostProfile JSON')
        if (supported_instance_profiles := _dict.get('supported_instance_profiles')) is not None:
            args['supported_instance_profiles'] = [InstanceProfileReference.from_dict(v) for v in supported_instance_profiles]
        else:
            raise ValueError('Required property \'supported_instance_profiles\' not present in DedicatedHostProfile JSON')
        if (vcpu_architecture := _dict.get('vcpu_architecture')) is not None:
            args['vcpu_architecture'] = DedicatedHostProfileVCPUArchitecture.from_dict(vcpu_architecture)
        else:
            raise ValueError('Required property \'vcpu_architecture\' not present in DedicatedHostProfile JSON')
        if (vcpu_count := _dict.get('vcpu_count')) is not None:
            args['vcpu_count'] = vcpu_count
        else:
            raise ValueError('Required property \'vcpu_count\' not present in DedicatedHostProfile JSON')
        if (vcpu_manufacturer := _dict.get('vcpu_manufacturer')) is not None:
            args['vcpu_manufacturer'] = DedicatedHostProfileVCPUManufacturer.from_dict(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 may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        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 dedicated host profile is the latest revision.
        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 may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        CURRENT = 'current'
        PREVIOUS = 'previous'



class DedicatedHostProfileCollection:
    """
    DedicatedHostProfileCollection.

    :param PageLink 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 PageLink next: (optional) A link to the next page of resources. This
          property is present for all pages
          except the last page.
    :param List[DedicatedHostProfile] profiles: A page of dedicated host profiles.
    :param int total_count: The total number of resources across all pages.
    """

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

        :param PageLink 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: A page of dedicated host
               profiles.
        :param int total_count: The total number of resources across all pages.
        :param PageLink 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 := _dict.get('first')) is not None:
            args['first'] = PageLink.from_dict(first)
        else:
            raise ValueError('Required property \'first\' not present in DedicatedHostProfileCollection JSON')
        if (limit := _dict.get('limit')) is not None:
            args['limit'] = limit
        else:
            raise ValueError('Required property \'limit\' not present in DedicatedHostProfileCollection JSON')
        if (next := _dict.get('next')) is not None:
            args['next'] = PageLink.from_dict(next)
        if (profiles := _dict.get('profiles')) is not None:
            args['profiles'] = [DedicatedHostProfile.from_dict(v) for v in profiles]
        else:
            raise ValueError('Required property \'profiles\' not present in DedicatedHostProfileCollection JSON')
        if (total_count := _dict.get('total_count')) is not None:
            args['total_count'] = 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 DedicatedHostProfileDisk:
    """
    Disks provided by this profile.

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

    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 := _dict.get('interface_type')) is not None:
            args['interface_type'] = DedicatedHostProfileDiskInterface.from_dict(interface_type)
        else:
            raise ValueError('Required property \'interface_type\' not present in DedicatedHostProfileDisk JSON')
        if (quantity := _dict.get('quantity')) is not None:
            args['quantity'] = DedicatedHostProfileDiskQuantity.from_dict(quantity)
        else:
            raise ValueError('Required property \'quantity\' not present in DedicatedHostProfileDisk JSON')
        if (size := _dict.get('size')) is not None:
            args['size'] = DedicatedHostProfileDiskSize.from_dict(size)
        else:
            raise ValueError('Required property \'size\' not present in DedicatedHostProfileDisk JSON')
        if (supported_instance_interface_types := _dict.get('supported_instance_interface_types')) is not None:
            args['supported_instance_interface_types'] = DedicatedHostProfileDiskSupportedInterfaces.from_dict(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.

    :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 may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    """

    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 may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        """
        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 := _dict.get('type')) is not None:
            args['type'] = type
        else:
            raise ValueError('Required property \'type\' not present in DedicatedHostProfileDiskInterface JSON')
        if (value := _dict.get('value')) is not None:
            args['value'] = 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 may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        NVME = 'nvme'



class DedicatedHostProfileDiskQuantity:
    """
    The number of disks of this type for a dedicated host with this profile.

    :param str type: The type for this profile field.
    :param 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 := _dict.get('type')) is not None:
            args['type'] = type
        else:
            raise ValueError('Required property \'type\' not present in DedicatedHostProfileDiskQuantity JSON')
        if (value := _dict.get('value')) is not None:
            args['value'] = 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).

    :param str type: The type for this profile field.
    :param 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 := _dict.get('type')) is not None:
            args['type'] = type
        else:
            raise ValueError('Required property \'type\' not present in DedicatedHostProfileDiskSize JSON')
        if (value := _dict.get('value')) is not None:
            args['value'] = 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.

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

    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 := _dict.get('type')) is not None:
            args['type'] = type
        else:
            raise ValueError('Required property \'type\' not present in DedicatedHostProfileDiskSupportedInterfaces JSON')
        if (value := _dict.get('value')) is not None:
            args['value'] = 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 may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        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.

    :param str href: The URL for this dedicated host.
    :param 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 := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in DedicatedHostProfileReference JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = 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.

    :param str type: The type for this profile field.
    :param 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 := _dict.get('type')) is not None:
            args['type'] = type
        else:
            raise ValueError('Required property \'type\' not present in DedicatedHostProfileVCPUArchitecture JSON')
        if (value := _dict.get('value')) is not None:
            args['value'] = 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.

    :param str type: The type for this profile field.
    :param 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 := _dict.get('type')) is not None:
            args['type'] = type
        else:
            raise ValueError('Required property \'type\' not present in DedicatedHostProfileVCPUManufacturer JSON')
        if (value := _dict.get('value')) is not None:
            args['value'] = 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.

    :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 DedicatedHostProfileIdentity profile: The
          [profile](https://cloud.ibm.com/docs/vpc?topic=vpc-dh-profiles) to use for this
          dedicated host.
    :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.
    """

    def __init__(
        self,
        profile: 'DedicatedHostProfileIdentity',
        *,
        instance_placement_enabled: Optional[bool] = None,
        name: Optional[str] = None,
        resource_group: Optional['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.

    :param str crn: The CRN for this dedicated host.
    :param Deleted deleted: (optional) If present, this property indicates the
          referenced resource has been deleted, and provides
          some supplementary information.
    :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.
    """

    def __init__(
        self,
        crn: str,
        href: str,
        id: str,
        name: str,
        resource_type: str,
        *,
        deleted: Optional['Deleted'] = 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 Deleted 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 := _dict.get('crn')) is not None:
            args['crn'] = crn
        else:
            raise ValueError('Required property \'crn\' not present in DedicatedHostReference JSON')
        if (deleted := _dict.get('deleted')) is not None:
            args['deleted'] = Deleted.from_dict(deleted)
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in DedicatedHostReference JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in DedicatedHostReference JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in DedicatedHostReference JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = 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 DefaultNetworkACL:
    """
    DefaultNetworkACL.

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

    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 := _dict.get('created_at')) is not None:
            args['created_at'] = string_to_datetime(created_at)
        else:
            raise ValueError('Required property \'created_at\' not present in DefaultNetworkACL JSON')
        if (crn := _dict.get('crn')) is not None:
            args['crn'] = crn
        else:
            raise ValueError('Required property \'crn\' not present in DefaultNetworkACL JSON')
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in DefaultNetworkACL JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in DefaultNetworkACL JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in DefaultNetworkACL JSON')
        if (resource_group := _dict.get('resource_group')) is not None:
            args['resource_group'] = ResourceGroupReference.from_dict(resource_group)
        else:
            raise ValueError('Required property \'resource_group\' not present in DefaultNetworkACL JSON')
        if (rules := _dict.get('rules')) is not None:
            args['rules'] = [NetworkACLRuleItem.from_dict(v) for v in rules]
        else:
            raise ValueError('Required property \'rules\' not present in DefaultNetworkACL JSON')
        if (subnets := _dict.get('subnets')) is not None:
            args['subnets'] = [SubnetReference.from_dict(v) for v in subnets]
        else:
            raise ValueError('Required property \'subnets\' not present in DefaultNetworkACL JSON')
        if (vpc := _dict.get('vpc')) is not None:
            args['vpc'] = VPCReference.from_dict(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.

    :param List[ResourceFilter] accept_routes_from: The filters specifying the
          resources that may create routes in this routing table.
          The resources and types of filters supported by this property is expected to
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :param List[str] advertise_routes_to: The ingress sources to advertise routes
          to. Routes in the table with `advertise` enabled will be advertised to these
          sources.
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :param datetime created_at: The date and time that this routing table was
          created.
    :param str crn: The CRN for this VPC routing table.
    :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 ResourceGroupReference resource_group: The resource group for this
          routing table.
    :param str resource_type: The resource type.
    :param bool route_direct_link_ingress: Indicates whether this routing table is
          used to route traffic that originates from
          [Direct Link](https://cloud.ibm.com/docs/dl) to this VPC.
          Incoming traffic will be routed according to the routing table with one
          exception: routes with an `action` of `deliver` are treated as `drop` unless the
          `next_hop` is an IP address 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.
    """

    def __init__(
        self,
        accept_routes_from: List['ResourceFilter'],
        advertise_routes_to: List[str],
        created_at: datetime,
        crn: str,
        href: str,
        id: str,
        is_default: bool,
        lifecycle_state: str,
        name: str,
        resource_group: 'ResourceGroupReference',
        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.
               The resources and types of filters supported by this property is expected
               to
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :param List[str] advertise_routes_to: The ingress sources to advertise
               routes to. Routes in the table with `advertise` enabled will be advertised
               to these sources.
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :param datetime created_at: The date and time that this routing table was
               created.
        :param str crn: The CRN for this VPC routing table.
        :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 ResourceGroupReference resource_group: The resource group for this
               routing table.
        :param str resource_type: The resource type.
        :param bool route_direct_link_ingress: Indicates whether this routing table
               is used to route traffic that originates from
               [Direct Link](https://cloud.ibm.com/docs/dl) to this VPC.
               Incoming traffic will be routed according to the routing table with one
               exception: routes with an `action` of `deliver` are treated as `drop`
               unless the `next_hop` is an IP address 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.advertise_routes_to = advertise_routes_to
        self.created_at = created_at
        self.crn = crn
        self.href = href
        self.id = id
        self.is_default = is_default
        self.lifecycle_state = lifecycle_state
        self.name = name
        self.resource_group = resource_group
        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 := _dict.get('accept_routes_from')) is not None:
            args['accept_routes_from'] = [ResourceFilter.from_dict(v) for v in accept_routes_from]
        else:
            raise ValueError('Required property \'accept_routes_from\' not present in DefaultRoutingTable JSON')
        if (advertise_routes_to := _dict.get('advertise_routes_to')) is not None:
            args['advertise_routes_to'] = advertise_routes_to
        else:
            raise ValueError('Required property \'advertise_routes_to\' not present in DefaultRoutingTable JSON')
        if (created_at := _dict.get('created_at')) is not None:
            args['created_at'] = string_to_datetime(created_at)
        else:
            raise ValueError('Required property \'created_at\' not present in DefaultRoutingTable JSON')
        if (crn := _dict.get('crn')) is not None:
            args['crn'] = crn
        else:
            raise ValueError('Required property \'crn\' not present in DefaultRoutingTable JSON')
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in DefaultRoutingTable JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in DefaultRoutingTable JSON')
        if (is_default := _dict.get('is_default')) is not None:
            args['is_default'] = is_default
        else:
            raise ValueError('Required property \'is_default\' not present in DefaultRoutingTable JSON')
        if (lifecycle_state := _dict.get('lifecycle_state')) is not None:
            args['lifecycle_state'] = lifecycle_state
        else:
            raise ValueError('Required property \'lifecycle_state\' not present in DefaultRoutingTable JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in DefaultRoutingTable JSON')
        if (resource_group := _dict.get('resource_group')) is not None:
            args['resource_group'] = ResourceGroupReference.from_dict(resource_group)
        else:
            raise ValueError('Required property \'resource_group\' not present in DefaultRoutingTable JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = resource_type
        else:
            raise ValueError('Required property \'resource_type\' not present in DefaultRoutingTable JSON')
        if (route_direct_link_ingress := _dict.get('route_direct_link_ingress')) is not None:
            args['route_direct_link_ingress'] = route_direct_link_ingress
        else:
            raise ValueError('Required property \'route_direct_link_ingress\' not present in DefaultRoutingTable JSON')
        if (route_internet_ingress := _dict.get('route_internet_ingress')) is not None:
            args['route_internet_ingress'] = route_internet_ingress
        else:
            raise ValueError('Required property \'route_internet_ingress\' not present in DefaultRoutingTable JSON')
        if (route_transit_gateway_ingress := _dict.get('route_transit_gateway_ingress')) is not None:
            args['route_transit_gateway_ingress'] = route_transit_gateway_ingress
        else:
            raise ValueError('Required property \'route_transit_gateway_ingress\' not present in DefaultRoutingTable JSON')
        if (route_vpc_zone_ingress := _dict.get('route_vpc_zone_ingress')) is not None:
            args['route_vpc_zone_ingress'] = route_vpc_zone_ingress
        else:
            raise ValueError('Required property \'route_vpc_zone_ingress\' not present in DefaultRoutingTable JSON')
        if (routes := _dict.get('routes')) is not None:
            args['routes'] = [RouteReference.from_dict(v) for v in routes]
        else:
            raise ValueError('Required property \'routes\' not present in DefaultRoutingTable JSON')
        if (subnets := _dict.get('subnets')) is not None:
            args['subnets'] = [SubnetReference.from_dict(v) for v in 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, 'advertise_routes_to') and self.advertise_routes_to is not None:
            _dict['advertise_routes_to'] = self.advertise_routes_to
        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, '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_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_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 AdvertiseRoutesToEnum(str, Enum):
        """
        An ingress source that routes can be advertised to:
        - `direct_link` (requires `route_direct_link_ingress` be set to `true`)
        - `transit_gateway` (requires `route_transit_gateway_ingress` be set to `true`).
        """

        DIRECT_LINK = 'direct_link'
        TRANSIT_GATEWAY = 'transit_gateway'


    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.

    :param datetime created_at: The date and time that this security group was
          created.
    :param str crn: The CRN for this security group.
    :param str href: The URL for this security group.
    :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.
    """

    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 CRN for this security group.
        :param str href: The URL for this security group.
        :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 := _dict.get('created_at')) is not None:
            args['created_at'] = string_to_datetime(created_at)
        else:
            raise ValueError('Required property \'created_at\' not present in DefaultSecurityGroup JSON')
        if (crn := _dict.get('crn')) is not None:
            args['crn'] = crn
        else:
            raise ValueError('Required property \'crn\' not present in DefaultSecurityGroup JSON')
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in DefaultSecurityGroup JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in DefaultSecurityGroup JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in DefaultSecurityGroup JSON')
        if (resource_group := _dict.get('resource_group')) is not None:
            args['resource_group'] = ResourceGroupReference.from_dict(resource_group)
        else:
            raise ValueError('Required property \'resource_group\' not present in DefaultSecurityGroup JSON')
        if (rules := _dict.get('rules')) is not None:
            args['rules'] = [SecurityGroupRule.from_dict(v) for v in rules]
        else:
            raise ValueError('Required property \'rules\' not present in DefaultSecurityGroup JSON')
        if (targets := _dict.get('targets')) is not None:
            args['targets'] = targets
        else:
            raise ValueError('Required property \'targets\' not present in DefaultSecurityGroup JSON')
        if (vpc := _dict.get('vpc')) is not None:
            args['vpc'] = VPCReference.from_dict(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 Deleted:
    """
    If present, this property indicates the referenced resource has been deleted, and
    provides some supplementary information.

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

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

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

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

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

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

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

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

    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 := _dict.get('crn')) is not None:
            args['crn'] = 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.

    :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 List[EndpointGatewayLifecycleReason] lifecycle_reasons: The reasons for
          the current `lifecycle_state` (if any).
    :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 str service_endpoint: (optional) Deprecated: The fully qualified domain
          name for the target service.
    :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.
    """

    def __init__(
        self,
        allow_dns_resolution_binding: bool,
        created_at: datetime,
        crn: str,
        health_state: str,
        href: str,
        id: str,
        ips: List['ReservedIPReference'],
        lifecycle_reasons: List['EndpointGatewayLifecycleReason'],
        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: Optional[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 List[EndpointGatewayLifecycleReason] lifecycle_reasons: The reasons
               for the current `lifecycle_state` (if any).
        :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_reasons = lifecycle_reasons
        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 := _dict.get('allow_dns_resolution_binding')) is not None:
            args['allow_dns_resolution_binding'] = allow_dns_resolution_binding
        else:
            raise ValueError('Required property \'allow_dns_resolution_binding\' not present in EndpointGateway JSON')
        if (created_at := _dict.get('created_at')) is not None:
            args['created_at'] = string_to_datetime(created_at)
        else:
            raise ValueError('Required property \'created_at\' not present in EndpointGateway JSON')
        if (crn := _dict.get('crn')) is not None:
            args['crn'] = crn
        else:
            raise ValueError('Required property \'crn\' not present in EndpointGateway JSON')
        if (health_state := _dict.get('health_state')) is not None:
            args['health_state'] = health_state
        else:
            raise ValueError('Required property \'health_state\' not present in EndpointGateway JSON')
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in EndpointGateway JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in EndpointGateway JSON')
        if (ips := _dict.get('ips')) is not None:
            args['ips'] = [ReservedIPReference.from_dict(v) for v in ips]
        else:
            raise ValueError('Required property \'ips\' not present in EndpointGateway JSON')
        if (lifecycle_reasons := _dict.get('lifecycle_reasons')) is not None:
            args['lifecycle_reasons'] = [EndpointGatewayLifecycleReason.from_dict(v) for v in lifecycle_reasons]
        else:
            raise ValueError('Required property \'lifecycle_reasons\' not present in EndpointGateway JSON')
        if (lifecycle_state := _dict.get('lifecycle_state')) is not None:
            args['lifecycle_state'] = lifecycle_state
        else:
            raise ValueError('Required property \'lifecycle_state\' not present in EndpointGateway JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in EndpointGateway JSON')
        if (resource_group := _dict.get('resource_group')) is not None:
            args['resource_group'] = ResourceGroupReference.from_dict(resource_group)
        else:
            raise ValueError('Required property \'resource_group\' not present in EndpointGateway JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = resource_type
        else:
            raise ValueError('Required property \'resource_type\' not present in EndpointGateway JSON')
        if (security_groups := _dict.get('security_groups')) is not None:
            args['security_groups'] = [SecurityGroupReference.from_dict(v) for v in security_groups]
        else:
            raise ValueError('Required property \'security_groups\' not present in EndpointGateway JSON')
        if (service_endpoint := _dict.get('service_endpoint')) is not None:
            args['service_endpoint'] = service_endpoint
        if (service_endpoints := _dict.get('service_endpoints')) is not None:
            args['service_endpoints'] = service_endpoints
        else:
            raise ValueError('Required property \'service_endpoints\' not present in EndpointGateway JSON')
        if (target := _dict.get('target')) is not None:
            args['target'] = target
        else:
            raise ValueError('Required property \'target\' not present in EndpointGateway JSON')
        if (vpc := _dict.get('vpc')) is not None:
            args['vpc'] = VPCReference.from_dict(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_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_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.

    :param List[EndpointGateway] endpoint_gateways: A page of endpoint gateways.
    :param PageLink 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 PageLink next: (optional) A link to the next page of resources. This
          property is present for all pages
          except the last page.
    :param int total_count: The total number of resources across all pages.
    """

    def __init__(
        self,
        endpoint_gateways: List['EndpointGateway'],
        first: 'PageLink',
        limit: int,
        total_count: int,
        *,
        next: Optional['PageLink'] = None,
    ) -> None:
        """
        Initialize a EndpointGatewayCollection object.

        :param List[EndpointGateway] endpoint_gateways: A page of endpoint
               gateways.
        :param PageLink 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 PageLink 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 := _dict.get('endpoint_gateways')) is not None:
            args['endpoint_gateways'] = [EndpointGateway.from_dict(v) for v in endpoint_gateways]
        else:
            raise ValueError('Required property \'endpoint_gateways\' not present in EndpointGatewayCollection JSON')
        if (first := _dict.get('first')) is not None:
            args['first'] = PageLink.from_dict(first)
        else:
            raise ValueError('Required property \'first\' not present in EndpointGatewayCollection JSON')
        if (limit := _dict.get('limit')) is not None:
            args['limit'] = limit
        else:
            raise ValueError('Required property \'limit\' not present in EndpointGatewayCollection JSON')
        if (next := _dict.get('next')) is not None:
            args['next'] = PageLink.from_dict(next)
        if (total_count := _dict.get('total_count')) is not None:
            args['total_count'] = 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 EndpointGatewayLifecycleReason:
    """
    EndpointGatewayLifecycleReason.

    :param str code: A reason code for this lifecycle state:
          - `access_denied`: endpoint gateway access was denied
          - `access_expired`: endpoint gateway access has expired
          - `access_pending`: endpoint gateway access is pending
          - `dns_resolution_binding_pending`: the DNS resolution binding is being set up
          - `internal_error`: internal error (contact IBM support)
          - `resource_suspended_by_provider`: The resource has been suspended (contact IBM
            support)
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :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.
    """

    def __init__(
        self,
        code: str,
        message: str,
        *,
        more_info: Optional[str] = None,
    ) -> None:
        """
        Initialize a EndpointGatewayLifecycleReason object.

        :param str code: A reason code for this lifecycle state:
               - `access_denied`: endpoint gateway access was denied
               - `access_expired`: endpoint gateway access has expired
               - `access_pending`: endpoint gateway access is pending
               - `dns_resolution_binding_pending`: the DNS resolution binding is being set
               up
               - `internal_error`: internal error (contact IBM support)
               - `resource_suspended_by_provider`: The resource has been suspended
               (contact IBM
                 support)
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :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) -> 'EndpointGatewayLifecycleReason':
        """Initialize a EndpointGatewayLifecycleReason object from a json dictionary."""
        args = {}
        if (code := _dict.get('code')) is not None:
            args['code'] = code
        else:
            raise ValueError('Required property \'code\' not present in EndpointGatewayLifecycleReason JSON')
        if (message := _dict.get('message')) is not None:
            args['message'] = message
        else:
            raise ValueError('Required property \'message\' not present in EndpointGatewayLifecycleReason JSON')
        if (more_info := _dict.get('more_info')) is not None:
            args['more_info'] = more_info
        return cls(**args)

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

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

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

    class CodeEnum(str, Enum):
        """
        A reason code for this lifecycle state:
        - `access_denied`: endpoint gateway access was denied
        - `access_expired`: endpoint gateway access has expired
        - `access_pending`: endpoint gateway access is pending
        - `dns_resolution_binding_pending`: the DNS resolution binding is being set up
        - `internal_error`: internal error (contact IBM support)
        - `resource_suspended_by_provider`: The resource has been suspended (contact IBM
          support)
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        ACCESS_DENIED = 'access_denied'
        ACCESS_EXPIRED = 'access_expired'
        ACCESS_PENDING = 'access_pending'
        DNS_RESOLUTION_BINDING_PENDING = 'dns_resolution_binding_pending'
        INTERNAL_ERROR = 'internal_error'
        RESOURCE_SUSPENDED_BY_PROVIDER = 'resource_suspended_by_provider'



class EndpointGatewayPatch:
    """
    EndpointGatewayPatch.

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

    def __init__(
        self,
        *,
        allow_dns_resolution_binding: Optional[bool] = None,
        name: Optional[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 := _dict.get('allow_dns_resolution_binding')) is not None:
            args['allow_dns_resolution_binding'] = allow_dns_resolution_binding
        if (name := _dict.get('name')) is not None:
            args['name'] = 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 EndpointGatewayReferenceRemote:
    """
    EndpointGatewayReferenceRemote.

    :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 EndpointGatewayRemote remote: (optional) If present, this property
          indicates that the resource associated with this reference
          is remote and therefore may not be directly retrievable.
    :param str resource_type: The resource type.
    """

    def __init__(
        self,
        crn: str,
        href: str,
        id: str,
        name: str,
        resource_type: str,
        *,
        remote: Optional['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 := _dict.get('crn')) is not None:
            args['crn'] = crn
        else:
            raise ValueError('Required property \'crn\' not present in EndpointGatewayReferenceRemote JSON')
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in EndpointGatewayReferenceRemote JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in EndpointGatewayReferenceRemote JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in EndpointGatewayReferenceRemote JSON')
        if (remote := _dict.get('remote')) is not None:
            args['remote'] = EndpointGatewayRemote.from_dict(remote)
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = 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.

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

    def __init__(
        self,
        *,
        account: Optional['AccountReference'] = None,
        region: Optional['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 := _dict.get('account')) is not None:
            args['account'] = AccountReference.from_dict(account)
        if (region := _dict.get('region')) is not None:
            args['region'] = RegionReference.from_dict(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.

    :param str resource_type: The target resource type for this endpoint gateway.
    """

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

        :param str resource_type: The target resource type for this endpoint
               gateway.
        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['EndpointGatewayTargetPrivatePathServiceGatewayReference', 'EndpointGatewayTargetProviderCloudServiceReference', 'EndpointGatewayTargetProviderInfrastructureServiceReference'])
        )
        raise Exception(msg)

    class ResourceTypeEnum(str, Enum):
        """
        The target resource type for this endpoint gateway.
        """

        PRIVATE_PATH_SERVICE_GATEWAY = 'private_path_service_gateway'
        PROVIDER_CLOUD_SERVICE = 'provider_cloud_service'
        PROVIDER_INFRASTRUCTURE_SERVICE = 'provider_infrastructure_service'



class EndpointGatewayTargetPrototype:
    """
    The target to use for this endpoint gateway. The target:
    - Must not already be the target of another endpoint gateway in the VPC
    - Must not have a service endpoint that duplicates or overlaps with any
    `service_endpoints`
      of another endpoint gateway in the VPC.

    :param str resource_type: (optional) The target resource type for this endpoint
          gateway.
    """

    def __init__(
        self,
        *,
        resource_type: Optional[str] = None,
    ) -> None:
        """
        Initialize a EndpointGatewayTargetPrototype object.

        :param str resource_type: (optional) The target resource type for this
               endpoint gateway.
        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['EndpointGatewayTargetPrototypeEndpointGatewayTargetResourceTypePrivatePathServiceGatewayPrototype', 'EndpointGatewayTargetPrototypeEndpointGatewayTargetResourceTypeProviderInfrastructureServicePrototype', 'EndpointGatewayTargetPrototypeEndpointGatewayTargetResourceTypeProviderCloudServicePrototype'])
        )
        raise Exception(msg)

    class ResourceTypeEnum(str, Enum):
        """
        The target resource type for this endpoint gateway.
        """

        PRIVATE_PATH_SERVICE_GATEWAY = 'private_path_service_gateway'
        PROVIDER_CLOUD_SERVICE = 'provider_cloud_service'
        PROVIDER_INFRASTRUCTURE_SERVICE = 'provider_infrastructure_service'



class FloatingIP:
    """
    FloatingIP.

    :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.
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :param FloatingIPTarget target: (optional) The target of this floating IP.
    :param 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: Optional['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.
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :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 := _dict.get('address')) is not None:
            args['address'] = address
        else:
            raise ValueError('Required property \'address\' not present in FloatingIP JSON')
        if (created_at := _dict.get('created_at')) is not None:
            args['created_at'] = string_to_datetime(created_at)
        else:
            raise ValueError('Required property \'created_at\' not present in FloatingIP JSON')
        if (crn := _dict.get('crn')) is not None:
            args['crn'] = crn
        else:
            raise ValueError('Required property \'crn\' not present in FloatingIP JSON')
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in FloatingIP JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in FloatingIP JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in FloatingIP JSON')
        if (resource_group := _dict.get('resource_group')) is not None:
            args['resource_group'] = ResourceGroupReference.from_dict(resource_group)
        else:
            raise ValueError('Required property \'resource_group\' not present in FloatingIP JSON')
        if (status := _dict.get('status')) is not None:
            args['status'] = status
        else:
            raise ValueError('Required property \'status\' not present in FloatingIP JSON')
        if (target := _dict.get('target')) is not None:
            args['target'] = target
        if (zone := _dict.get('zone')) is not None:
            args['zone'] = ZoneReference.from_dict(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.
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        AVAILABLE = 'available'
        DELETING = 'deleting'
        FAILED = 'failed'
        PENDING = 'pending'



class FloatingIPCollection:
    """
    FloatingIPCollection.

    :param PageLink first: A link to the first page of resources.
    :param List[FloatingIP] floating_ips: A page of floating IPs.
    :param int limit: The maximum number of resources that can be returned by the
          request.
    :param PageLink next: (optional) A link to the next page of resources. This
          property is present for all pages
          except the last page.
    :param int total_count: The total number of resources across all pages.
    """

    def __init__(
        self,
        first: 'PageLink',
        floating_ips: List['FloatingIP'],
        limit: int,
        total_count: int,
        *,
        next: Optional['PageLink'] = None,
    ) -> None:
        """
        Initialize a FloatingIPCollection object.

        :param PageLink first: A link to the first page of resources.
        :param List[FloatingIP] floating_ips: A page 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 PageLink 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 := _dict.get('first')) is not None:
            args['first'] = PageLink.from_dict(first)
        else:
            raise ValueError('Required property \'first\' not present in FloatingIPCollection JSON')
        if (floating_ips := _dict.get('floating_ips')) is not None:
            args['floating_ips'] = [FloatingIP.from_dict(v) for v in floating_ips]
        else:
            raise ValueError('Required property \'floating_ips\' not present in FloatingIPCollection JSON')
        if (limit := _dict.get('limit')) is not None:
            args['limit'] = limit
        else:
            raise ValueError('Required property \'limit\' not present in FloatingIPCollection JSON')
        if (next := _dict.get('next')) is not None:
            args['next'] = PageLink.from_dict(next)
        if (total_count := _dict.get('total_count')) is not None:
            args['total_count'] = 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 FloatingIPCollectionVirtualNetworkInterfaceContext:
    """
    FloatingIPCollectionVirtualNetworkInterfaceContext.

    :param PageLink first: A link to the first page of resources.
    :param List[FloatingIPReference] floating_ips: A page of floating IPs bound to
          the virtual network interface specified by the identifier in the URL.
    :param int limit: The maximum number of resources that can be returned by the
          request.
    :param PageLink next: (optional) A link to the next page of resources. This
          property is present for all pages
          except the last page.
    :param int total_count: The total number of resources across all pages.
    """

    def __init__(
        self,
        first: 'PageLink',
        floating_ips: List['FloatingIPReference'],
        limit: int,
        total_count: int,
        *,
        next: Optional['PageLink'] = None,
    ) -> None:
        """
        Initialize a FloatingIPCollectionVirtualNetworkInterfaceContext object.

        :param PageLink first: A link to the first page of resources.
        :param List[FloatingIPReference] floating_ips: A page of floating IPs bound
               to the virtual network interface specified by the identifier in the URL.
        :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 PageLink 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) -> 'FloatingIPCollectionVirtualNetworkInterfaceContext':
        """Initialize a FloatingIPCollectionVirtualNetworkInterfaceContext object from a json dictionary."""
        args = {}
        if (first := _dict.get('first')) is not None:
            args['first'] = PageLink.from_dict(first)
        else:
            raise ValueError('Required property \'first\' not present in FloatingIPCollectionVirtualNetworkInterfaceContext JSON')
        if (floating_ips := _dict.get('floating_ips')) is not None:
            args['floating_ips'] = [FloatingIPReference.from_dict(v) for v in floating_ips]
        else:
            raise ValueError('Required property \'floating_ips\' not present in FloatingIPCollectionVirtualNetworkInterfaceContext JSON')
        if (limit := _dict.get('limit')) is not None:
            args['limit'] = limit
        else:
            raise ValueError('Required property \'limit\' not present in FloatingIPCollectionVirtualNetworkInterfaceContext JSON')
        if (next := _dict.get('next')) is not None:
            args['next'] = PageLink.from_dict(next)
        if (total_count := _dict.get('total_count')) is not None:
            args['total_count'] = total_count
        else:
            raise ValueError('Required property \'total_count\' not present in FloatingIPCollectionVirtualNetworkInterfaceContext JSON')
        return cls(**args)

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

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

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


class FloatingIPPatch:
    """
    FloatingIPPatch.

    :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`
          - a virtual network interface with `enable_infrastructure_nat` set to `true`
          Specify `null` to remove an existing binding.
    """

    def __init__(
        self,
        *,
        name: Optional[str] = None,
        target: Optional['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`
               - a virtual network interface with `enable_infrastructure_nat` set to
               `true`
               Specify `null` to remove an existing binding.
        """
        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 := _dict.get('name')) is not None:
            args['name'] = name
        if (target := _dict.get('target')) is not None:
            args['target'] = 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.

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

    def __init__(
        self,
        *,
        name: Optional[str] = None,
        resource_group: Optional['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.

    :param str address: The globally unique IP address.
    :param str crn: The CRN for this floating IP.
    :param Deleted deleted: (optional) If present, this property indicates the
          referenced resource has been deleted, and provides
          some supplementary information.
    :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.
    """

    def __init__(
        self,
        address: str,
        crn: str,
        href: str,
        id: str,
        name: str,
        *,
        deleted: Optional['Deleted'] = 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 Deleted 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 := _dict.get('address')) is not None:
            args['address'] = address
        else:
            raise ValueError('Required property \'address\' not present in FloatingIPReference JSON')
        if (crn := _dict.get('crn')) is not None:
            args['crn'] = crn
        else:
            raise ValueError('Required property \'crn\' not present in FloatingIPReference JSON')
        if (deleted := _dict.get('deleted')) is not None:
            args['deleted'] = Deleted.from_dict(deleted)
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in FloatingIPReference JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in FloatingIPReference JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = 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 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', 'FloatingIPTargetVirtualNetworkInterfaceReference'])
        )
        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`
    - a virtual network interface with `enable_infrastructure_nat` set to `true`
    Specify `null` to remove an existing binding.

    """

    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', 'FloatingIPTargetPatchVirtualNetworkInterfaceIdentity'])
        )
        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`
    - a virtual 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', 'FloatingIPTargetPrototypeVirtualNetworkInterfaceIdentity'])
        )
        raise Exception(msg)


class FloatingIPUnpaginatedCollection:
    """
    FloatingIPUnpaginatedCollection.

    :param List[FloatingIP] floating_ips: The floating IPs.
    """

    def __init__(
        self,
        floating_ips: List['FloatingIP'],
    ) -> None:
        """
        Initialize a FloatingIPUnpaginatedCollection object.

        :param List[FloatingIP] floating_ips: The 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 := _dict.get('floating_ips')) is not None:
            args['floating_ips'] = [FloatingIP.from_dict(v) for v in 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.

    :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 attachment, flow logs will be collected
            for that instance network attachment.
          - If the target is an instance network interface, flow logs will be collected
            for that instance network interface.
          - If the target is a virtual network interface, flow logs will be collected for
          the
            virtual network interface's `target` resource if the resource is an instance
          network
            attachment, unless the target resource is itself the target of a flow log
          collector.
          - If the target is a virtual server instance, flow logs will be collected
            for all network attachments or network interfaces on that instance.
          - If the target is a subnet, flow logs will be collected
            for all instance network interfaces and virtual network interfaces
            attached to that subnet.
          - If the target is a VPC, flow logs will be collected for all instance network
            interfaces and virtual 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 attachments or 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.
    """

    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 attachment, flow logs will be
               collected
                 for that instance network attachment.
               - If the target is an instance network interface, flow logs will be
               collected
                 for that instance network interface.
               - If the target is a virtual network interface, flow logs will be collected
               for the
                 virtual network interface's `target` resource if the resource is an
               instance network
                 attachment, unless the target resource is itself the target of a flow log
               collector.
               - If the target is a virtual server instance, flow logs will be collected
                 for all network attachments or network interfaces on that instance.
               - If the target is a subnet, flow logs will be collected
                 for all instance network interfaces and virtual network interfaces
                 attached to that subnet.
               - If the target is a VPC, flow logs will be collected for all instance
               network
                 interfaces and virtual 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 attachments or 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 := _dict.get('active')) is not None:
            args['active'] = active
        else:
            raise ValueError('Required property \'active\' not present in FlowLogCollector JSON')
        if (auto_delete := _dict.get('auto_delete')) is not None:
            args['auto_delete'] = auto_delete
        else:
            raise ValueError('Required property \'auto_delete\' not present in FlowLogCollector JSON')
        if (created_at := _dict.get('created_at')) is not None:
            args['created_at'] = string_to_datetime(created_at)
        else:
            raise ValueError('Required property \'created_at\' not present in FlowLogCollector JSON')
        if (crn := _dict.get('crn')) is not None:
            args['crn'] = crn
        else:
            raise ValueError('Required property \'crn\' not present in FlowLogCollector JSON')
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in FlowLogCollector JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in FlowLogCollector JSON')
        if (lifecycle_state := _dict.get('lifecycle_state')) is not None:
            args['lifecycle_state'] = lifecycle_state
        else:
            raise ValueError('Required property \'lifecycle_state\' not present in FlowLogCollector JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in FlowLogCollector JSON')
        if (resource_group := _dict.get('resource_group')) is not None:
            args['resource_group'] = ResourceGroupReference.from_dict(resource_group)
        else:
            raise ValueError('Required property \'resource_group\' not present in FlowLogCollector JSON')
        if (storage_bucket := _dict.get('storage_bucket')) is not None:
            args['storage_bucket'] = LegacyCloudObjectStorageBucketReference.from_dict(storage_bucket)
        else:
            raise ValueError('Required property \'storage_bucket\' not present in FlowLogCollector JSON')
        if (target := _dict.get('target')) is not None:
            args['target'] = target
        else:
            raise ValueError('Required property \'target\' not present in FlowLogCollector JSON')
        if (vpc := _dict.get('vpc')) is not None:
            args['vpc'] = VPCReference.from_dict(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.

    :param PageLink first: A link to the first page of resources.
    :param List[FlowLogCollector] flow_log_collectors: A page of flow log
          collectors.
    :param int limit: The maximum number of resources that can be returned by the
          request.
    :param PageLink next: (optional) A link to the next page of resources. This
          property is present for all pages
          except the last page.
    :param int total_count: The total number of resources across all pages.
    """

    def __init__(
        self,
        first: 'PageLink',
        flow_log_collectors: List['FlowLogCollector'],
        limit: int,
        total_count: int,
        *,
        next: Optional['PageLink'] = None,
    ) -> None:
        """
        Initialize a FlowLogCollectorCollection object.

        :param PageLink first: A link to the first page of resources.
        :param List[FlowLogCollector] flow_log_collectors: A page 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 PageLink 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 := _dict.get('first')) is not None:
            args['first'] = PageLink.from_dict(first)
        else:
            raise ValueError('Required property \'first\' not present in FlowLogCollectorCollection JSON')
        if (flow_log_collectors := _dict.get('flow_log_collectors')) is not None:
            args['flow_log_collectors'] = [FlowLogCollector.from_dict(v) for v in flow_log_collectors]
        else:
            raise ValueError('Required property \'flow_log_collectors\' not present in FlowLogCollectorCollection JSON')
        if (limit := _dict.get('limit')) is not None:
            args['limit'] = limit
        else:
            raise ValueError('Required property \'limit\' not present in FlowLogCollectorCollection JSON')
        if (next := _dict.get('next')) is not None:
            args['next'] = PageLink.from_dict(next)
        if (total_count := _dict.get('total_count')) is not None:
            args['total_count'] = 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 FlowLogCollectorPatch:
    """
    FlowLogCollectorPatch.

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

    def __init__(
        self,
        *,
        active: Optional[bool] = None,
        name: Optional[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 := _dict.get('active')) is not None:
            args['active'] = active
        if (name := _dict.get('name')) is not None:
            args['name'] = 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 attachment, flow logs will be collected
      for that instance network attachment.
    - If the target is an instance network interface, flow logs will be collected
      for that instance network interface.
    - If the target is a virtual network interface, flow logs will be collected for the
      virtual network interface's `target` resource if the resource is an instance network
      attachment, unless the target resource is itself the target of a flow log collector.
    - If the target is a virtual server instance, flow logs will be collected
      for all network attachments or network interfaces on that instance.
    - If the target is a subnet, flow logs will be collected
      for all instance network interfaces and virtual network interfaces
      attached to that subnet.
    - If the target is a VPC, flow logs will be collected for all instance network
      interfaces and virtual 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 attachments or 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', 'FlowLogCollectorTargetInstanceNetworkAttachmentReference', 'FlowLogCollectorTargetVirtualNetworkInterfaceReferenceAttachmentContext'])
        )
        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 attachments, virtual network interfaces or instance network
    interfaces within the target that are themselves the target of a more specific flow
    log collector.
    The target must not be a virtual network interface that is attached to a bare metal
    server network attachment or to a file share mount target.

    """

    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', 'FlowLogCollectorTargetPrototypeVirtualNetworkInterfaceIdentity', 'FlowLogCollectorTargetPrototypeInstanceNetworkAttachmentIdentity'])
        )
        raise Exception(msg)


class IKEPolicy:
    """
    IKEPolicy.

    :param str authentication_algorithm: The authentication algorithm.
          The `md5` and `sha1` algorithms have been deprecated.
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :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.
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :param str href: The URL for this IKE policy.
    :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.
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :param ResourceGroupReference resource_group: The resource group for this IKE
          policy.
    :param 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.
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :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.
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :param str href: The URL for this IKE policy.
        :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.
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :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 := _dict.get('authentication_algorithm')) is not None:
            args['authentication_algorithm'] = authentication_algorithm
        else:
            raise ValueError('Required property \'authentication_algorithm\' not present in IKEPolicy JSON')
        if (connections := _dict.get('connections')) is not None:
            args['connections'] = [VPNGatewayConnectionReference.from_dict(v) for v in connections]
        else:
            raise ValueError('Required property \'connections\' not present in IKEPolicy JSON')
        if (created_at := _dict.get('created_at')) is not None:
            args['created_at'] = string_to_datetime(created_at)
        else:
            raise ValueError('Required property \'created_at\' not present in IKEPolicy JSON')
        if (dh_group := _dict.get('dh_group')) is not None:
            args['dh_group'] = dh_group
        else:
            raise ValueError('Required property \'dh_group\' not present in IKEPolicy JSON')
        if (encryption_algorithm := _dict.get('encryption_algorithm')) is not None:
            args['encryption_algorithm'] = encryption_algorithm
        else:
            raise ValueError('Required property \'encryption_algorithm\' not present in IKEPolicy JSON')
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in IKEPolicy JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in IKEPolicy JSON')
        if (ike_version := _dict.get('ike_version')) is not None:
            args['ike_version'] = ike_version
        else:
            raise ValueError('Required property \'ike_version\' not present in IKEPolicy JSON')
        if (key_lifetime := _dict.get('key_lifetime')) is not None:
            args['key_lifetime'] = key_lifetime
        else:
            raise ValueError('Required property \'key_lifetime\' not present in IKEPolicy JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in IKEPolicy JSON')
        if (negotiation_mode := _dict.get('negotiation_mode')) is not None:
            args['negotiation_mode'] = negotiation_mode
        else:
            raise ValueError('Required property \'negotiation_mode\' not present in IKEPolicy JSON')
        if (resource_group := _dict.get('resource_group')) is not None:
            args['resource_group'] = ResourceGroupReference.from_dict(resource_group)
        else:
            raise ValueError('Required property \'resource_group\' not present in IKEPolicy JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = 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.
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        MD5 = 'md5'
        SHA1 = 'sha1'
        SHA256 = 'sha256'
        SHA384 = 'sha384'
        SHA512 = 'sha512'


    class EncryptionAlgorithmEnum(str, Enum):
        """
        The encryption algorithm.
        The `triple_des` algorithm has been deprecated.
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        AES128 = 'aes128'
        AES192 = 'aes192'
        AES256 = 'aes256'
        TRIPLE_DES = 'triple_des'


    class NegotiationModeEnum(str, Enum):
        """
        The IKE negotiation mode.
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        MAIN = 'main'


    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        IKE_POLICY = 'ike_policy'



class IKEPolicyCollection:
    """
    IKEPolicyCollection.

    :param PageLink first: A link to the first page of resources.
    :param List[IKEPolicy] ike_policies: A page of IKE policies.
    :param int limit: The maximum number of resources that can be returned by the
          request.
    :param PageLink next: (optional) A link to the next page of resources. This
          property is present for all pages
          except the last page.
    :param int total_count: The total number of resources across all pages.
    """

    def __init__(
        self,
        first: 'PageLink',
        ike_policies: List['IKEPolicy'],
        limit: int,
        total_count: int,
        *,
        next: Optional['PageLink'] = None,
    ) -> None:
        """
        Initialize a IKEPolicyCollection object.

        :param PageLink first: A link to the first page of resources.
        :param List[IKEPolicy] ike_policies: A page 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 PageLink 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 := _dict.get('first')) is not None:
            args['first'] = PageLink.from_dict(first)
        else:
            raise ValueError('Required property \'first\' not present in IKEPolicyCollection JSON')
        if (ike_policies := _dict.get('ike_policies')) is not None:
            args['ike_policies'] = [IKEPolicy.from_dict(v) for v in ike_policies]
        else:
            raise ValueError('Required property \'ike_policies\' not present in IKEPolicyCollection JSON')
        if (limit := _dict.get('limit')) is not None:
            args['limit'] = limit
        else:
            raise ValueError('Required property \'limit\' not present in IKEPolicyCollection JSON')
        if (next := _dict.get('next')) is not None:
            args['next'] = PageLink.from_dict(next)
        if (total_count := _dict.get('total_count')) is not None:
            args['total_count'] = 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 IKEPolicyConnectionCollection:
    """
    IKEPolicyConnectionCollection.

    :param List[VPNGatewayConnection] connections: A page of VPN gateway connections
          that use the IKE policy specified by the identifier in the URL.
    :param PageLink 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 PageLink next: (optional) A link to the next page of resources. This
          property is present for all pages
          except the last page.
    :param int total_count: The total number of resources across all pages.
    """

    def __init__(
        self,
        connections: List['VPNGatewayConnection'],
        first: 'PageLink',
        limit: int,
        total_count: int,
        *,
        next: Optional['PageLink'] = None,
    ) -> None:
        """
        Initialize a IKEPolicyConnectionCollection object.

        :param List[VPNGatewayConnection] connections: A page of VPN gateway
               connections that use the IKE policy specified by the identifier in the URL.
        :param PageLink 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 PageLink next: (optional) A link to the next page of resources. This
               property is present for all pages
               except the last page.
        """
        self.connections = connections
        self.first = first
        self.limit = limit
        self.next = next
        self.total_count = total_count

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'IKEPolicyConnectionCollection':
        """Initialize a IKEPolicyConnectionCollection object from a json dictionary."""
        args = {}
        if (connections := _dict.get('connections')) is not None:
            args['connections'] = [VPNGatewayConnection.from_dict(v) for v in connections]
        else:
            raise ValueError('Required property \'connections\' not present in IKEPolicyConnectionCollection JSON')
        if (first := _dict.get('first')) is not None:
            args['first'] = PageLink.from_dict(first)
        else:
            raise ValueError('Required property \'first\' not present in IKEPolicyConnectionCollection JSON')
        if (limit := _dict.get('limit')) is not None:
            args['limit'] = limit
        else:
            raise ValueError('Required property \'limit\' not present in IKEPolicyConnectionCollection JSON')
        if (next := _dict.get('next')) is not None:
            args['next'] = PageLink.from_dict(next)
        if (total_count := _dict.get('total_count')) is not None:
            args['total_count'] = total_count
        else:
            raise ValueError('Required property \'total_count\' not present in IKEPolicyConnectionCollection JSON')
        return cls(**args)

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

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

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


class IKEPolicyPatch:
    """
    IKEPolicyPatch.

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

    def __init__(
        self,
        *,
        authentication_algorithm: Optional[str] = None,
        dh_group: Optional[int] = None,
        encryption_algorithm: Optional[str] = None,
        ike_version: Optional[int] = None,
        key_lifetime: Optional[int] = None,
        name: Optional[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 := _dict.get('authentication_algorithm')) is not None:
            args['authentication_algorithm'] = authentication_algorithm
        if (dh_group := _dict.get('dh_group')) is not None:
            args['dh_group'] = dh_group
        if (encryption_algorithm := _dict.get('encryption_algorithm')) is not None:
            args['encryption_algorithm'] = encryption_algorithm
        if (ike_version := _dict.get('ike_version')) is not None:
            args['ike_version'] = ike_version
        if (key_lifetime := _dict.get('key_lifetime')) is not None:
            args['key_lifetime'] = key_lifetime
        if (name := _dict.get('name')) is not None:
            args['name'] = 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.

    :param Deleted deleted: (optional) If present, this property indicates the
          referenced resource has been deleted, and provides
          some supplementary information.
    :param str href: The URL for this IKE policy.
    :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.
    """

    def __init__(
        self,
        href: str,
        id: str,
        name: str,
        resource_type: str,
        *,
        deleted: Optional['Deleted'] = None,
    ) -> None:
        """
        Initialize a IKEPolicyReference object.

        :param str href: The URL for this IKE policy.
        :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 Deleted 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 := _dict.get('deleted')) is not None:
            args['deleted'] = Deleted.from_dict(deleted)
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in IKEPolicyReference JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in IKEPolicyReference JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in IKEPolicyReference JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = 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 IP:
    """
    IP.

    :param str address: The IP address.
          This property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) to support
          IPv6 addresses in the future.
    """

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

        :param str address: The IP address.
               This property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) to
               support IPv6 addresses in the future.
        """
        self.address = address

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'IP':
        """Initialize a IP object from a json dictionary."""
        args = {}
        if (address := _dict.get('address')) is not None:
            args['address'] = 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.

    :param str authentication_algorithm: The authentication algorithm
          The `md5` and `sha1` algorithms have been deprecated
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :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.
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :param str encryption_algorithm: The encryption algorithm
          The `triple_des` algorithm has been deprecated
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :param str href: The URL for this IPsec policy.
    :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: The Perfect Forward Secrecy group
          Groups `group_2` and `group_5` have been deprecated
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :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.
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    """

    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
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :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.
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :param str encryption_algorithm: The encryption algorithm
               The `triple_des` algorithm has been deprecated
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :param str href: The URL for this IPsec policy.
        :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: The Perfect Forward Secrecy group
               Groups `group_2` and `group_5` have been deprecated
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :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.
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        """
        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 := _dict.get('authentication_algorithm')) is not None:
            args['authentication_algorithm'] = authentication_algorithm
        else:
            raise ValueError('Required property \'authentication_algorithm\' not present in IPsecPolicy JSON')
        if (connections := _dict.get('connections')) is not None:
            args['connections'] = [VPNGatewayConnectionReference.from_dict(v) for v in connections]
        else:
            raise ValueError('Required property \'connections\' not present in IPsecPolicy JSON')
        if (created_at := _dict.get('created_at')) is not None:
            args['created_at'] = string_to_datetime(created_at)
        else:
            raise ValueError('Required property \'created_at\' not present in IPsecPolicy JSON')
        if (encapsulation_mode := _dict.get('encapsulation_mode')) is not None:
            args['encapsulation_mode'] = encapsulation_mode
        else:
            raise ValueError('Required property \'encapsulation_mode\' not present in IPsecPolicy JSON')
        if (encryption_algorithm := _dict.get('encryption_algorithm')) is not None:
            args['encryption_algorithm'] = encryption_algorithm
        else:
            raise ValueError('Required property \'encryption_algorithm\' not present in IPsecPolicy JSON')
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in IPsecPolicy JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in IPsecPolicy JSON')
        if (key_lifetime := _dict.get('key_lifetime')) is not None:
            args['key_lifetime'] = key_lifetime
        else:
            raise ValueError('Required property \'key_lifetime\' not present in IPsecPolicy JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in IPsecPolicy JSON')
        if (pfs := _dict.get('pfs')) is not None:
            args['pfs'] = pfs
        else:
            raise ValueError('Required property \'pfs\' not present in IPsecPolicy JSON')
        if (resource_group := _dict.get('resource_group')) is not None:
            args['resource_group'] = ResourceGroupReference.from_dict(resource_group)
        else:
            raise ValueError('Required property \'resource_group\' not present in IPsecPolicy JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = resource_type
        else:
            raise ValueError('Required property \'resource_type\' not present in IPsecPolicy JSON')
        if (transform_protocol := _dict.get('transform_protocol')) is not None:
            args['transform_protocol'] = 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
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        DISABLED = 'disabled'
        MD5 = 'md5'
        SHA1 = 'sha1'
        SHA256 = 'sha256'
        SHA384 = 'sha384'
        SHA512 = 'sha512'


    class EncapsulationModeEnum(str, Enum):
        """
        The encapsulation mode used.
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        TUNNEL = 'tunnel'


    class EncryptionAlgorithmEnum(str, Enum):
        """
        The encryption algorithm
        The `triple_des` algorithm has been deprecated
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        AES128 = 'aes128'
        AES128GCM16 = 'aes128gcm16'
        AES192 = 'aes192'
        AES192GCM16 = 'aes192gcm16'
        AES256 = 'aes256'
        AES256GCM16 = 'aes256gcm16'
        TRIPLE_DES = 'triple_des'


    class PfsEnum(str, Enum):
        """
        The Perfect Forward Secrecy group
        Groups `group_2` and `group_5` have been deprecated
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        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.
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        ESP = 'esp'



class IPsecPolicyCollection:
    """
    IPsecPolicyCollection.

    :param PageLink first: A link to the first page of resources.
    :param List[IPsecPolicy] ipsec_policies: A page of IPsec policies.
    :param int limit: The maximum number of resources that can be returned by the
          request.
    :param PageLink next: (optional) A link to the next page of resources. This
          property is present for all pages
          except the last page.
    :param int total_count: The total number of resources across all pages.
    """

    def __init__(
        self,
        first: 'PageLink',
        ipsec_policies: List['IPsecPolicy'],
        limit: int,
        total_count: int,
        *,
        next: Optional['PageLink'] = None,
    ) -> None:
        """
        Initialize a IPsecPolicyCollection object.

        :param PageLink first: A link to the first page of resources.
        :param List[IPsecPolicy] ipsec_policies: A page 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 PageLink 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 := _dict.get('first')) is not None:
            args['first'] = PageLink.from_dict(first)
        else:
            raise ValueError('Required property \'first\' not present in IPsecPolicyCollection JSON')
        if (ipsec_policies := _dict.get('ipsec_policies')) is not None:
            args['ipsec_policies'] = [IPsecPolicy.from_dict(v) for v in ipsec_policies]
        else:
            raise ValueError('Required property \'ipsec_policies\' not present in IPsecPolicyCollection JSON')
        if (limit := _dict.get('limit')) is not None:
            args['limit'] = limit
        else:
            raise ValueError('Required property \'limit\' not present in IPsecPolicyCollection JSON')
        if (next := _dict.get('next')) is not None:
            args['next'] = PageLink.from_dict(next)
        if (total_count := _dict.get('total_count')) is not None:
            args['total_count'] = 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 IPsecPolicyConnectionCollection:
    """
    IPsecPolicyConnectionCollection.

    :param List[VPNGatewayConnection] connections: A page of VPN gateway connections
          that use the IPsec policy specified by the identifier in the URL.
    :param PageLink 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 PageLink next: (optional) A link to the next page of resources. This
          property is present for all pages
          except the last page.
    :param int total_count: The total number of resources across all pages.
    """

    def __init__(
        self,
        connections: List['VPNGatewayConnection'],
        first: 'PageLink',
        limit: int,
        total_count: int,
        *,
        next: Optional['PageLink'] = None,
    ) -> None:
        """
        Initialize a IPsecPolicyConnectionCollection object.

        :param List[VPNGatewayConnection] connections: A page of VPN gateway
               connections that use the IPsec policy specified by the identifier in the
               URL.
        :param PageLink 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 PageLink next: (optional) A link to the next page of resources. This
               property is present for all pages
               except the last page.
        """
        self.connections = connections
        self.first = first
        self.limit = limit
        self.next = next
        self.total_count = total_count

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'IPsecPolicyConnectionCollection':
        """Initialize a IPsecPolicyConnectionCollection object from a json dictionary."""
        args = {}
        if (connections := _dict.get('connections')) is not None:
            args['connections'] = [VPNGatewayConnection.from_dict(v) for v in connections]
        else:
            raise ValueError('Required property \'connections\' not present in IPsecPolicyConnectionCollection JSON')
        if (first := _dict.get('first')) is not None:
            args['first'] = PageLink.from_dict(first)
        else:
            raise ValueError('Required property \'first\' not present in IPsecPolicyConnectionCollection JSON')
        if (limit := _dict.get('limit')) is not None:
            args['limit'] = limit
        else:
            raise ValueError('Required property \'limit\' not present in IPsecPolicyConnectionCollection JSON')
        if (next := _dict.get('next')) is not None:
            args['next'] = PageLink.from_dict(next)
        if (total_count := _dict.get('total_count')) is not None:
            args['total_count'] = total_count
        else:
            raise ValueError('Required property \'total_count\' not present in IPsecPolicyConnectionCollection JSON')
        return cls(**args)

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

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

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


class IPsecPolicyPatch:
    """
    IPsecPolicyPatch.

    :param str authentication_algorithm: (optional) The authentication algorithm
          Must be `disabled` if and only if the `encryption_algorithm` is `aes128gcm16`,
          `aes192gcm16`, or `aes256gcm16`
          The `md5` and `sha1` algorithms have been deprecated.
    :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`
          The `triple_des` algorithm has been deprecated.
    :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) The Perfect Forward Secrecy group.
          Groups `group_2` and `group_5` have been deprecated.
    """

    def __init__(
        self,
        *,
        authentication_algorithm: Optional[str] = None,
        encryption_algorithm: Optional[str] = None,
        key_lifetime: Optional[int] = None,
        name: Optional[str] = None,
        pfs: Optional[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`
               The `md5` and `sha1` algorithms have been deprecated.
        :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`
               The `triple_des` algorithm has been deprecated.
        :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) The Perfect Forward Secrecy group.
               Groups `group_2` and `group_5` have been deprecated.
        """
        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 := _dict.get('authentication_algorithm')) is not None:
            args['authentication_algorithm'] = authentication_algorithm
        if (encryption_algorithm := _dict.get('encryption_algorithm')) is not None:
            args['encryption_algorithm'] = encryption_algorithm
        if (key_lifetime := _dict.get('key_lifetime')) is not None:
            args['key_lifetime'] = key_lifetime
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        if (pfs := _dict.get('pfs')) is not None:
            args['pfs'] = 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`
        The `md5` and `sha1` algorithms have been deprecated.
        """

        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`
        The `triple_des` algorithm has been deprecated.
        """

        AES128 = 'aes128'
        AES128GCM16 = 'aes128gcm16'
        AES192 = 'aes192'
        AES192GCM16 = 'aes192gcm16'
        AES256 = 'aes256'
        AES256GCM16 = 'aes256gcm16'


    class PfsEnum(str, Enum):
        """
        The Perfect Forward Secrecy group.
        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_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.

    :param Deleted deleted: (optional) If present, this property indicates the
          referenced resource has been deleted, and provides
          some supplementary information.
    :param str href: The URL for this IPsec policy.
    :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.
    """

    def __init__(
        self,
        href: str,
        id: str,
        name: str,
        resource_type: str,
        *,
        deleted: Optional['Deleted'] = None,
    ) -> None:
        """
        Initialize a IPsecPolicyReference object.

        :param str href: The URL for this IPsec policy.
        :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 Deleted 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 := _dict.get('deleted')) is not None:
            args['deleted'] = Deleted.from_dict(deleted)
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in IPsecPolicyReference JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in IPsecPolicyReference JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in IPsecPolicyReference JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = 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 Image:
    """
    Image.

    :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 datetime deprecation_at: (optional) The deprecation date and time (UTC)
          for this image.
          If absent, no deprecation date and time has been set.
    :param str encryption: The type of encryption used on the image.
    :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 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 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 str name: The name for this image. The name is unique across all images
          in the region.
    :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 ResourceGroupReference resource_group: The resource group for this image.
    :param str resource_type: The resource type.
    :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.
    :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 may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :param List[ImageStatusReason] status_reasons:
    :param str user_data_format: The user data format for this image:
          - `cloud_init`: `user_data` will be interpreted according to the cloud-init
          standard
          - `esxi_kickstart`: `user_data` will be interpreted as a VMware ESXi
          installation script
          - `ipxe`: `user_data` will be interpreted as a single URL to an iPXE script or
          as the
            text of an iPXE script
          The value for this property is inherited from
          `operating_system.user_data_format`.
    :param 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'],
        user_data_format: str,
        visibility: str,
        *,
        deprecation_at: Optional[datetime] = None,
        encryption_key: Optional['EncryptionKeyReference'] = None,
        minimum_provisioned_size: Optional[int] = None,
        obsolescence_at: Optional[datetime] = None,
        operating_system: Optional['OperatingSystem'] = None,
        source_volume: Optional['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 may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :param List[ImageStatusReason] status_reasons:
        :param str user_data_format: The user data format for this image:
               - `cloud_init`: `user_data` will be interpreted according to the cloud-init
               standard
               - `esxi_kickstart`: `user_data` will be interpreted as a VMware ESXi
               installation script
               - `ipxe`: `user_data` will be interpreted as a single URL to an iPXE script
               or as the
                 text of an iPXE script
               The value for this property is inherited from
               `operating_system.user_data_format`.
        :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.user_data_format = user_data_format
        self.visibility = visibility

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'Image':
        """Initialize a Image object from a json dictionary."""
        args = {}
        if (catalog_offering := _dict.get('catalog_offering')) is not None:
            args['catalog_offering'] = ImageCatalogOffering.from_dict(catalog_offering)
        else:
            raise ValueError('Required property \'catalog_offering\' not present in Image JSON')
        if (created_at := _dict.get('created_at')) is not None:
            args['created_at'] = string_to_datetime(created_at)
        else:
            raise ValueError('Required property \'created_at\' not present in Image JSON')
        if (crn := _dict.get('crn')) is not None:
            args['crn'] = crn
        else:
            raise ValueError('Required property \'crn\' not present in Image JSON')
        if (deprecation_at := _dict.get('deprecation_at')) is not None:
            args['deprecation_at'] = string_to_datetime(deprecation_at)
        if (encryption := _dict.get('encryption')) is not None:
            args['encryption'] = encryption
        else:
            raise ValueError('Required property \'encryption\' not present in Image JSON')
        if (encryption_key := _dict.get('encryption_key')) is not None:
            args['encryption_key'] = EncryptionKeyReference.from_dict(encryption_key)
        if (file := _dict.get('file')) is not None:
            args['file'] = ImageFile.from_dict(file)
        else:
            raise ValueError('Required property \'file\' not present in Image JSON')
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in Image JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in Image JSON')
        if (minimum_provisioned_size := _dict.get('minimum_provisioned_size')) is not None:
            args['minimum_provisioned_size'] = minimum_provisioned_size
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in Image JSON')
        if (obsolescence_at := _dict.get('obsolescence_at')) is not None:
            args['obsolescence_at'] = string_to_datetime(obsolescence_at)
        if (operating_system := _dict.get('operating_system')) is not None:
            args['operating_system'] = OperatingSystem.from_dict(operating_system)
        if (resource_group := _dict.get('resource_group')) is not None:
            args['resource_group'] = ResourceGroupReference.from_dict(resource_group)
        else:
            raise ValueError('Required property \'resource_group\' not present in Image JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = resource_type
        else:
            raise ValueError('Required property \'resource_type\' not present in Image JSON')
        if (source_volume := _dict.get('source_volume')) is not None:
            args['source_volume'] = VolumeReference.from_dict(source_volume)
        if (status := _dict.get('status')) is not None:
            args['status'] = status
        else:
            raise ValueError('Required property \'status\' not present in Image JSON')
        if (status_reasons := _dict.get('status_reasons')) is not None:
            args['status_reasons'] = [ImageStatusReason.from_dict(v) for v in status_reasons]
        else:
            raise ValueError('Required property \'status_reasons\' not present in Image JSON')
        if (user_data_format := _dict.get('user_data_format')) is not None:
            args['user_data_format'] = user_data_format
        else:
            raise ValueError('Required property \'user_data_format\' not present in Image JSON')
        if (visibility := _dict.get('visibility')) is not None:
            args['visibility'] = 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, 'user_data_format') and self.user_data_format is not None:
            _dict['user_data_format'] = self.user_data_format
        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 may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        AVAILABLE = 'available'
        DELETING = 'deleting'
        DEPRECATED = 'deprecated'
        FAILED = 'failed'
        OBSOLETE = 'obsolete'
        PENDING = 'pending'
        UNUSABLE = 'unusable'


    class UserDataFormatEnum(str, Enum):
        """
        The user data format for this image:
        - `cloud_init`: `user_data` will be interpreted according to the cloud-init
        standard
        - `esxi_kickstart`: `user_data` will be interpreted as a VMware ESXi installation
        script
        - `ipxe`: `user_data` will be interpreted as a single URL to an iPXE script or as
        the
          text of an iPXE script
        The value for this property is inherited from `operating_system.user_data_format`.
        """

        CLOUD_INIT = 'cloud_init'
        ESXI_KICKSTART = 'esxi_kickstart'
        IPXE = 'ipxe'


    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.

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

    def __init__(
        self,
        managed: bool,
        *,
        version: Optional['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 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 := _dict.get('managed')) is not None:
            args['managed'] = managed
        else:
            raise ValueError('Required property \'managed\' not present in ImageCatalogOffering JSON')
        if (version := _dict.get('version')) is not None:
            args['version'] = CatalogOfferingVersionReference.from_dict(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.

    :param PageLink first: A link to the first page of resources.
    :param List[Image] images: A page of images.
    :param int limit: The maximum number of resources that can be returned by the
          request.
    :param PageLink next: (optional) A link to the next page of resources. This
          property is present for all pages
          except the last page.
    :param int total_count: The total number of resources across all pages.
    """

    def __init__(
        self,
        first: 'PageLink',
        images: List['Image'],
        limit: int,
        total_count: int,
        *,
        next: Optional['PageLink'] = None,
    ) -> None:
        """
        Initialize a ImageCollection object.

        :param PageLink first: A link to the first page of resources.
        :param List[Image] images: A page 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 PageLink 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 := _dict.get('first')) is not None:
            args['first'] = PageLink.from_dict(first)
        else:
            raise ValueError('Required property \'first\' not present in ImageCollection JSON')
        if (images := _dict.get('images')) is not None:
            args['images'] = [Image.from_dict(v) for v in images]
        else:
            raise ValueError('Required property \'images\' not present in ImageCollection JSON')
        if (limit := _dict.get('limit')) is not None:
            args['limit'] = limit
        else:
            raise ValueError('Required property \'limit\' not present in ImageCollection JSON')
        if (next := _dict.get('next')) is not None:
            args['next'] = PageLink.from_dict(next)
        if (total_count := _dict.get('total_count')) is not None:
            args['total_count'] = 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 ImageExportJob:
    """
    ImageExportJob.

    :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 datetime created_at: The date and time that the image export job was
          created.
    :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 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 resource type.
    :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.
    :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.
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :param List[ImageExportJobStatusReason] status_reasons: The reasons for the
          current status (if any).
    :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.
    """

    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: Optional[datetime] = None,
        encrypted_data_key: Optional[bytes] = None,
        started_at: Optional[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 resource type.
        :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.
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :param List[ImageExportJobStatusReason] status_reasons: The reasons for the
               current status (if any).
        :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 := _dict.get('completed_at')) is not None:
            args['completed_at'] = string_to_datetime(completed_at)
        if (created_at := _dict.get('created_at')) is not None:
            args['created_at'] = string_to_datetime(created_at)
        else:
            raise ValueError('Required property \'created_at\' not present in ImageExportJob JSON')
        if (encrypted_data_key := _dict.get('encrypted_data_key')) is not None:
            args['encrypted_data_key'] = base64.b64decode(encrypted_data_key)
        if (format := _dict.get('format')) is not None:
            args['format'] = format
        else:
            raise ValueError('Required property \'format\' not present in ImageExportJob JSON')
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in ImageExportJob JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in ImageExportJob JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in ImageExportJob JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = resource_type
        else:
            raise ValueError('Required property \'resource_type\' not present in ImageExportJob JSON')
        if (started_at := _dict.get('started_at')) is not None:
            args['started_at'] = string_to_datetime(started_at)
        if (status := _dict.get('status')) is not None:
            args['status'] = status
        else:
            raise ValueError('Required property \'status\' not present in ImageExportJob JSON')
        if (status_reasons := _dict.get('status_reasons')) is not None:
            args['status_reasons'] = [ImageExportJobStatusReason.from_dict(v) for v in status_reasons]
        else:
            raise ValueError('Required property \'status_reasons\' not present in ImageExportJob JSON')
        if (storage_bucket := _dict.get('storage_bucket')) is not None:
            args['storage_bucket'] = CloudObjectStorageBucketReference.from_dict(storage_bucket)
        else:
            raise ValueError('Required property \'storage_bucket\' not present in ImageExportJob JSON')
        if (storage_href := _dict.get('storage_href')) is not None:
            args['storage_href'] = storage_href
        else:
            raise ValueError('Required property \'storage_href\' not present in ImageExportJob JSON')
        if (storage_object := _dict.get('storage_object')) is not None:
            args['storage_object'] = CloudObjectStorageObjectReference.from_dict(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 resource type.
        """

        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.
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        DELETING = 'deleting'
        FAILED = 'failed'
        QUEUED = 'queued'
        RUNNING = 'running'
        SUCCEEDED = 'succeeded'



class ImageExportJobPatch:
    """
    ImageExportJobPatch.

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

    def __init__(
        self,
        *,
        name: Optional[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 := _dict.get('name')) is not None:
            args['name'] = 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.

    :param str code: A snake case string succinctly identifying the status reason.
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :param str message: An explanation of the status reason.
    :param str more_info: (optional) Link to documentation about this status reason.
    """

    def __init__(
        self,
        code: str,
        message: str,
        *,
        more_info: Optional[str] = None,
    ) -> None:
        """
        Initialize a ImageExportJobStatusReason object.

        :param str code: A snake case string succinctly identifying the status
               reason.
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :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 := _dict.get('code')) is not None:
            args['code'] = code
        else:
            raise ValueError('Required property \'code\' not present in ImageExportJobStatusReason JSON')
        if (message := _dict.get('message')) is not None:
            args['message'] = message
        else:
            raise ValueError('Required property \'message\' not present in ImageExportJobStatusReason JSON')
        if (more_info := _dict.get('more_info')) is not None:
            args['more_info'] = 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.
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        CANNOT_ACCESS_STORAGE_BUCKET = 'cannot_access_storage_bucket'
        INTERNAL_ERROR = 'internal_error'



class ImageExportJobUnpaginatedCollection:
    """
    ImageExportJobUnpaginatedCollection.

    :param List[ImageExportJob] export_jobs: The export jobs for the image.
    """

    def __init__(
        self,
        export_jobs: List['ImageExportJob'],
    ) -> None:
        """
        Initialize a ImageExportJobUnpaginatedCollection object.

        :param List[ImageExportJob] export_jobs: The export jobs for the image.
        """
        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 := _dict.get('export_jobs')) is not None:
            args['export_jobs'] = [ImageExportJob.from_dict(v) for v in 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.

    :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`.
    """

    def __init__(
        self,
        *,
        checksums: Optional['ImageFileChecksums'] = None,
        size: Optional[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 := _dict.get('checksums')) is not None:
            args['checksums'] = ImageFileChecksums.from_dict(checksums)
        if (size := _dict.get('size')) is not None:
            args['size'] = 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.

    :param str sha256: (optional) The SHA256 fingerprint of the image file, in
          hexadecimal.
    """

    def __init__(
        self,
        *,
        sha256: Optional[str] = None,
    ) -> None:
        """
        Initialize a ImageFileChecksums object.

        :param str sha256: (optional) The SHA256 fingerprint of the image file, in
               hexadecimal.
        """
        self.sha256 = sha256

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ImageFileChecksums':
        """Initialize a ImageFileChecksums object from a json dictionary."""
        args = {}
        if (sha256 := _dict.get('sha256')) is not None:
            args['sha256'] = 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.

    :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`.
    """

    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 := _dict.get('href')) is not None:
            args['href'] = 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.

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

    def __init__(
        self,
        *,
        deprecation_at: Optional[datetime] = None,
        name: Optional[str] = None,
        obsolescence_at: Optional[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 := _dict.get('deprecation_at')) is not None:
            args['deprecation_at'] = string_to_datetime(deprecation_at)
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        if (obsolescence_at := _dict.get('obsolescence_at')) is not None:
            args['obsolescence_at'] = string_to_datetime(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.

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

    def __init__(
        self,
        *,
        deprecation_at: Optional[datetime] = None,
        name: Optional[str] = None,
        obsolescence_at: Optional[datetime] = None,
        resource_group: Optional['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.

    :param str crn: The CRN for this image.
    :param Deleted deleted: (optional) If present, this property indicates the
          referenced resource has been deleted, and provides
          some supplementary information.
    :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 ImageRemote remote: (optional) If present, this property indicates that
          the resource associated with this reference
          is remote and therefore may not be directly retrievable.
    :param str resource_type: The resource type.
    """

    def __init__(
        self,
        crn: str,
        href: str,
        id: str,
        name: str,
        resource_type: str,
        *,
        deleted: Optional['Deleted'] = None,
        remote: Optional['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 Deleted 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 := _dict.get('crn')) is not None:
            args['crn'] = crn
        else:
            raise ValueError('Required property \'crn\' not present in ImageReference JSON')
        if (deleted := _dict.get('deleted')) is not None:
            args['deleted'] = Deleted.from_dict(deleted)
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in ImageReference JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in ImageReference JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in ImageReference JSON')
        if (remote := _dict.get('remote')) is not None:
            args['remote'] = ImageRemote.from_dict(remote)
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = 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 ImageRemote:
    """
    If present, this property indicates that the resource associated with this reference
    is remote and therefore may not be directly retrievable.

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

    def __init__(
        self,
        *,
        account: Optional['AccountReference'] = None,
        region: Optional['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 := _dict.get('account')) is not None:
            args['account'] = AccountReference.from_dict(account)
        if (region := _dict.get('region')) is not None:
            args['region'] = RegionReference.from_dict(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.

    :param str code: A reason code for the status:
          - `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 values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :param str message: An explanation of the status reason.
    :param str more_info: (optional) Link to documentation about this status reason.
    """

    def __init__(
        self,
        code: str,
        message: str,
        *,
        more_info: Optional[str] = None,
    ) -> None:
        """
        Initialize a ImageStatusReason object.

        :param str code: A reason code for the status:
               - `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 values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :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 := _dict.get('code')) is not None:
            args['code'] = code
        else:
            raise ValueError('Required property \'code\' not present in ImageStatusReason JSON')
        if (message := _dict.get('message')) is not None:
            args['message'] = message
        else:
            raise ValueError('Required property \'message\' not present in ImageStatusReason JSON')
        if (more_info := _dict.get('more_info')) is not None:
            args['more_info'] = 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 reason code for the status:
        - `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 values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        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.

    :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 attachments or instance network interfaces and storage
          volumes of the virtual server instance.
    :param VolumeAttachmentReferenceInstanceContext boot_volume_attachment: Boot
          volume attachment.
    :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 ClusterNetworkReference cluster_network: (optional) If present, the
          cluster network that this virtual server instance resides in.
    :param List[InstanceClusterNetworkAttachmentReference]
          cluster_network_attachments: The cluster network attachments for this virtual
          server instance.
          The cluster network attachments are ordered for consistent instance
          configuration.
    :param str confidential_compute_mode: The confidential compute mode for this
          virtual server instance.
    :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 DedicatedHostReference dedicated_host: (optional) If present, the
          dedicated host this virtual server instance has been placed on.
    :param List[InstanceDisk] disks: The instance disks for this virtual server
          instance.
    :param bool enable_secure_boot: Indicates whether secure boot is enabled for
          this virtual server instance.
    :param InstanceGPU gpu: (optional) The virtual server instance GPU
          configuration.
    :param List[InstanceHealthReason] health_reasons: The reasons for the current
          `health_state` (if any).
    :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 virtual server instance.
    :param str id: The unique identifier for this virtual server instance.
    :param ImageReference image: (optional) The image the virtual server instance
          was provisioned from.
    :param List[InstanceLifecycleReason] lifecycle_reasons: The reasons for the
          current `lifecycle_state` (if any).
    :param str lifecycle_state: The lifecycle state of the virtual server instance.
    :param int memory: The amount of memory, truncated to whole gibibytes.
          The maximum limit for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :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[InstanceNetworkAttachmentReference] network_attachments: The network
          attachments for this virtual server instance, including the primary network
          attachment.
    :param List[NetworkInterfaceInstanceContextReference] network_interfaces: The
          network interfaces for this instance, including the primary network interface.
          If this instance has network attachments, each network interface is a [read-only
          representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
          of its corresponding network attachment and its attached virtual network
          interface.
    :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.
    :param InstanceNetworkAttachmentReference primary_network_attachment: (optional)
          The primary network attachment for this virtual server instance.
    :param NetworkInterfaceInstanceContextReference primary_network_interface: The
          primary network interface for this virtual server instance.
          If this instance has network attachments, this primary network interface is a
          [read-only
          representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
          of the primary network attachment and its attached virtual network interface.
    :param InstanceProfileReference profile: The
          [profile](https://cloud.ibm.com/docs/vpc?topic=vpc-profiles) for this virtual
          server instance.
    :param ReservationReference reservation: (optional) The reservation used by this
          virtual server instance.
          If absent, no reservation is in use.
    :param InstanceReservationAffinity reservation_affinity:
    :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 may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :param List[InstanceStatusReason] status_reasons: The reasons for the current
          status (if any).
    :param int total_network_bandwidth: The amount of bandwidth (in megabits per
          second) allocated exclusively to instance network attachments or 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.
    """

    def __init__(
        self,
        availability_policy: 'InstanceAvailabilityPolicy',
        bandwidth: int,
        boot_volume_attachment: 'VolumeAttachmentReferenceInstanceContext',
        cluster_network_attachments: List['InstanceClusterNetworkAttachmentReference'],
        confidential_compute_mode: str,
        created_at: datetime,
        crn: str,
        disks: List['InstanceDisk'],
        enable_secure_boot: bool,
        health_reasons: List['InstanceHealthReason'],
        health_state: str,
        href: str,
        id: str,
        lifecycle_reasons: List['InstanceLifecycleReason'],
        lifecycle_state: str,
        memory: int,
        metadata_service: 'InstanceMetadataService',
        name: str,
        network_attachments: List['InstanceNetworkAttachmentReference'],
        network_interfaces: List['NetworkInterfaceInstanceContextReference'],
        primary_network_interface: 'NetworkInterfaceInstanceContextReference',
        profile: 'InstanceProfileReference',
        reservation_affinity: 'InstanceReservationAffinity',
        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: Optional['InstanceCatalogOffering'] = None,
        cluster_network: Optional['ClusterNetworkReference'] = None,
        dedicated_host: Optional['DedicatedHostReference'] = None,
        gpu: Optional['InstanceGPU'] = None,
        image: Optional['ImageReference'] = None,
        numa_count: Optional[int] = None,
        placement_target: Optional['InstancePlacementTarget'] = None,
        primary_network_attachment: Optional['InstanceNetworkAttachmentReference'] = None,
        reservation: Optional['ReservationReference'] = 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 attachments or instance network interfaces and
               storage volumes of the virtual server instance.
        :param VolumeAttachmentReferenceInstanceContext boot_volume_attachment:
               Boot volume attachment.
        :param List[InstanceClusterNetworkAttachmentReference]
               cluster_network_attachments: The cluster network attachments for this
               virtual server instance.
               The cluster network attachments are ordered for consistent instance
               configuration.
        :param str confidential_compute_mode: The confidential compute mode for
               this virtual server instance.
        :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 bool enable_secure_boot: Indicates whether secure boot is enabled
               for this virtual server instance.
        :param List[InstanceHealthReason] health_reasons: The reasons for the
               current `health_state` (if any).
        :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 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).
        :param str lifecycle_state: The lifecycle state of the virtual server
               instance.
        :param int memory: The amount of memory, truncated to whole gibibytes.
               The maximum limit for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :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[InstanceNetworkAttachmentReference] network_attachments: The
               network attachments for this virtual server instance, including the primary
               network attachment.
        :param List[NetworkInterfaceInstanceContextReference] network_interfaces:
               The network interfaces for this instance, including the primary network
               interface.
               If this instance has network attachments, each network interface is a
               [read-only
               representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
               of its corresponding network attachment and its attached virtual network
               interface.
        :param NetworkInterfaceInstanceContextReference primary_network_interface:
               The primary network interface for this virtual server instance.
               If this instance has network attachments, this primary network interface is
               a
               [read-only
               representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
               of the primary network attachment and its attached virtual network
               interface.
        :param InstanceProfileReference profile: The
               [profile](https://cloud.ibm.com/docs/vpc?topic=vpc-profiles) for this
               virtual
               server instance.
        :param InstanceReservationAffinity reservation_affinity:
        :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 may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :param List[InstanceStatusReason] status_reasons: The reasons for the
               current status (if any).
        :param int total_network_bandwidth: The amount of bandwidth (in megabits
               per second) allocated exclusively to instance network attachments or
               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 ClusterNetworkReference cluster_network: (optional) If present, the
               cluster network that this virtual server instance resides in.
        :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.
        :param InstanceNetworkAttachmentReference primary_network_attachment:
               (optional) The primary network attachment for this virtual server instance.
        :param ReservationReference reservation: (optional) The reservation used by
               this virtual server instance.
               If absent, no reservation is in use.
        """
        self.availability_policy = availability_policy
        self.bandwidth = bandwidth
        self.boot_volume_attachment = boot_volume_attachment
        self.catalog_offering = catalog_offering
        self.cluster_network = cluster_network
        self.cluster_network_attachments = cluster_network_attachments
        self.confidential_compute_mode = confidential_compute_mode
        self.created_at = created_at
        self.crn = crn
        self.dedicated_host = dedicated_host
        self.disks = disks
        self.enable_secure_boot = enable_secure_boot
        self.gpu = gpu
        self.health_reasons = health_reasons
        self.health_state = health_state
        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_attachments = network_attachments
        self.network_interfaces = network_interfaces
        self.numa_count = numa_count
        self.placement_target = placement_target
        self.primary_network_attachment = primary_network_attachment
        self.primary_network_interface = primary_network_interface
        self.profile = profile
        self.reservation = reservation
        self.reservation_affinity = reservation_affinity
        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 := _dict.get('availability_policy')) is not None:
            args['availability_policy'] = InstanceAvailabilityPolicy.from_dict(availability_policy)
        else:
            raise ValueError('Required property \'availability_policy\' not present in Instance JSON')
        if (bandwidth := _dict.get('bandwidth')) is not None:
            args['bandwidth'] = bandwidth
        else:
            raise ValueError('Required property \'bandwidth\' not present in Instance JSON')
        if (boot_volume_attachment := _dict.get('boot_volume_attachment')) is not None:
            args['boot_volume_attachment'] = VolumeAttachmentReferenceInstanceContext.from_dict(boot_volume_attachment)
        else:
            raise ValueError('Required property \'boot_volume_attachment\' not present in Instance JSON')
        if (catalog_offering := _dict.get('catalog_offering')) is not None:
            args['catalog_offering'] = InstanceCatalogOffering.from_dict(catalog_offering)
        if (cluster_network := _dict.get('cluster_network')) is not None:
            args['cluster_network'] = ClusterNetworkReference.from_dict(cluster_network)
        if (cluster_network_attachments := _dict.get('cluster_network_attachments')) is not None:
            args['cluster_network_attachments'] = [InstanceClusterNetworkAttachmentReference.from_dict(v) for v in cluster_network_attachments]
        else:
            raise ValueError('Required property \'cluster_network_attachments\' not present in Instance JSON')
        if (confidential_compute_mode := _dict.get('confidential_compute_mode')) is not None:
            args['confidential_compute_mode'] = confidential_compute_mode
        else:
            raise ValueError('Required property \'confidential_compute_mode\' not present in Instance JSON')
        if (created_at := _dict.get('created_at')) is not None:
            args['created_at'] = string_to_datetime(created_at)
        else:
            raise ValueError('Required property \'created_at\' not present in Instance JSON')
        if (crn := _dict.get('crn')) is not None:
            args['crn'] = crn
        else:
            raise ValueError('Required property \'crn\' not present in Instance JSON')
        if (dedicated_host := _dict.get('dedicated_host')) is not None:
            args['dedicated_host'] = DedicatedHostReference.from_dict(dedicated_host)
        if (disks := _dict.get('disks')) is not None:
            args['disks'] = [InstanceDisk.from_dict(v) for v in disks]
        else:
            raise ValueError('Required property \'disks\' not present in Instance JSON')
        if (enable_secure_boot := _dict.get('enable_secure_boot')) is not None:
            args['enable_secure_boot'] = enable_secure_boot
        else:
            raise ValueError('Required property \'enable_secure_boot\' not present in Instance JSON')
        if (gpu := _dict.get('gpu')) is not None:
            args['gpu'] = InstanceGPU.from_dict(gpu)
        if (health_reasons := _dict.get('health_reasons')) is not None:
            args['health_reasons'] = [InstanceHealthReason.from_dict(v) for v in health_reasons]
        else:
            raise ValueError('Required property \'health_reasons\' not present in Instance JSON')
        if (health_state := _dict.get('health_state')) is not None:
            args['health_state'] = health_state
        else:
            raise ValueError('Required property \'health_state\' not present in Instance JSON')
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in Instance JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in Instance JSON')
        if (image := _dict.get('image')) is not None:
            args['image'] = ImageReference.from_dict(image)
        if (lifecycle_reasons := _dict.get('lifecycle_reasons')) is not None:
            args['lifecycle_reasons'] = [InstanceLifecycleReason.from_dict(v) for v in lifecycle_reasons]
        else:
            raise ValueError('Required property \'lifecycle_reasons\' not present in Instance JSON')
        if (lifecycle_state := _dict.get('lifecycle_state')) is not None:
            args['lifecycle_state'] = lifecycle_state
        else:
            raise ValueError('Required property \'lifecycle_state\' not present in Instance JSON')
        if (memory := _dict.get('memory')) is not None:
            args['memory'] = memory
        else:
            raise ValueError('Required property \'memory\' not present in Instance JSON')
        if (metadata_service := _dict.get('metadata_service')) is not None:
            args['metadata_service'] = InstanceMetadataService.from_dict(metadata_service)
        else:
            raise ValueError('Required property \'metadata_service\' not present in Instance JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in Instance JSON')
        if (network_attachments := _dict.get('network_attachments')) is not None:
            args['network_attachments'] = [InstanceNetworkAttachmentReference.from_dict(v) for v in network_attachments]
        else:
            raise ValueError('Required property \'network_attachments\' not present in Instance JSON')
        if (network_interfaces := _dict.get('network_interfaces')) is not None:
            args['network_interfaces'] = [NetworkInterfaceInstanceContextReference.from_dict(v) for v in network_interfaces]
        else:
            raise ValueError('Required property \'network_interfaces\' not present in Instance JSON')
        if (numa_count := _dict.get('numa_count')) is not None:
            args['numa_count'] = numa_count
        if (placement_target := _dict.get('placement_target')) is not None:
            args['placement_target'] = placement_target
        if (primary_network_attachment := _dict.get('primary_network_attachment')) is not None:
            args['primary_network_attachment'] = InstanceNetworkAttachmentReference.from_dict(primary_network_attachment)
        if (primary_network_interface := _dict.get('primary_network_interface')) is not None:
            args['primary_network_interface'] = NetworkInterfaceInstanceContextReference.from_dict(primary_network_interface)
        else:
            raise ValueError('Required property \'primary_network_interface\' not present in Instance JSON')
        if (profile := _dict.get('profile')) is not None:
            args['profile'] = InstanceProfileReference.from_dict(profile)
        else:
            raise ValueError('Required property \'profile\' not present in Instance JSON')
        if (reservation := _dict.get('reservation')) is not None:
            args['reservation'] = ReservationReference.from_dict(reservation)
        if (reservation_affinity := _dict.get('reservation_affinity')) is not None:
            args['reservation_affinity'] = InstanceReservationAffinity.from_dict(reservation_affinity)
        else:
            raise ValueError('Required property \'reservation_affinity\' not present in Instance JSON')
        if (resource_group := _dict.get('resource_group')) is not None:
            args['resource_group'] = ResourceGroupReference.from_dict(resource_group)
        else:
            raise ValueError('Required property \'resource_group\' not present in Instance JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = resource_type
        else:
            raise ValueError('Required property \'resource_type\' not present in Instance JSON')
        if (startable := _dict.get('startable')) is not None:
            args['startable'] = startable
        else:
            raise ValueError('Required property \'startable\' not present in Instance JSON')
        if (status := _dict.get('status')) is not None:
            args['status'] = status
        else:
            raise ValueError('Required property \'status\' not present in Instance JSON')
        if (status_reasons := _dict.get('status_reasons')) is not None:
            args['status_reasons'] = [InstanceStatusReason.from_dict(v) for v in status_reasons]
        else:
            raise ValueError('Required property \'status_reasons\' not present in Instance JSON')
        if (total_network_bandwidth := _dict.get('total_network_bandwidth')) is not None:
            args['total_network_bandwidth'] = total_network_bandwidth
        else:
            raise ValueError('Required property \'total_network_bandwidth\' not present in Instance JSON')
        if (total_volume_bandwidth := _dict.get('total_volume_bandwidth')) is not None:
            args['total_volume_bandwidth'] = total_volume_bandwidth
        else:
            raise ValueError('Required property \'total_volume_bandwidth\' not present in Instance JSON')
        if (vcpu := _dict.get('vcpu')) is not None:
            args['vcpu'] = InstanceVCPU.from_dict(vcpu)
        else:
            raise ValueError('Required property \'vcpu\' not present in Instance JSON')
        if (volume_attachments := _dict.get('volume_attachments')) is not None:
            args['volume_attachments'] = [VolumeAttachmentReferenceInstanceContext.from_dict(v) for v in volume_attachments]
        else:
            raise ValueError('Required property \'volume_attachments\' not present in Instance JSON')
        if (vpc := _dict.get('vpc')) is not None:
            args['vpc'] = VPCReference.from_dict(vpc)
        else:
            raise ValueError('Required property \'vpc\' not present in Instance JSON')
        if (zone := _dict.get('zone')) is not None:
            args['zone'] = ZoneReference.from_dict(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, 'cluster_network') and self.cluster_network is not None:
            if isinstance(self.cluster_network, dict):
                _dict['cluster_network'] = self.cluster_network
            else:
                _dict['cluster_network'] = self.cluster_network.to_dict()
        if hasattr(self, 'cluster_network_attachments') and self.cluster_network_attachments is not None:
            cluster_network_attachments_list = []
            for v in self.cluster_network_attachments:
                if isinstance(v, dict):
                    cluster_network_attachments_list.append(v)
                else:
                    cluster_network_attachments_list.append(v.to_dict())
            _dict['cluster_network_attachments'] = cluster_network_attachments_list
        if hasattr(self, 'confidential_compute_mode') and self.confidential_compute_mode is not None:
            _dict['confidential_compute_mode'] = self.confidential_compute_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, '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, 'enable_secure_boot') and self.enable_secure_boot is not None:
            _dict['enable_secure_boot'] = self.enable_secure_boot
        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, '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, '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_attachments') and self.network_attachments is not None:
            network_attachments_list = []
            for v in self.network_attachments:
                if isinstance(v, dict):
                    network_attachments_list.append(v)
                else:
                    network_attachments_list.append(v.to_dict())
            _dict['network_attachments'] = network_attachments_list
        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_attachment') and self.primary_network_attachment is not None:
            if isinstance(self.primary_network_attachment, dict):
                _dict['primary_network_attachment'] = self.primary_network_attachment
            else:
                _dict['primary_network_attachment'] = self.primary_network_attachment.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, 'reservation') and self.reservation is not None:
            if isinstance(self.reservation, dict):
                _dict['reservation'] = self.reservation
            else:
                _dict['reservation'] = self.reservation.to_dict()
        if hasattr(self, 'reservation_affinity') and self.reservation_affinity is not None:
            if isinstance(self.reservation_affinity, dict):
                _dict['reservation_affinity'] = self.reservation_affinity
            else:
                _dict['reservation_affinity'] = self.reservation_affinity.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 ConfidentialComputeModeEnum(str, Enum):
        """
        The confidential compute mode for this virtual server instance.
        """

        DISABLED = 'disabled'
        SGX = 'sgx'


    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 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 may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        DELETING = 'deleting'
        FAILED = 'failed'
        PENDING = 'pending'
        RESTARTING = 'restarting'
        RUNNING = 'running'
        STARTING = 'starting'
        STOPPED = 'stopped'
        STOPPING = 'stopping'



class InstanceAction:
    """
    InstanceAction.

    :param datetime completed_at: (optional) Deprecated: The date and time that the
          action was completed.
    :param datetime created_at: The date and time that the action was created.
    :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 str href: Deprecated: The URL for this instance action.
    :param str id: Deprecated: The identifier for this instance action.
    :param datetime started_at: (optional) Deprecated: The date and time that the
          action was started.
    :param str status: Deprecated: The current status of this action.
    :param str type: The type of action.
    """

    def __init__(
        self,
        created_at: datetime,
        href: str,
        id: str,
        status: str,
        type: str,
        *,
        completed_at: Optional[datetime] = None,
        force: Optional[bool] = None,
        started_at: Optional[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 := _dict.get('completed_at')) is not None:
            args['completed_at'] = string_to_datetime(completed_at)
        if (created_at := _dict.get('created_at')) is not None:
            args['created_at'] = string_to_datetime(created_at)
        else:
            raise ValueError('Required property \'created_at\' not present in InstanceAction JSON')
        if (force := _dict.get('force')) is not None:
            args['force'] = force
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in InstanceAction JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in InstanceAction JSON')
        if (started_at := _dict.get('started_at')) is not None:
            args['started_at'] = string_to_datetime(started_at)
        if (status := _dict.get('status')) is not None:
            args['status'] = status
        else:
            raise ValueError('Required property \'status\' not present in InstanceAction JSON')
        if (type := _dict.get('type')) is not None:
            args['type'] = 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.

    :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 may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    """

    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 may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        """
        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 := _dict.get('host_failure')) is not None:
            args['host_failure'] = 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 may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        RESTART = 'restart'
        STOP = 'stop'



class InstanceAvailabilityPolicyPatch:
    """
    InstanceAvailabilityPolicyPatch.

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

    def __init__(
        self,
        *,
        host_failure: Optional[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 := _dict.get('host_failure')) is not None:
            args['host_failure'] = 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.

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

    def __init__(
        self,
        *,
        host_failure: Optional[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 := _dict.get('host_failure')) is not None:
            args['host_failure'] = 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.

    :param CatalogOfferingVersionPlanReference plan: (optional) The billing plan
          used for the catalog offering version.
          If absent, no billing plan is in use (free).
    :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.
    """

    def __init__(
        self,
        version: 'CatalogOfferingVersionReference',
        *,
        plan: Optional['CatalogOfferingVersionPlanReference'] = None,
    ) -> 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.
        :param CatalogOfferingVersionPlanReference plan: (optional) The billing
               plan used for the catalog offering version.
               If absent, no billing plan is in use (free).
        """
        self.plan = plan
        self.version = version

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceCatalogOffering':
        """Initialize a InstanceCatalogOffering object from a json dictionary."""
        args = {}
        if (plan := _dict.get('plan')) is not None:
            args['plan'] = CatalogOfferingVersionPlanReference.from_dict(plan)
        if (version := _dict.get('version')) is not None:
            args['version'] = CatalogOfferingVersionReference.from_dict(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, 'plan') and self.plan is not None:
            if isinstance(self.plan, dict):
                _dict['plan'] = self.plan
            else:
                _dict['plan'] = self.plan.to_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, subject to
    IAM policies.

    :param CatalogOfferingVersionPlanIdentity plan: (optional) The billing plan to
          use for the catalog offering version. If unspecified, no billing
          plan will be used (free). Must be specified for catalog offering versions that
          require
          a billing plan to be used.
    """

    def __init__(
        self,
        *,
        plan: Optional['CatalogOfferingVersionPlanIdentity'] = None,
    ) -> None:
        """
        Initialize a InstanceCatalogOfferingPrototype object.

        :param CatalogOfferingVersionPlanIdentity plan: (optional) The billing plan
               to use for the catalog offering version. If unspecified, no billing
               plan will be used (free). Must be specified for catalog offering versions
               that require
               a billing plan to be used.
        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['InstanceCatalogOfferingPrototypeCatalogOfferingByOffering', 'InstanceCatalogOfferingPrototypeCatalogOfferingByVersion'])
        )
        raise Exception(msg)


class InstanceClusterNetworkAttachment:
    """
    InstanceClusterNetworkAttachment.

    :param InstanceClusterNetworkAttachmentBefore before: (optional) The instance
          cluster network attachment that is immediately before. If absent, this is the
          last instance cluster network attachment.
    :param ClusterNetworkInterfaceReference cluster_network_interface: The cluster
          network interface for this instance cluster network attachment.
    :param str href: The URL for this instance cluster network attachment.
    :param str id: The unique identifier for this instance cluster network
          attachment.
    :param List[InstanceClusterNetworkAttachmentLifecycleReason] lifecycle_reasons:
          The reasons for the current `lifecycle_state` (if any).
    :param str lifecycle_state: The lifecycle state of the instance cluster network
          attachment.
    :param str name: The name for this instance cluster network attachment. The name
          is unique across all network attachments for the instance.
    :param str resource_type: The resource type.
    """

    def __init__(
        self,
        cluster_network_interface: 'ClusterNetworkInterfaceReference',
        href: str,
        id: str,
        lifecycle_reasons: List['InstanceClusterNetworkAttachmentLifecycleReason'],
        lifecycle_state: str,
        name: str,
        resource_type: str,
        *,
        before: Optional['InstanceClusterNetworkAttachmentBefore'] = None,
    ) -> None:
        """
        Initialize a InstanceClusterNetworkAttachment object.

        :param ClusterNetworkInterfaceReference cluster_network_interface: The
               cluster network interface for this instance cluster network attachment.
        :param str href: The URL for this instance cluster network attachment.
        :param str id: The unique identifier for this instance cluster network
               attachment.
        :param List[InstanceClusterNetworkAttachmentLifecycleReason]
               lifecycle_reasons: The reasons for the current `lifecycle_state` (if any).
        :param str lifecycle_state: The lifecycle state of the instance cluster
               network attachment.
        :param str name: The name for this instance cluster network attachment. The
               name is unique across all network attachments for the instance.
        :param str resource_type: The resource type.
        :param InstanceClusterNetworkAttachmentBefore before: (optional) The
               instance cluster network attachment that is immediately before. If absent,
               this is the
               last instance cluster network attachment.
        """
        self.before = before
        self.cluster_network_interface = cluster_network_interface
        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) -> 'InstanceClusterNetworkAttachment':
        """Initialize a InstanceClusterNetworkAttachment object from a json dictionary."""
        args = {}
        if (before := _dict.get('before')) is not None:
            args['before'] = InstanceClusterNetworkAttachmentBefore.from_dict(before)
        if (cluster_network_interface := _dict.get('cluster_network_interface')) is not None:
            args['cluster_network_interface'] = ClusterNetworkInterfaceReference.from_dict(cluster_network_interface)
        else:
            raise ValueError('Required property \'cluster_network_interface\' not present in InstanceClusterNetworkAttachment JSON')
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in InstanceClusterNetworkAttachment JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in InstanceClusterNetworkAttachment JSON')
        if (lifecycle_reasons := _dict.get('lifecycle_reasons')) is not None:
            args['lifecycle_reasons'] = [InstanceClusterNetworkAttachmentLifecycleReason.from_dict(v) for v in lifecycle_reasons]
        else:
            raise ValueError('Required property \'lifecycle_reasons\' not present in InstanceClusterNetworkAttachment JSON')
        if (lifecycle_state := _dict.get('lifecycle_state')) is not None:
            args['lifecycle_state'] = lifecycle_state
        else:
            raise ValueError('Required property \'lifecycle_state\' not present in InstanceClusterNetworkAttachment JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in InstanceClusterNetworkAttachment JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = resource_type
        else:
            raise ValueError('Required property \'resource_type\' not present in InstanceClusterNetworkAttachment JSON')
        return cls(**args)

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

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

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

    def __ne__(self, other: 'InstanceClusterNetworkAttachment') -> 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 instance cluster network attachment.
        """

        DELETING = 'deleting'
        FAILED = 'failed'
        PENDING = 'pending'
        STABLE = 'stable'
        SUSPENDED = 'suspended'
        UPDATING = 'updating'
        WAITING = 'waiting'


    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        INSTANCE_CLUSTER_NETWORK_ATTACHMENT = 'instance_cluster_network_attachment'



class InstanceClusterNetworkAttachmentBefore:
    """
    The instance cluster network attachment that is immediately before. If absent, this is
    the last instance cluster network attachment.

    :param str href: The URL for this instance cluster network attachment.
    :param str id: The unique identifier for this instance cluster network
          attachment.
    :param str name: The name for this instance cluster network attachment. The name
          is unique across all network attachments for the instance.
    :param str resource_type: The resource type.
    """

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

        :param str href: The URL for this instance cluster network attachment.
        :param str id: The unique identifier for this instance cluster network
               attachment.
        :param str name: The name for this instance cluster network attachment. The
               name is unique across all network attachments for the instance.
        :param str resource_type: The resource type.
        """
        self.href = href
        self.id = id
        self.name = name
        self.resource_type = resource_type

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

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

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

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

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

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

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

    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        INSTANCE_CLUSTER_NETWORK_ATTACHMENT = 'instance_cluster_network_attachment'



class InstanceClusterNetworkAttachmentBeforePrototype:
    """
    The instance cluster network attachment to insert this instance cluster network
    attachment immediately before.
    If unspecified, this instance cluster network attachment will be inserted after all
    existing instance cluster network attachments.

    """

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

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


class InstanceClusterNetworkAttachmentCollection:
    """
    InstanceClusterNetworkAttachmentCollection.

    :param List[InstanceClusterNetworkAttachment] cluster_network_attachments: A
          page of ordered cluster network attachments (sorted based on the `before`
          property) for the instance. A cluster network attachment represents a device to
          which a cluster network interface is attached.
    :param PageLink 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 PageLink next: (optional) A link to the next page of resources. This
          property is present for all pages
          except the last page.
    :param int total_count: The total number of resources across all pages.
    """

    def __init__(
        self,
        cluster_network_attachments: List['InstanceClusterNetworkAttachment'],
        first: 'PageLink',
        limit: int,
        total_count: int,
        *,
        next: Optional['PageLink'] = None,
    ) -> None:
        """
        Initialize a InstanceClusterNetworkAttachmentCollection object.

        :param List[InstanceClusterNetworkAttachment] cluster_network_attachments:
               A page of ordered cluster network attachments (sorted based on the `before`
               property) for the instance. A cluster network attachment represents a
               device to which a cluster network interface is attached.
        :param PageLink 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 PageLink next: (optional) A link to the next page of resources. This
               property is present for all pages
               except the last page.
        """
        self.cluster_network_attachments = cluster_network_attachments
        self.first = first
        self.limit = limit
        self.next = next
        self.total_count = total_count

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceClusterNetworkAttachmentCollection':
        """Initialize a InstanceClusterNetworkAttachmentCollection object from a json dictionary."""
        args = {}
        if (cluster_network_attachments := _dict.get('cluster_network_attachments')) is not None:
            args['cluster_network_attachments'] = [InstanceClusterNetworkAttachment.from_dict(v) for v in cluster_network_attachments]
        else:
            raise ValueError('Required property \'cluster_network_attachments\' not present in InstanceClusterNetworkAttachmentCollection JSON')
        if (first := _dict.get('first')) is not None:
            args['first'] = PageLink.from_dict(first)
        else:
            raise ValueError('Required property \'first\' not present in InstanceClusterNetworkAttachmentCollection JSON')
        if (limit := _dict.get('limit')) is not None:
            args['limit'] = limit
        else:
            raise ValueError('Required property \'limit\' not present in InstanceClusterNetworkAttachmentCollection JSON')
        if (next := _dict.get('next')) is not None:
            args['next'] = PageLink.from_dict(next)
        if (total_count := _dict.get('total_count')) is not None:
            args['total_count'] = total_count
        else:
            raise ValueError('Required property \'total_count\' not present in InstanceClusterNetworkAttachmentCollection JSON')
        return cls(**args)

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

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'cluster_network_attachments') and self.cluster_network_attachments is not None:
            cluster_network_attachments_list = []
            for v in self.cluster_network_attachments:
                if isinstance(v, dict):
                    cluster_network_attachments_list.append(v)
                else:
                    cluster_network_attachments_list.append(v.to_dict())
            _dict['cluster_network_attachments'] = cluster_network_attachments_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 InstanceClusterNetworkAttachmentCollection object."""
        return json.dumps(self.to_dict(), indent=2)

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

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


class InstanceClusterNetworkAttachmentLifecycleReason:
    """
    InstanceClusterNetworkAttachmentLifecycleReason.

    :param str code: A reason code for this lifecycle state:
          - `internal_error`: internal error (contact IBM support)
          - `resource_suspended_by_provider`: The resource has been suspended (contact IBM
            support)
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :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.
    """

    def __init__(
        self,
        code: str,
        message: str,
        *,
        more_info: Optional[str] = None,
    ) -> None:
        """
        Initialize a InstanceClusterNetworkAttachmentLifecycleReason object.

        :param str code: A reason code for this lifecycle state:
               - `internal_error`: internal error (contact IBM support)
               - `resource_suspended_by_provider`: The resource has been suspended
               (contact IBM
                 support)
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :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) -> 'InstanceClusterNetworkAttachmentLifecycleReason':
        """Initialize a InstanceClusterNetworkAttachmentLifecycleReason object from a json dictionary."""
        args = {}
        if (code := _dict.get('code')) is not None:
            args['code'] = code
        else:
            raise ValueError('Required property \'code\' not present in InstanceClusterNetworkAttachmentLifecycleReason JSON')
        if (message := _dict.get('message')) is not None:
            args['message'] = message
        else:
            raise ValueError('Required property \'message\' not present in InstanceClusterNetworkAttachmentLifecycleReason JSON')
        if (more_info := _dict.get('more_info')) is not None:
            args['more_info'] = more_info
        return cls(**args)

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

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

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

    class CodeEnum(str, Enum):
        """
        A reason code for this lifecycle state:
        - `internal_error`: internal error (contact IBM support)
        - `resource_suspended_by_provider`: The resource has been suspended (contact IBM
          support)
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        INTERNAL_ERROR = 'internal_error'
        RESOURCE_SUSPENDED_BY_PROVIDER = 'resource_suspended_by_provider'



class InstanceClusterNetworkAttachmentPatch:
    """
    InstanceClusterNetworkAttachmentPatch.

    :param str name: (optional) The name for this network attachment. The name must
          not be used by another network attachment for the instance. Names starting with
          `ibm-` are reserved for provider-owned resources, and are not allowed.
    """

    def __init__(
        self,
        *,
        name: Optional[str] = None,
    ) -> None:
        """
        Initialize a InstanceClusterNetworkAttachmentPatch object.

        :param str name: (optional) The name for this network attachment. The name
               must not be used by another network attachment for the instance. Names
               starting with `ibm-` are reserved for provider-owned resources, and are not
               allowed.
        """
        self.name = name

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

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

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

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


class InstanceClusterNetworkAttachmentPrototypeClusterNetworkInterface:
    """
    A cluster network interface for the instance cluster network attachment. This can be
    specified using an existing cluster network interface that does not already have a
    `target`, or a prototype object for a new cluster network interface.
    This instance must reside in the same VPC as the specified cluster network interface.
    The cluster network interface must reside in the same cluster network as the
    `cluster_network_interface` of any other `cluster_network_attachments` for this
    instance.

    """

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

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


class InstanceClusterNetworkAttachmentPrototypeInstanceContext:
    """
    InstanceClusterNetworkAttachmentPrototypeInstanceContext.

    :param InstanceClusterNetworkAttachmentPrototypeClusterNetworkInterface
          cluster_network_interface: A cluster network interface for the instance cluster
          network attachment. This can be
          specified using an existing cluster network interface that does not already have
          a `target`,
          or a prototype object for a new cluster network interface.
          This instance must reside in the same VPC as the specified cluster network
          interface. The
          cluster network interface must reside in the same cluster network as the
          `cluster_network_interface` of any other `cluster_network_attachments` for this
          instance.
    :param str name: (optional) The name for this cluster network attachment. Names
          must be unique within the instance the cluster network attachment resides in. If
          unspecified, the name will be a hyphenated list of randomly-selected words.
          Names starting with `ibm-` are reserved for provider-owned resources, and are
          not allowed.
    """

    def __init__(
        self,
        cluster_network_interface: 'InstanceClusterNetworkAttachmentPrototypeClusterNetworkInterface',
        *,
        name: Optional[str] = None,
    ) -> None:
        """
        Initialize a InstanceClusterNetworkAttachmentPrototypeInstanceContext object.

        :param InstanceClusterNetworkAttachmentPrototypeClusterNetworkInterface
               cluster_network_interface: A cluster network interface for the instance
               cluster network attachment. This can be
               specified using an existing cluster network interface that does not already
               have a `target`,
               or a prototype object for a new cluster network interface.
               This instance must reside in the same VPC as the specified cluster network
               interface. The
               cluster network interface must reside in the same cluster network as the
               `cluster_network_interface` of any other `cluster_network_attachments` for
               this instance.
        :param str name: (optional) The name for this cluster network attachment.
               Names must be unique within the instance the cluster network attachment
               resides in. If unspecified, the name will be a hyphenated list of
               randomly-selected words. Names starting with `ibm-` are reserved for
               provider-owned resources, and are not allowed.
        """
        self.cluster_network_interface = cluster_network_interface
        self.name = name

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

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

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

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

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


class InstanceClusterNetworkAttachmentReference:
    """
    InstanceClusterNetworkAttachmentReference.

    :param str href: The URL for this instance cluster network attachment.
    :param str id: The unique identifier for this instance cluster network
          attachment.
    :param str name: The name for this instance cluster network attachment. The name
          is unique across all network attachments for the instance.
    :param str resource_type: The resource type.
    """

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

        :param str href: The URL for this instance cluster network attachment.
        :param str id: The unique identifier for this instance cluster network
               attachment.
        :param str name: The name for this instance cluster network attachment. The
               name is unique across all network attachments for the instance.
        :param str resource_type: The resource type.
        """
        self.href = href
        self.id = id
        self.name = name
        self.resource_type = resource_type

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

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

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

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

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

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

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

    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        INSTANCE_CLUSTER_NETWORK_ATTACHMENT = 'instance_cluster_network_attachment'



class InstanceCollection:
    """
    InstanceCollection.

    :param PageLink first: A link to the first page of resources.
    :param List[Instance] instances: A page of virtual server instances.
    :param int limit: The maximum number of resources that can be returned by the
          request.
    :param PageLink next: (optional) A link to the next page of resources. This
          property is present for all pages
          except the last page.
    :param int total_count: The total number of resources across all pages.
    """

    def __init__(
        self,
        first: 'PageLink',
        instances: List['Instance'],
        limit: int,
        total_count: int,
        *,
        next: Optional['PageLink'] = None,
    ) -> None:
        """
        Initialize a InstanceCollection object.

        :param PageLink first: A link to the first page of resources.
        :param List[Instance] instances: A page 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 PageLink 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 := _dict.get('first')) is not None:
            args['first'] = PageLink.from_dict(first)
        else:
            raise ValueError('Required property \'first\' not present in InstanceCollection JSON')
        if (instances := _dict.get('instances')) is not None:
            args['instances'] = [Instance.from_dict(v) for v in instances]
        else:
            raise ValueError('Required property \'instances\' not present in InstanceCollection JSON')
        if (limit := _dict.get('limit')) is not None:
            args['limit'] = limit
        else:
            raise ValueError('Required property \'limit\' not present in InstanceCollection JSON')
        if (next := _dict.get('next')) is not None:
            args['next'] = PageLink.from_dict(next)
        if (total_count := _dict.get('total_count')) is not None:
            args['total_count'] = 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 InstanceConsoleAccessToken:
    """
    The instance console access token information.

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

    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 := _dict.get('access_token')) is not None:
            args['access_token'] = access_token
        else:
            raise ValueError('Required property \'access_token\' not present in InstanceConsoleAccessToken JSON')
        if (console_type := _dict.get('console_type')) is not None:
            args['console_type'] = console_type
        else:
            raise ValueError('Required property \'console_type\' not present in InstanceConsoleAccessToken JSON')
        if (created_at := _dict.get('created_at')) is not None:
            args['created_at'] = string_to_datetime(created_at)
        else:
            raise ValueError('Required property \'created_at\' not present in InstanceConsoleAccessToken JSON')
        if (expires_at := _dict.get('expires_at')) is not None:
            args['expires_at'] = string_to_datetime(expires_at)
        else:
            raise ValueError('Required property \'expires_at\' not present in InstanceConsoleAccessToken JSON')
        if (force := _dict.get('force')) is not None:
            args['force'] = force
        else:
            raise ValueError('Required property \'force\' not present in InstanceConsoleAccessToken JSON')
        if (href := _dict.get('href')) is not None:
            args['href'] = 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.

    :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.
    :param TrustedProfileIdentity target: The default IAM trusted profile to use for
          this virtual server instance.
    """

    def __init__(
        self,
        target: 'TrustedProfileIdentity',
        *,
        auto_link: Optional[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 := _dict.get('auto_link')) is not None:
            args['auto_link'] = auto_link
        if (target := _dict.get('target')) is not None:
            args['target'] = 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.

    :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 may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :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).
    """

    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 may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :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 := _dict.get('created_at')) is not None:
            args['created_at'] = string_to_datetime(created_at)
        else:
            raise ValueError('Required property \'created_at\' not present in InstanceDisk JSON')
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in InstanceDisk JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in InstanceDisk JSON')
        if (interface_type := _dict.get('interface_type')) is not None:
            args['interface_type'] = interface_type
        else:
            raise ValueError('Required property \'interface_type\' not present in InstanceDisk JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in InstanceDisk JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = resource_type
        else:
            raise ValueError('Required property \'resource_type\' not present in InstanceDisk JSON')
        if (size := _dict.get('size')) is not None:
            args['size'] = 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 may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        NVME = 'nvme'
        VIRTIO_BLK = 'virtio_blk'


    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        INSTANCE_DISK = 'instance_disk'



class InstanceDiskCollection:
    """
    InstanceDiskCollection.

    :param List[InstanceDisk] disks: The disks for the instance.
    """

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

        :param List[InstanceDisk] disks: The disks for the instance.
        """
        self.disks = disks

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceDiskCollection':
        """Initialize a InstanceDiskCollection object from a json dictionary."""
        args = {}
        if (disks := _dict.get('disks')) is not None:
            args['disks'] = [InstanceDisk.from_dict(v) for v in 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.

    :param 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: Optional[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 := _dict.get('name')) is not None:
            args['name'] = 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.

    :param Deleted deleted: (optional) If present, this property indicates the
          referenced resource has been deleted, and provides
          some supplementary information.
    :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.
    """

    def __init__(
        self,
        href: str,
        id: str,
        name: str,
        resource_type: str,
        *,
        deleted: Optional['Deleted'] = 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 Deleted 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 := _dict.get('deleted')) is not None:
            args['deleted'] = Deleted.from_dict(deleted)
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in InstanceDiskReference JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in InstanceDiskReference JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in InstanceDiskReference JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = 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 InstanceGPU:
    """
    The virtual server instance GPU configuration.

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

    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 := _dict.get('count')) is not None:
            args['count'] = count
        else:
            raise ValueError('Required property \'count\' not present in InstanceGPU JSON')
        if (manufacturer := _dict.get('manufacturer')) is not None:
            args['manufacturer'] = manufacturer
        else:
            raise ValueError('Required property \'manufacturer\' not present in InstanceGPU JSON')
        if (memory := _dict.get('memory')) is not None:
            args['memory'] = memory
        else:
            raise ValueError('Required property \'memory\' not present in InstanceGPU JSON')
        if (model := _dict.get('model')) is not None:
            args['model'] = 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.

    :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 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[InstanceGroupLifecycleReason] lifecycle_reasons: The reasons for the
          current `lifecycle_state` (if any).
    :param str lifecycle_state: The lifecycle state of the instance group.
    :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.
    :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
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :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.
    """

    def __init__(
        self,
        created_at: datetime,
        crn: str,
        href: str,
        id: str,
        instance_template: 'InstanceTemplateReference',
        lifecycle_reasons: List['InstanceGroupLifecycleReason'],
        lifecycle_state: str,
        managers: List['InstanceGroupManagerReference'],
        membership_count: int,
        name: str,
        resource_group: 'ResourceGroupReference',
        status: str,
        subnets: List['SubnetReference'],
        updated_at: datetime,
        vpc: 'VPCReference',
        *,
        application_port: Optional[int] = None,
        load_balancer_pool: Optional['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[InstanceGroupLifecycleReason] lifecycle_reasons: The reasons
               for the current `lifecycle_state` (if any).
        :param str lifecycle_state: The lifecycle state of the instance 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
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :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.lifecycle_reasons = lifecycle_reasons
        self.lifecycle_state = lifecycle_state
        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 := _dict.get('application_port')) is not None:
            args['application_port'] = application_port
        if (created_at := _dict.get('created_at')) is not None:
            args['created_at'] = string_to_datetime(created_at)
        else:
            raise ValueError('Required property \'created_at\' not present in InstanceGroup JSON')
        if (crn := _dict.get('crn')) is not None:
            args['crn'] = crn
        else:
            raise ValueError('Required property \'crn\' not present in InstanceGroup JSON')
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in InstanceGroup JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in InstanceGroup JSON')
        if (instance_template := _dict.get('instance_template')) is not None:
            args['instance_template'] = InstanceTemplateReference.from_dict(instance_template)
        else:
            raise ValueError('Required property \'instance_template\' not present in InstanceGroup JSON')
        if (lifecycle_reasons := _dict.get('lifecycle_reasons')) is not None:
            args['lifecycle_reasons'] = [InstanceGroupLifecycleReason.from_dict(v) for v in lifecycle_reasons]
        else:
            raise ValueError('Required property \'lifecycle_reasons\' not present in InstanceGroup JSON')
        if (lifecycle_state := _dict.get('lifecycle_state')) is not None:
            args['lifecycle_state'] = lifecycle_state
        else:
            raise ValueError('Required property \'lifecycle_state\' not present in InstanceGroup JSON')
        if (load_balancer_pool := _dict.get('load_balancer_pool')) is not None:
            args['load_balancer_pool'] = LoadBalancerPoolReference.from_dict(load_balancer_pool)
        if (managers := _dict.get('managers')) is not None:
            args['managers'] = [InstanceGroupManagerReference.from_dict(v) for v in managers]
        else:
            raise ValueError('Required property \'managers\' not present in InstanceGroup JSON')
        if (membership_count := _dict.get('membership_count')) is not None:
            args['membership_count'] = membership_count
        else:
            raise ValueError('Required property \'membership_count\' not present in InstanceGroup JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in InstanceGroup JSON')
        if (resource_group := _dict.get('resource_group')) is not None:
            args['resource_group'] = ResourceGroupReference.from_dict(resource_group)
        else:
            raise ValueError('Required property \'resource_group\' not present in InstanceGroup JSON')
        if (status := _dict.get('status')) is not None:
            args['status'] = status
        else:
            raise ValueError('Required property \'status\' not present in InstanceGroup JSON')
        if (subnets := _dict.get('subnets')) is not None:
            args['subnets'] = [SubnetReference.from_dict(v) for v in subnets]
        else:
            raise ValueError('Required property \'subnets\' not present in InstanceGroup JSON')
        if (updated_at := _dict.get('updated_at')) is not None:
            args['updated_at'] = string_to_datetime(updated_at)
        else:
            raise ValueError('Required property \'updated_at\' not present in InstanceGroup JSON')
        if (vpc := _dict.get('vpc')) is not None:
            args['vpc'] = VPCReference.from_dict(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, '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, '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 LifecycleStateEnum(str, Enum):
        """
        The lifecycle state of the instance group.
        """

        DELETING = 'deleting'
        FAILED = 'failed'
        PENDING = 'pending'
        STABLE = 'stable'
        SUSPENDED = 'suspended'
        UPDATING = 'updating'
        WAITING = 'waiting'


    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
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        DELETING = 'deleting'
        HEALTHY = 'healthy'
        SCALING = 'scaling'
        UNHEALTHY = 'unhealthy'



class InstanceGroupCollection:
    """
    InstanceGroupCollection.

    :param PageLink first: A link to the first page of resources.
    :param List[InstanceGroup] instance_groups: A page of instance groups.
    :param int limit: The maximum number of resources that can be returned by the
          request.
    :param PageLink next: (optional) A link to the next page of resources. This
          property is present for all pages
          except the last page.
    :param int total_count: The total number of resources across all pages.
    """

    def __init__(
        self,
        first: 'PageLink',
        instance_groups: List['InstanceGroup'],
        limit: int,
        total_count: int,
        *,
        next: Optional['PageLink'] = None,
    ) -> None:
        """
        Initialize a InstanceGroupCollection object.

        :param PageLink first: A link to the first page of resources.
        :param List[InstanceGroup] instance_groups: A page 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 PageLink 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 := _dict.get('first')) is not None:
            args['first'] = PageLink.from_dict(first)
        else:
            raise ValueError('Required property \'first\' not present in InstanceGroupCollection JSON')
        if (instance_groups := _dict.get('instance_groups')) is not None:
            args['instance_groups'] = [InstanceGroup.from_dict(v) for v in instance_groups]
        else:
            raise ValueError('Required property \'instance_groups\' not present in InstanceGroupCollection JSON')
        if (limit := _dict.get('limit')) is not None:
            args['limit'] = limit
        else:
            raise ValueError('Required property \'limit\' not present in InstanceGroupCollection JSON')
        if (next := _dict.get('next')) is not None:
            args['next'] = PageLink.from_dict(next)
        if (total_count := _dict.get('total_count')) is not None:
            args['total_count'] = 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 InstanceGroupLifecycleReason:
    """
    InstanceGroupLifecycleReason.

    :param str code: A reason code for this lifecycle state:
          - `internal_error`: internal error (contact IBM support)
          - `resource_suspended_by_provider`: The resource has been suspended (contact IBM
            support)
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :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.
    """

    def __init__(
        self,
        code: str,
        message: str,
        *,
        more_info: Optional[str] = None,
    ) -> None:
        """
        Initialize a InstanceGroupLifecycleReason object.

        :param str code: A reason code for this lifecycle state:
               - `internal_error`: internal error (contact IBM support)
               - `resource_suspended_by_provider`: The resource has been suspended
               (contact IBM
                 support)
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :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) -> 'InstanceGroupLifecycleReason':
        """Initialize a InstanceGroupLifecycleReason object from a json dictionary."""
        args = {}
        if (code := _dict.get('code')) is not None:
            args['code'] = code
        else:
            raise ValueError('Required property \'code\' not present in InstanceGroupLifecycleReason JSON')
        if (message := _dict.get('message')) is not None:
            args['message'] = message
        else:
            raise ValueError('Required property \'message\' not present in InstanceGroupLifecycleReason JSON')
        if (more_info := _dict.get('more_info')) is not None:
            args['more_info'] = more_info
        return cls(**args)

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

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

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

    class CodeEnum(str, Enum):
        """
        A reason code for this lifecycle state:
        - `internal_error`: internal error (contact IBM support)
        - `resource_suspended_by_provider`: The resource has been suspended (contact IBM
          support)
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        INTERNAL_ERROR = 'internal_error'
        RESOURCE_SUSPENDED_BY_PROVIDER = 'resource_suspended_by_provider'



class InstanceGroupManager:
    """
    InstanceGroupManager.

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

    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.

    :param bool auto_delete: Indicates whether this scheduled action will be
          automatically deleted after it has completed and `auto_delete_timeout` hours
          have passed.
    :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.
    :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
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :param 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.
        :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.
        :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
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :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
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        ACTIVE = 'active'
        COMPLETED = 'completed'
        FAILED = 'failed'
        INCOMPATIBLE = 'incompatible'
        OMITTED = 'omitted'



class InstanceGroupManagerActionGroupPatch:
    """
    InstanceGroupManagerActionGroupPatch.

    :param int membership_count: (optional) The desired number of instance group
          members at the scheduled time.
    """

    def __init__(
        self,
        *,
        membership_count: Optional[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 := _dict.get('membership_count')) is not None:
            args['membership_count'] = 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.

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

    def __init__(
        self,
        *,
        max_membership_count: Optional[int] = None,
        min_membership_count: Optional[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 := _dict.get('max_membership_count')) is not None:
            args['max_membership_count'] = max_membership_count
        if (min_membership_count := _dict.get('min_membership_count')) is not None:
            args['min_membership_count'] = 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.

    :param bool auto_delete: (optional) Indicates whether this scheduled action will
          be automatically deleted after it has completed and `auto_delete_timeout` hours
          have passed.
    :param int auto_delete_timeout: (optional) 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.
    :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.
    """

    def __init__(
        self,
        *,
        auto_delete: Optional[bool] = None,
        auto_delete_timeout: Optional[int] = None,
        cron_spec: Optional[str] = None,
        group: Optional['InstanceGroupManagerActionGroupPatch'] = None,
        manager: Optional['InstanceGroupManagerActionManagerPatch'] = None,
        name: Optional[str] = None,
        run_at: Optional[datetime] = None,
    ) -> None:
        """
        Initialize a InstanceGroupManagerActionPatch object.

        :param bool auto_delete: (optional) Indicates whether this scheduled action
               will be automatically deleted after it has completed and
               `auto_delete_timeout` hours have passed.
        :param int auto_delete_timeout: (optional) 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.
        :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.auto_delete = auto_delete
        self.auto_delete_timeout = auto_delete_timeout
        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 (auto_delete := _dict.get('auto_delete')) is not None:
            args['auto_delete'] = auto_delete
        if (auto_delete_timeout := _dict.get('auto_delete_timeout')) is not None:
            args['auto_delete_timeout'] = auto_delete_timeout
        if (cron_spec := _dict.get('cron_spec')) is not None:
            args['cron_spec'] = cron_spec
        if (group := _dict.get('group')) is not None:
            args['group'] = InstanceGroupManagerActionGroupPatch.from_dict(group)
        if (manager := _dict.get('manager')) is not None:
            args['manager'] = InstanceGroupManagerActionManagerPatch.from_dict(manager)
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        if (run_at := _dict.get('run_at')) is not None:
            args['run_at'] = string_to_datetime(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, '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, '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.

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

    def __init__(
        self,
        *,
        name: Optional[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.

    :param Deleted deleted: (optional) If present, this property indicates the
          referenced resource has been deleted, and provides
          some supplementary information.
    :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.
    """

    def __init__(
        self,
        href: str,
        id: str,
        name: str,
        resource_type: str,
        *,
        deleted: Optional['Deleted'] = 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 Deleted 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 := _dict.get('deleted')) is not None:
            args['deleted'] = Deleted.from_dict(deleted)
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in InstanceGroupManagerActionReference JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in InstanceGroupManagerActionReference JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in InstanceGroupManagerActionReference JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = 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 InstanceGroupManagerActionsCollection:
    """
    InstanceGroupManagerActionsCollection.

    :param List[InstanceGroupManagerAction] actions: A page of actions for the
          instance group manager.
    :param PageLink 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 PageLink next: (optional) A link to the next page of resources. This
          property is present for all pages
          except the last page.
    :param int total_count: The total number of resources across all pages.
    """

    def __init__(
        self,
        actions: List['InstanceGroupManagerAction'],
        first: 'PageLink',
        limit: int,
        total_count: int,
        *,
        next: Optional['PageLink'] = None,
    ) -> None:
        """
        Initialize a InstanceGroupManagerActionsCollection object.

        :param List[InstanceGroupManagerAction] actions: A page of actions for the
               instance group manager.
        :param PageLink 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 PageLink 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 := _dict.get('actions')) is not None:
            args['actions'] = actions
        else:
            raise ValueError('Required property \'actions\' not present in InstanceGroupManagerActionsCollection JSON')
        if (first := _dict.get('first')) is not None:
            args['first'] = PageLink.from_dict(first)
        else:
            raise ValueError('Required property \'first\' not present in InstanceGroupManagerActionsCollection JSON')
        if (limit := _dict.get('limit')) is not None:
            args['limit'] = limit
        else:
            raise ValueError('Required property \'limit\' not present in InstanceGroupManagerActionsCollection JSON')
        if (next := _dict.get('next')) is not None:
            args['next'] = PageLink.from_dict(next)
        if (total_count := _dict.get('total_count')) is not None:
            args['total_count'] = 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 InstanceGroupManagerCollection:
    """
    InstanceGroupManagerCollection.

    :param PageLink 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: A page of managers for the instance
          group.
    :param PageLink next: (optional) A link to the next page of resources. This
          property is present for all pages
          except the last page.
    :param int total_count: The total number of resources across all pages.
    """

    def __init__(
        self,
        first: 'PageLink',
        limit: int,
        managers: List['InstanceGroupManager'],
        total_count: int,
        *,
        next: Optional['PageLink'] = None,
    ) -> None:
        """
        Initialize a InstanceGroupManagerCollection object.

        :param PageLink 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: A page of managers for the
               instance group.
        :param int total_count: The total number of resources across all pages.
        :param PageLink 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 := _dict.get('first')) is not None:
            args['first'] = PageLink.from_dict(first)
        else:
            raise ValueError('Required property \'first\' not present in InstanceGroupManagerCollection JSON')
        if (limit := _dict.get('limit')) is not None:
            args['limit'] = limit
        else:
            raise ValueError('Required property \'limit\' not present in InstanceGroupManagerCollection JSON')
        if (managers := _dict.get('managers')) is not None:
            args['managers'] = managers
        else:
            raise ValueError('Required property \'managers\' not present in InstanceGroupManagerCollection JSON')
        if (next := _dict.get('next')) is not None:
            args['next'] = PageLink.from_dict(next)
        if (total_count := _dict.get('total_count')) is not None:
            args['total_count'] = 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 InstanceGroupManagerPatch:
    """
    InstanceGroupManagerPatch.

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

    def __init__(
        self,
        *,
        aggregation_window: Optional[int] = None,
        cooldown: Optional[int] = None,
        management_enabled: Optional[bool] = None,
        max_membership_count: Optional[int] = None,
        min_membership_count: Optional[int] = None,
        name: Optional[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 := _dict.get('aggregation_window')) is not None:
            args['aggregation_window'] = aggregation_window
        if (cooldown := _dict.get('cooldown')) is not None:
            args['cooldown'] = cooldown
        if (management_enabled := _dict.get('management_enabled')) is not None:
            args['management_enabled'] = management_enabled
        if (max_membership_count := _dict.get('max_membership_count')) is not None:
            args['max_membership_count'] = max_membership_count
        if (min_membership_count := _dict.get('min_membership_count')) is not None:
            args['min_membership_count'] = min_membership_count
        if (name := _dict.get('name')) is not None:
            args['name'] = 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.

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

    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.

    :param PageLink 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 PageLink next: (optional) A link to the next page of resources. This
          property is present for all pages
          except the last page.
    :param List[InstanceGroupManagerPolicy] policies: A page of policies for the
          instance group manager.
    :param int total_count: The total number of resources across all pages.
    """

    def __init__(
        self,
        first: 'PageLink',
        limit: int,
        policies: List['InstanceGroupManagerPolicy'],
        total_count: int,
        *,
        next: Optional['PageLink'] = None,
    ) -> None:
        """
        Initialize a InstanceGroupManagerPolicyCollection object.

        :param PageLink 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: A page of policies for
               the instance group manager.
        :param int total_count: The total number of resources across all pages.
        :param PageLink 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 := _dict.get('first')) is not None:
            args['first'] = PageLink.from_dict(first)
        else:
            raise ValueError('Required property \'first\' not present in InstanceGroupManagerPolicyCollection JSON')
        if (limit := _dict.get('limit')) is not None:
            args['limit'] = limit
        else:
            raise ValueError('Required property \'limit\' not present in InstanceGroupManagerPolicyCollection JSON')
        if (next := _dict.get('next')) is not None:
            args['next'] = PageLink.from_dict(next)
        if (policies := _dict.get('policies')) is not None:
            args['policies'] = policies
        else:
            raise ValueError('Required property \'policies\' not present in InstanceGroupManagerPolicyCollection JSON')
        if (total_count := _dict.get('total_count')) is not None:
            args['total_count'] = 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 InstanceGroupManagerPolicyPatch:
    """
    InstanceGroupManagerPolicyPatch.

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

    def __init__(
        self,
        *,
        metric_type: Optional[str] = None,
        metric_value: Optional[int] = None,
        name: Optional[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 := _dict.get('metric_type')) is not None:
            args['metric_type'] = metric_type
        if (metric_value := _dict.get('metric_value')) is not None:
            args['metric_value'] = metric_value
        if (name := _dict.get('name')) is not None:
            args['name'] = 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.

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

    def __init__(
        self,
        *,
        name: Optional[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.

    :param Deleted deleted: (optional) If present, this property indicates the
          referenced resource has been deleted, and provides
          some supplementary information.
    :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.
    """

    def __init__(
        self,
        href: str,
        id: str,
        name: str,
        *,
        deleted: Optional['Deleted'] = 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 Deleted 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 := _dict.get('deleted')) is not None:
            args['deleted'] = Deleted.from_dict(deleted)
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in InstanceGroupManagerPolicyReference JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in InstanceGroupManagerPolicyReference JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = 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 InstanceGroupManagerPrototype:
    """
    InstanceGroupManagerPrototype.

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

    def __init__(
        self,
        *,
        management_enabled: Optional[bool] = None,
        name: Optional[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.

    :param Deleted deleted: (optional) If present, this property indicates the
          referenced resource has been deleted, and provides
          some supplementary information.
    :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.
    """

    def __init__(
        self,
        href: str,
        id: str,
        name: str,
        *,
        deleted: Optional['Deleted'] = 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 Deleted 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 := _dict.get('deleted')) is not None:
            args['deleted'] = Deleted.from_dict(deleted)
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in InstanceGroupManagerReference JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in InstanceGroupManagerReference JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = 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 InstanceGroupManagerScheduledActionGroup:
    """
    InstanceGroupManagerScheduledActionGroup.

    :param 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 := _dict.get('membership_count')) is not None:
            args['membership_count'] = 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.

    :param 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 := _dict.get('membership_count')) is not None:
            args['membership_count'] = 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.

    :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 LoadBalancerPoolMemberReference pool_member: (optional)
    :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
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :param 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: Optional['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
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :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 := _dict.get('created_at')) is not None:
            args['created_at'] = string_to_datetime(created_at)
        else:
            raise ValueError('Required property \'created_at\' not present in InstanceGroupMembership JSON')
        if (delete_instance_on_membership_delete := _dict.get('delete_instance_on_membership_delete')) is not None:
            args['delete_instance_on_membership_delete'] = delete_instance_on_membership_delete
        else:
            raise ValueError('Required property \'delete_instance_on_membership_delete\' not present in InstanceGroupMembership JSON')
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in InstanceGroupMembership JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in InstanceGroupMembership JSON')
        if (instance := _dict.get('instance')) is not None:
            args['instance'] = InstanceReference.from_dict(instance)
        else:
            raise ValueError('Required property \'instance\' not present in InstanceGroupMembership JSON')
        if (instance_template := _dict.get('instance_template')) is not None:
            args['instance_template'] = InstanceTemplateReference.from_dict(instance_template)
        else:
            raise ValueError('Required property \'instance_template\' not present in InstanceGroupMembership JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in InstanceGroupMembership JSON')
        if (pool_member := _dict.get('pool_member')) is not None:
            args['pool_member'] = LoadBalancerPoolMemberReference.from_dict(pool_member)
        if (status := _dict.get('status')) is not None:
            args['status'] = status
        else:
            raise ValueError('Required property \'status\' not present in InstanceGroupMembership JSON')
        if (updated_at := _dict.get('updated_at')) is not None:
            args['updated_at'] = string_to_datetime(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
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        DELETING = 'deleting'
        FAILED = 'failed'
        HEALTHY = 'healthy'
        PENDING = 'pending'
        UNHEALTHY = 'unhealthy'



class InstanceGroupMembershipCollection:
    """
    InstanceGroupMembershipCollection.

    :param PageLink 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: A page of memberships for the
          instance group.
    :param PageLink next: (optional) A link to the next page of resources. This
          property is present for all pages
          except the last page.
    :param int total_count: The total number of resources across all pages.
    """

    def __init__(
        self,
        first: 'PageLink',
        limit: int,
        memberships: List['InstanceGroupMembership'],
        total_count: int,
        *,
        next: Optional['PageLink'] = None,
    ) -> None:
        """
        Initialize a InstanceGroupMembershipCollection object.

        :param PageLink 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: A page of memberships for
               the instance group.
        :param int total_count: The total number of resources across all pages.
        :param PageLink 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 := _dict.get('first')) is not None:
            args['first'] = PageLink.from_dict(first)
        else:
            raise ValueError('Required property \'first\' not present in InstanceGroupMembershipCollection JSON')
        if (limit := _dict.get('limit')) is not None:
            args['limit'] = limit
        else:
            raise ValueError('Required property \'limit\' not present in InstanceGroupMembershipCollection JSON')
        if (memberships := _dict.get('memberships')) is not None:
            args['memberships'] = [InstanceGroupMembership.from_dict(v) for v in memberships]
        else:
            raise ValueError('Required property \'memberships\' not present in InstanceGroupMembershipCollection JSON')
        if (next := _dict.get('next')) is not None:
            args['next'] = PageLink.from_dict(next)
        if (total_count := _dict.get('total_count')) is not None:
            args['total_count'] = 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 InstanceGroupMembershipPatch:
    """
    InstanceGroupMembershipPatch.

    :param bool delete_instance_on_membership_delete: (optional) If set to true,
          when deleting the membership the instance will also be deleted.
    :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.
    """

    def __init__(
        self,
        *,
        delete_instance_on_membership_delete: Optional[bool] = None,
        name: Optional[str] = None,
    ) -> None:
        """
        Initialize a InstanceGroupMembershipPatch object.

        :param bool delete_instance_on_membership_delete: (optional) If set to
               true, when deleting the membership the instance will also be deleted.
        :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.delete_instance_on_membership_delete = delete_instance_on_membership_delete
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceGroupMembershipPatch':
        """Initialize a InstanceGroupMembershipPatch object from a json dictionary."""
        args = {}
        if (delete_instance_on_membership_delete := _dict.get('delete_instance_on_membership_delete')) is not None:
            args['delete_instance_on_membership_delete'] = delete_instance_on_membership_delete
        if (name := _dict.get('name')) is not None:
            args['name'] = 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, '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, '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.

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

    def __init__(
        self,
        *,
        application_port: Optional[int] = None,
        instance_template: Optional['InstanceTemplateIdentity'] = None,
        load_balancer: Optional['LoadBalancerIdentity'] = None,
        load_balancer_pool: Optional['LoadBalancerPoolIdentity'] = None,
        membership_count: Optional[int] = None,
        name: Optional[str] = None,
        subnets: Optional[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 := _dict.get('application_port')) is not None:
            args['application_port'] = application_port
        if (instance_template := _dict.get('instance_template')) is not None:
            args['instance_template'] = instance_template
        if (load_balancer := _dict.get('load_balancer')) is not None:
            args['load_balancer'] = load_balancer
        if (load_balancer_pool := _dict.get('load_balancer_pool')) is not None:
            args['load_balancer_pool'] = load_balancer_pool
        if (membership_count := _dict.get('membership_count')) is not None:
            args['membership_count'] = membership_count
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        if (subnets := _dict.get('subnets')) is not None:
            args['subnets'] = 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.

    :param str crn: The CRN for this instance group.
    :param Deleted deleted: (optional) If present, this property indicates the
          referenced resource has been deleted, and provides
          some supplementary information.
    :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.
    """

    def __init__(
        self,
        crn: str,
        href: str,
        id: str,
        name: str,
        *,
        deleted: Optional['Deleted'] = 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 Deleted 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 := _dict.get('crn')) is not None:
            args['crn'] = crn
        else:
            raise ValueError('Required property \'crn\' not present in InstanceGroupReference JSON')
        if (deleted := _dict.get('deleted')) is not None:
            args['deleted'] = Deleted.from_dict(deleted)
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in InstanceGroupReference JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in InstanceGroupReference JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = 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 InstanceHealthReason:
    """
    InstanceHealthReason.

    :param str code: A reason code for this health state:
          - `reservation_capacity_unavailable`: The reservation affinity pool has no
            available capacity.
          - `reservation_deleted`: The reservation affinity pool has a deleted
          reservation.
          - `reservation_expired`: The reservation affinity pool has an expired
          reservation.
          - `reservation_failed`: The reservation affinity pool has a failed reservation.
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :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.
    """

    def __init__(
        self,
        code: str,
        message: str,
        *,
        more_info: Optional[str] = None,
    ) -> None:
        """
        Initialize a InstanceHealthReason object.

        :param str code: A reason code for this health state:
               - `reservation_capacity_unavailable`: The reservation affinity pool has no
                 available capacity.
               - `reservation_deleted`: The reservation affinity pool has a deleted
               reservation.
               - `reservation_expired`: The reservation affinity pool has an expired
               reservation.
               - `reservation_failed`: The reservation affinity pool has a failed
               reservation.
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :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) -> 'InstanceHealthReason':
        """Initialize a InstanceHealthReason object from a json dictionary."""
        args = {}
        if (code := _dict.get('code')) is not None:
            args['code'] = code
        else:
            raise ValueError('Required property \'code\' not present in InstanceHealthReason JSON')
        if (message := _dict.get('message')) is not None:
            args['message'] = message
        else:
            raise ValueError('Required property \'message\' not present in InstanceHealthReason JSON')
        if (more_info := _dict.get('more_info')) is not None:
            args['more_info'] = more_info
        return cls(**args)

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

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

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

    class CodeEnum(str, Enum):
        """
        A reason code for this health state:
        - `reservation_capacity_unavailable`: The reservation affinity pool has no
          available capacity.
        - `reservation_deleted`: The reservation affinity pool has a deleted reservation.
        - `reservation_expired`: The reservation affinity pool has an expired reservation.
        - `reservation_failed`: The reservation affinity pool has a failed reservation.
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        RESERVATION_CAPACITY_UNAVAILABLE = 'reservation_capacity_unavailable'
        RESERVATION_DELETED = 'reservation_deleted'
        RESERVATION_EXPIRED = 'reservation_expired'
        RESERVATION_FAILED = 'reservation_failed'



class InstanceInitialization:
    """
    InstanceInitialization.

    :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 List[KeyReference] keys: The public SSH keys used at instance
          initialization.
    :param InstanceInitializationPassword password: (optional)
    """

    def __init__(
        self,
        keys: List['KeyReference'],
        *,
        default_trusted_profile: Optional['InstanceInitializationDefaultTrustedProfile'] = None,
        password: Optional['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 := _dict.get('default_trusted_profile')) is not None:
            args['default_trusted_profile'] = InstanceInitializationDefaultTrustedProfile.from_dict(default_trusted_profile)
        if (keys := _dict.get('keys')) is not None:
            args['keys'] = [KeyReference.from_dict(v) for v in keys]
        else:
            raise ValueError('Required property \'keys\' not present in InstanceInitialization JSON')
        if (password := _dict.get('password')) is not None:
            args['password'] = InstanceInitializationPassword.from_dict(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.

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

    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 := _dict.get('auto_link')) is not None:
            args['auto_link'] = auto_link
        else:
            raise ValueError('Required property \'auto_link\' not present in InstanceInitializationDefaultTrustedProfile JSON')
        if (target := _dict.get('target')) is not None:
            args['target'] = TrustedProfileReference.from_dict(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.

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

    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 := _dict.get('encrypted_password')) is not None:
            args['encrypted_password'] = base64.b64decode(encrypted_password)
        else:
            raise ValueError('Required property \'encrypted_password\' not present in InstanceInitializationPassword JSON')
        if (encryption_key := _dict.get('encryption_key')) is not None:
            args['encryption_key'] = KeyIdentityByFingerprint.from_dict(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.

    :param str code: A reason code for this lifecycle state:
          - `failed_registration`: the instance's registration to Resource Controller has
            failed. Delete the instance and provision it again. If the problem persists,
            contact IBM Support.
          - `internal_error`: internal error (contact IBM support)
          - `pending_registration`: the instance's registration to Resource Controller is
            being processed.
          - `resource_suspended_by_provider`: The resource has been suspended (contact IBM
            support)
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :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.
    """

    def __init__(
        self,
        code: str,
        message: str,
        *,
        more_info: Optional[str] = None,
    ) -> None:
        """
        Initialize a InstanceLifecycleReason object.

        :param str code: A reason code for this lifecycle state:
               - `failed_registration`: the instance's registration to Resource Controller
               has
                 failed. Delete the instance and provision it again. If the problem
               persists,
                 contact IBM Support.
               - `internal_error`: internal error (contact IBM support)
               - `pending_registration`: the instance's registration to Resource
               Controller is
                 being processed.
               - `resource_suspended_by_provider`: The resource has been suspended
               (contact IBM
                 support)
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :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 := _dict.get('code')) is not None:
            args['code'] = code
        else:
            raise ValueError('Required property \'code\' not present in InstanceLifecycleReason JSON')
        if (message := _dict.get('message')) is not None:
            args['message'] = message
        else:
            raise ValueError('Required property \'message\' not present in InstanceLifecycleReason JSON')
        if (more_info := _dict.get('more_info')) is not None:
            args['more_info'] = 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 reason code for this lifecycle state:
        - `failed_registration`: the instance's registration to Resource Controller has
          failed. Delete the instance and provision it again. If the problem persists,
          contact IBM Support.
        - `internal_error`: internal error (contact IBM support)
        - `pending_registration`: the instance's registration to Resource Controller is
          being processed.
        - `resource_suspended_by_provider`: The resource has been suspended (contact IBM
          support)
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        FAILED_REGISTRATION = 'failed_registration'
        INTERNAL_ERROR = 'internal_error'
        PENDING_REGISTRATION = 'pending_registration'
        RESOURCE_SUSPENDED_BY_PROVIDER = 'resource_suspended_by_provider'



class InstanceMetadataService:
    """
    The metadata service configuration.

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

    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 := _dict.get('enabled')) is not None:
            args['enabled'] = enabled
        else:
            raise ValueError('Required property \'enabled\' not present in InstanceMetadataService JSON')
        if (protocol := _dict.get('protocol')) is not None:
            args['protocol'] = protocol
        else:
            raise ValueError('Required property \'protocol\' not present in InstanceMetadataService JSON')
        if (response_hop_limit := _dict.get('response_hop_limit')) is not None:
            args['response_hop_limit'] = 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.

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

    def __init__(
        self,
        *,
        enabled: Optional[bool] = None,
        protocol: Optional[str] = None,
        response_hop_limit: Optional[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 := _dict.get('enabled')) is not None:
            args['enabled'] = enabled
        if (protocol := _dict.get('protocol')) is not None:
            args['protocol'] = protocol
        if (response_hop_limit := _dict.get('response_hop_limit')) is not None:
            args['response_hop_limit'] = 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.

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

    def __init__(
        self,
        *,
        enabled: Optional[bool] = None,
        protocol: Optional[str] = None,
        response_hop_limit: Optional[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 := _dict.get('enabled')) is not None:
            args['enabled'] = enabled
        if (protocol := _dict.get('protocol')) is not None:
            args['protocol'] = protocol
        if (response_hop_limit := _dict.get('response_hop_limit')) is not None:
            args['response_hop_limit'] = 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 InstanceNetworkAttachment:
    """
    InstanceNetworkAttachment.

    :param datetime created_at: The date and time that the instance network
          attachment was created.
    :param str href: The URL for this instance network attachment.
    :param str id: The unique identifier for this instance network attachment.
    :param str lifecycle_state: The lifecycle state of the instance network
          attachment.
    :param str name: The name for this instance network attachment. The name is
          unique across all network attachments for the instance.
    :param int port_speed: The port speed for this instance network attachment in
          Mbps.
    :param ReservedIPReference primary_ip: The primary IP address of the virtual
          network interface for the instance network
          attachment.
    :param str resource_type: The resource type.
    :param SubnetReference subnet: The subnet of the virtual network interface for
          the instance network attachment.
    :param str type: The instance network attachment type.
    :param VirtualNetworkInterfaceReferenceAttachmentContext
          virtual_network_interface: The virtual network interface for this instance
          network attachment.
    """

    def __init__(
        self,
        created_at: datetime,
        href: str,
        id: str,
        lifecycle_state: str,
        name: str,
        port_speed: int,
        primary_ip: 'ReservedIPReference',
        resource_type: str,
        subnet: 'SubnetReference',
        type: str,
        virtual_network_interface: 'VirtualNetworkInterfaceReferenceAttachmentContext',
    ) -> None:
        """
        Initialize a InstanceNetworkAttachment object.

        :param datetime created_at: The date and time that the instance network
               attachment was created.
        :param str href: The URL for this instance network attachment.
        :param str id: The unique identifier for this instance network attachment.
        :param str lifecycle_state: The lifecycle state of the instance network
               attachment.
        :param str name: The name for this instance network attachment. The name is
               unique across all network attachments for the instance.
        :param int port_speed: The port speed for this instance network attachment
               in Mbps.
        :param ReservedIPReference primary_ip: The primary IP address of the
               virtual network interface for the instance network
               attachment.
        :param str resource_type: The resource type.
        :param SubnetReference subnet: The subnet of the virtual network interface
               for the instance network attachment.
        :param str type: The instance network attachment type.
        :param VirtualNetworkInterfaceReferenceAttachmentContext
               virtual_network_interface: The virtual network interface for this instance
               network attachment.
        """
        self.created_at = created_at
        self.href = href
        self.id = id
        self.lifecycle_state = lifecycle_state
        self.name = name
        self.port_speed = port_speed
        self.primary_ip = primary_ip
        self.resource_type = resource_type
        self.subnet = subnet
        self.type = type
        self.virtual_network_interface = virtual_network_interface

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceNetworkAttachment':
        """Initialize a InstanceNetworkAttachment object from a json dictionary."""
        args = {}
        if (created_at := _dict.get('created_at')) is not None:
            args['created_at'] = string_to_datetime(created_at)
        else:
            raise ValueError('Required property \'created_at\' not present in InstanceNetworkAttachment JSON')
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in InstanceNetworkAttachment JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in InstanceNetworkAttachment JSON')
        if (lifecycle_state := _dict.get('lifecycle_state')) is not None:
            args['lifecycle_state'] = lifecycle_state
        else:
            raise ValueError('Required property \'lifecycle_state\' not present in InstanceNetworkAttachment JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in InstanceNetworkAttachment JSON')
        if (port_speed := _dict.get('port_speed')) is not None:
            args['port_speed'] = port_speed
        else:
            raise ValueError('Required property \'port_speed\' not present in InstanceNetworkAttachment JSON')
        if (primary_ip := _dict.get('primary_ip')) is not None:
            args['primary_ip'] = ReservedIPReference.from_dict(primary_ip)
        else:
            raise ValueError('Required property \'primary_ip\' not present in InstanceNetworkAttachment JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = resource_type
        else:
            raise ValueError('Required property \'resource_type\' not present in InstanceNetworkAttachment JSON')
        if (subnet := _dict.get('subnet')) is not None:
            args['subnet'] = SubnetReference.from_dict(subnet)
        else:
            raise ValueError('Required property \'subnet\' not present in InstanceNetworkAttachment JSON')
        if (type := _dict.get('type')) is not None:
            args['type'] = type
        else:
            raise ValueError('Required property \'type\' not present in InstanceNetworkAttachment JSON')
        if (virtual_network_interface := _dict.get('virtual_network_interface')) is not None:
            args['virtual_network_interface'] = VirtualNetworkInterfaceReferenceAttachmentContext.from_dict(virtual_network_interface)
        else:
            raise ValueError('Required property \'virtual_network_interface\' not present in InstanceNetworkAttachment JSON')
        return cls(**args)

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

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

    def __ne__(self, other: 'InstanceNetworkAttachment') -> 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 instance network attachment.
        """

        DELETING = 'deleting'
        FAILED = 'failed'
        PENDING = 'pending'
        STABLE = 'stable'
        SUSPENDED = 'suspended'
        UPDATING = 'updating'
        WAITING = 'waiting'


    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        INSTANCE_NETWORK_ATTACHMENT = 'instance_network_attachment'


    class TypeEnum(str, Enum):
        """
        The instance network attachment type.
        """

        PRIMARY = 'primary'
        SECONDARY = 'secondary'



class InstanceNetworkAttachmentCollection:
    """
    InstanceNetworkAttachmentCollection.

    :param List[InstanceNetworkAttachment] network_attachments: The network
          attachments for the instance.
    """

    def __init__(
        self,
        network_attachments: List['InstanceNetworkAttachment'],
    ) -> None:
        """
        Initialize a InstanceNetworkAttachmentCollection object.

        :param List[InstanceNetworkAttachment] network_attachments: The network
               attachments for the instance.
        """
        self.network_attachments = network_attachments

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

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceNetworkAttachmentCollection object from 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_attachments') and self.network_attachments is not None:
            network_attachments_list = []
            for v in self.network_attachments:
                if isinstance(v, dict):
                    network_attachments_list.append(v)
                else:
                    network_attachments_list.append(v.to_dict())
            _dict['network_attachments'] = network_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 InstanceNetworkAttachmentCollection object."""
        return json.dumps(self.to_dict(), indent=2)

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

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


class InstanceNetworkAttachmentPatch:
    """
    InstanceNetworkAttachmentPatch.

    :param str name: (optional) The name for this network attachment. The name must
          not be used by another network attachment for the instance.
    """

    def __init__(
        self,
        *,
        name: Optional[str] = None,
    ) -> None:
        """
        Initialize a InstanceNetworkAttachmentPatch object.

        :param str name: (optional) The name for this network attachment. The name
               must not be used by another network attachment for the instance.
        """
        self.name = name

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

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

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

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


class InstanceNetworkAttachmentPrototype:
    """
    InstanceNetworkAttachmentPrototype.

    :param str name: (optional) The name for this network attachment. Names must be
          unique within the instance the network attachment resides in. If unspecified,
          the name will be a hyphenated list of randomly-selected words.
    :param InstanceNetworkAttachmentPrototypeVirtualNetworkInterface
          virtual_network_interface: A virtual network interface for the instance network
          attachment. This can be specified
          using an existing virtual network interface, or a prototype object for a new
          virtual
          network interface.
          If an existing virtual network interface is specified,
          `enable_infrastructure_nat` must be
          `true`.
    """

    def __init__(
        self,
        virtual_network_interface: 'InstanceNetworkAttachmentPrototypeVirtualNetworkInterface',
        *,
        name: Optional[str] = None,
    ) -> None:
        """
        Initialize a InstanceNetworkAttachmentPrototype object.

        :param InstanceNetworkAttachmentPrototypeVirtualNetworkInterface
               virtual_network_interface: A virtual network interface for the instance
               network attachment. This can be specified
               using an existing virtual network interface, or a prototype object for a
               new virtual
               network interface.
               If an existing virtual network interface is specified,
               `enable_infrastructure_nat` must be
               `true`.
        :param str name: (optional) The name for this network attachment. Names
               must be unique within the instance the network attachment resides in. If
               unspecified, the name will be a hyphenated list of randomly-selected words.
        """
        self.name = name
        self.virtual_network_interface = virtual_network_interface

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

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

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

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


class InstanceNetworkAttachmentPrototypeVirtualNetworkInterface:
    """
    A virtual network interface for the instance network attachment. This can be specified
    using an existing virtual network interface, or a prototype object for a new virtual
    network interface.
    If an existing virtual network interface is specified, `enable_infrastructure_nat`
    must be
    `true`.

    """

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

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


class InstanceNetworkAttachmentReference:
    """
    InstanceNetworkAttachmentReference.

    :param Deleted deleted: (optional) If present, this property indicates the
          referenced resource has been deleted, and provides
          some supplementary information.
    :param str href: The URL for this instance network attachment.
    :param str id: The unique identifier for this instance network attachment.
    :param str name: The name for this instance network attachment. The name is
          unique across all network attachments for the instance.
    :param ReservedIPReference primary_ip: The primary IP address of the virtual
          network interface for the instance network
          attachment.
    :param str resource_type: The resource type.
    :param SubnetReference subnet: The subnet of the virtual network interface for
          the instance network attachment.
    :param VirtualNetworkInterfaceReferenceAttachmentContext
          virtual_network_interface: The virtual network interface for this instance
          network attachment.
    """

    def __init__(
        self,
        href: str,
        id: str,
        name: str,
        primary_ip: 'ReservedIPReference',
        resource_type: str,
        subnet: 'SubnetReference',
        virtual_network_interface: 'VirtualNetworkInterfaceReferenceAttachmentContext',
        *,
        deleted: Optional['Deleted'] = None,
    ) -> None:
        """
        Initialize a InstanceNetworkAttachmentReference object.

        :param str href: The URL for this instance network attachment.
        :param str id: The unique identifier for this instance network attachment.
        :param str name: The name for this instance network attachment. The name is
               unique across all network attachments for the instance.
        :param ReservedIPReference primary_ip: The primary IP address of the
               virtual network interface for the instance network
               attachment.
        :param str resource_type: The resource type.
        :param SubnetReference subnet: The subnet of the virtual network interface
               for the instance network attachment.
        :param VirtualNetworkInterfaceReferenceAttachmentContext
               virtual_network_interface: The virtual network interface for this instance
               network attachment.
        :param Deleted 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
        self.virtual_network_interface = virtual_network_interface

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceNetworkAttachmentReference':
        """Initialize a InstanceNetworkAttachmentReference object from a json dictionary."""
        args = {}
        if (deleted := _dict.get('deleted')) is not None:
            args['deleted'] = Deleted.from_dict(deleted)
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in InstanceNetworkAttachmentReference JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in InstanceNetworkAttachmentReference JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in InstanceNetworkAttachmentReference JSON')
        if (primary_ip := _dict.get('primary_ip')) is not None:
            args['primary_ip'] = ReservedIPReference.from_dict(primary_ip)
        else:
            raise ValueError('Required property \'primary_ip\' not present in InstanceNetworkAttachmentReference JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = resource_type
        else:
            raise ValueError('Required property \'resource_type\' not present in InstanceNetworkAttachmentReference JSON')
        if (subnet := _dict.get('subnet')) is not None:
            args['subnet'] = SubnetReference.from_dict(subnet)
        else:
            raise ValueError('Required property \'subnet\' not present in InstanceNetworkAttachmentReference JSON')
        if (virtual_network_interface := _dict.get('virtual_network_interface')) is not None:
            args['virtual_network_interface'] = VirtualNetworkInterfaceReferenceAttachmentContext.from_dict(virtual_network_interface)
        else:
            raise ValueError('Required property \'virtual_network_interface\' not present in InstanceNetworkAttachmentReference JSON')
        return cls(**args)

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

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

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

    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        INSTANCE_NETWORK_ATTACHMENT = 'instance_network_attachment'



class InstancePatch:
    """
    InstancePatch.

    :param InstanceAvailabilityPolicyPatch availability_policy: (optional) The
          availability policy for this virtual server instance.
    :param str confidential_compute_mode: (optional) The confidential compute mode
          to use for this virtual server instance.
          For this property to be changed, the virtual server instance `status` must be
          `stopping` or `stopped`.
    :param bool enable_secure_boot: (optional) Indicates whether secure boot is
          enabled for this virtual server instance.
          For this property to be changed, the virtual server instance `status` must be
          `stopping` or `stopped`.
    :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`.
          If set, `reservation_affinity.policy` must be `disabled`.
    :param InstancePatchProfile profile: (optional) The profile to use for this
          virtual server instance. Any disks associated with the
          current profile will be deleted, and any disks associated with the requested
          profile
          will be created.
          For the profile to be changed, the instance `status` must be `stopping` or
          `stopped`.
          In addition, the requested profile must:
          - 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 attachments or network interfaces the instance
            currently has.
    :param InstanceReservationAffinityPatch reservation_affinity: (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`.
    """

    def __init__(
        self,
        *,
        availability_policy: Optional['InstanceAvailabilityPolicyPatch'] = None,
        confidential_compute_mode: Optional[str] = None,
        enable_secure_boot: Optional[bool] = None,
        metadata_service: Optional['InstanceMetadataServicePatch'] = None,
        name: Optional[str] = None,
        placement_target: Optional['InstancePlacementTargetPatch'] = None,
        profile: Optional['InstancePatchProfile'] = None,
        reservation_affinity: Optional['InstanceReservationAffinityPatch'] = None,
        total_volume_bandwidth: Optional[int] = None,
    ) -> None:
        """
        Initialize a InstancePatch object.

        :param InstanceAvailabilityPolicyPatch availability_policy: (optional) The
               availability policy for this virtual server instance.
        :param str confidential_compute_mode: (optional) The confidential compute
               mode to use for this virtual server instance.
               For this property to be changed, the virtual server instance `status` must
               be
               `stopping` or `stopped`.
        :param bool enable_secure_boot: (optional) Indicates whether secure boot is
               enabled for this virtual server instance.
               For this property to be changed, the virtual server instance `status` must
               be
               `stopping` or `stopped`.
        :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`.
               If set, `reservation_affinity.policy` must be `disabled`.
        :param InstancePatchProfile profile: (optional) The profile to use for this
               virtual server instance. Any disks associated with the
               current profile will be deleted, and any disks associated with the
               requested profile
               will be created.
               For the profile to be changed, the instance `status` must be `stopping` or
               `stopped`.
               In addition, the requested profile must:
               - 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 attachments or network interfaces the
               instance
                 currently has.
        :param InstanceReservationAffinityPatch reservation_affinity: (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`.
        """
        self.availability_policy = availability_policy
        self.confidential_compute_mode = confidential_compute_mode
        self.enable_secure_boot = enable_secure_boot
        self.metadata_service = metadata_service
        self.name = name
        self.placement_target = placement_target
        self.profile = profile
        self.reservation_affinity = reservation_affinity
        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 := _dict.get('availability_policy')) is not None:
            args['availability_policy'] = InstanceAvailabilityPolicyPatch.from_dict(availability_policy)
        if (confidential_compute_mode := _dict.get('confidential_compute_mode')) is not None:
            args['confidential_compute_mode'] = confidential_compute_mode
        if (enable_secure_boot := _dict.get('enable_secure_boot')) is not None:
            args['enable_secure_boot'] = enable_secure_boot
        if (metadata_service := _dict.get('metadata_service')) is not None:
            args['metadata_service'] = InstanceMetadataServicePatch.from_dict(metadata_service)
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        if (placement_target := _dict.get('placement_target')) is not None:
            args['placement_target'] = placement_target
        if (profile := _dict.get('profile')) is not None:
            args['profile'] = profile
        if (reservation_affinity := _dict.get('reservation_affinity')) is not None:
            args['reservation_affinity'] = InstanceReservationAffinityPatch.from_dict(reservation_affinity)
        if (total_volume_bandwidth := _dict.get('total_volume_bandwidth')) is not None:
            args['total_volume_bandwidth'] = 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, 'confidential_compute_mode') and self.confidential_compute_mode is not None:
            _dict['confidential_compute_mode'] = self.confidential_compute_mode
        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, '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, 'reservation_affinity') and self.reservation_affinity is not None:
            if isinstance(self.reservation_affinity, dict):
                _dict['reservation_affinity'] = self.reservation_affinity
            else:
                _dict['reservation_affinity'] = self.reservation_affinity.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 ConfidentialComputeModeEnum(str, Enum):
        """
        The confidential compute mode to use for this virtual server instance.
        For this property to be changed, the virtual server instance `status` must be
        `stopping` or `stopped`.
        """

        DISABLED = 'disabled'
        SGX = 'sgx'



class InstancePatchProfile:
    """
    The profile to use for this virtual server instance. Any disks associated with the
    current profile will be deleted, and any disks associated with the requested profile
    will be created.
    For the profile to be changed, the instance `status` must be `stopping` or `stopped`.
    In addition, the requested profile must:
    - 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 attachments or 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.

    :param InstanceProfileBandwidth bandwidth:
    :param InstanceProfileClusterNetworkAttachmentCount
          cluster_network_attachment_count:
    :param InstanceProfileSupportedConfidentialComputeModes
          confidential_compute_modes:
    :param List[InstanceProfileDisk] disks: The disks for an instance with this
          profile.
    :param str family: The product family this virtual server instance profile
          belongs to.
    :param InstanceProfileGPU gpu_count: (optional)
    :param InstanceProfileGPUManufacturer gpu_manufacturer: (optional)
    :param InstanceProfileGPUMemory gpu_memory: (optional)
    :param InstanceProfileGPUModel gpu_model: (optional)
    :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 InstanceProfileNetworkAttachmentCount network_attachment_count:
    :param InstanceProfileNetworkInterfaceCount network_interface_count:
    :param InstanceProfileNUMACount numa_count: (optional)
    :param InstanceProfileOSArchitecture os_architecture:
    :param InstanceProfilePortSpeed port_speed:
    :param InstanceProfileReservationTerms reservation_terms:
    :param str resource_type: The resource type.
    :param InstanceProfileSupportedSecureBootModes secure_boot_modes:
    :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.
          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 may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :param List[ClusterNetworkProfileReference] supported_cluster_network_profiles:
          The cluster network profiles that support this instance profile.
    :param InstanceProfileVolumeBandwidth total_volume_bandwidth:
    :param InstanceProfileVCPUArchitecture vcpu_architecture:
    :param InstanceProfileVCPU vcpu_count:
    :param InstanceProfileVCPUManufacturer vcpu_manufacturer:
    """

    def __init__(
        self,
        bandwidth: 'InstanceProfileBandwidth',
        cluster_network_attachment_count: 'InstanceProfileClusterNetworkAttachmentCount',
        confidential_compute_modes: 'InstanceProfileSupportedConfidentialComputeModes',
        disks: List['InstanceProfileDisk'],
        family: str,
        href: str,
        memory: 'InstanceProfileMemory',
        name: str,
        network_attachment_count: 'InstanceProfileNetworkAttachmentCount',
        network_interface_count: 'InstanceProfileNetworkInterfaceCount',
        os_architecture: 'InstanceProfileOSArchitecture',
        port_speed: 'InstanceProfilePortSpeed',
        reservation_terms: 'InstanceProfileReservationTerms',
        resource_type: str,
        secure_boot_modes: 'InstanceProfileSupportedSecureBootModes',
        status: str,
        supported_cluster_network_profiles: List['ClusterNetworkProfileReference'],
        total_volume_bandwidth: 'InstanceProfileVolumeBandwidth',
        vcpu_architecture: 'InstanceProfileVCPUArchitecture',
        vcpu_count: 'InstanceProfileVCPU',
        vcpu_manufacturer: 'InstanceProfileVCPUManufacturer',
        *,
        gpu_count: Optional['InstanceProfileGPU'] = None,
        gpu_manufacturer: Optional['InstanceProfileGPUManufacturer'] = None,
        gpu_memory: Optional['InstanceProfileGPUMemory'] = None,
        gpu_model: Optional['InstanceProfileGPUModel'] = None,
        numa_count: Optional['InstanceProfileNUMACount'] = None,
    ) -> None:
        """
        Initialize a InstanceProfile object.

        :param InstanceProfileBandwidth bandwidth:
        :param InstanceProfileClusterNetworkAttachmentCount
               cluster_network_attachment_count:
        :param InstanceProfileSupportedConfidentialComputeModes
               confidential_compute_modes:
        :param List[InstanceProfileDisk] disks: The disks for an instance with this
               profile.
        :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 InstanceProfileNetworkAttachmentCount network_attachment_count:
        :param InstanceProfileNetworkInterfaceCount network_interface_count:
        :param InstanceProfileOSArchitecture os_architecture:
        :param InstanceProfilePortSpeed port_speed:
        :param InstanceProfileReservationTerms reservation_terms:
        :param str resource_type: The resource type.
        :param InstanceProfileSupportedSecureBootModes secure_boot_modes:
        :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.
               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 may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :param List[ClusterNetworkProfileReference]
               supported_cluster_network_profiles: The cluster network profiles that
               support this instance profile.
        :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.cluster_network_attachment_count = cluster_network_attachment_count
        self.confidential_compute_modes = confidential_compute_modes
        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_attachment_count = network_attachment_count
        self.network_interface_count = network_interface_count
        self.numa_count = numa_count
        self.os_architecture = os_architecture
        self.port_speed = port_speed
        self.reservation_terms = reservation_terms
        self.resource_type = resource_type
        self.secure_boot_modes = secure_boot_modes
        self.status = status
        self.supported_cluster_network_profiles = supported_cluster_network_profiles
        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 := _dict.get('bandwidth')) is not None:
            args['bandwidth'] = bandwidth
        else:
            raise ValueError('Required property \'bandwidth\' not present in InstanceProfile JSON')
        if (cluster_network_attachment_count := _dict.get('cluster_network_attachment_count')) is not None:
            args['cluster_network_attachment_count'] = cluster_network_attachment_count
        else:
            raise ValueError('Required property \'cluster_network_attachment_count\' not present in InstanceProfile JSON')
        if (confidential_compute_modes := _dict.get('confidential_compute_modes')) is not None:
            args['confidential_compute_modes'] = InstanceProfileSupportedConfidentialComputeModes.from_dict(confidential_compute_modes)
        else:
            raise ValueError('Required property \'confidential_compute_modes\' not present in InstanceProfile JSON')
        if (disks := _dict.get('disks')) is not None:
            args['disks'] = [InstanceProfileDisk.from_dict(v) for v in disks]
        else:
            raise ValueError('Required property \'disks\' not present in InstanceProfile JSON')
        if (family := _dict.get('family')) is not None:
            args['family'] = family
        else:
            raise ValueError('Required property \'family\' not present in InstanceProfile JSON')
        if (gpu_count := _dict.get('gpu_count')) is not None:
            args['gpu_count'] = gpu_count
        if (gpu_manufacturer := _dict.get('gpu_manufacturer')) is not None:
            args['gpu_manufacturer'] = InstanceProfileGPUManufacturer.from_dict(gpu_manufacturer)
        if (gpu_memory := _dict.get('gpu_memory')) is not None:
            args['gpu_memory'] = gpu_memory
        if (gpu_model := _dict.get('gpu_model')) is not None:
            args['gpu_model'] = InstanceProfileGPUModel.from_dict(gpu_model)
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in InstanceProfile JSON')
        if (memory := _dict.get('memory')) is not None:
            args['memory'] = memory
        else:
            raise ValueError('Required property \'memory\' not present in InstanceProfile JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in InstanceProfile JSON')
        if (network_attachment_count := _dict.get('network_attachment_count')) is not None:
            args['network_attachment_count'] = network_attachment_count
        else:
            raise ValueError('Required property \'network_attachment_count\' not present in InstanceProfile JSON')
        if (network_interface_count := _dict.get('network_interface_count')) is not None:
            args['network_interface_count'] = network_interface_count
        else:
            raise ValueError('Required property \'network_interface_count\' not present in InstanceProfile JSON')
        if (numa_count := _dict.get('numa_count')) is not None:
            args['numa_count'] = numa_count
        if (os_architecture := _dict.get('os_architecture')) is not None:
            args['os_architecture'] = InstanceProfileOSArchitecture.from_dict(os_architecture)
        else:
            raise ValueError('Required property \'os_architecture\' not present in InstanceProfile JSON')
        if (port_speed := _dict.get('port_speed')) is not None:
            args['port_speed'] = port_speed
        else:
            raise ValueError('Required property \'port_speed\' not present in InstanceProfile JSON')
        if (reservation_terms := _dict.get('reservation_terms')) is not None:
            args['reservation_terms'] = InstanceProfileReservationTerms.from_dict(reservation_terms)
        else:
            raise ValueError('Required property \'reservation_terms\' not present in InstanceProfile JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = resource_type
        else:
            raise ValueError('Required property \'resource_type\' not present in InstanceProfile JSON')
        if (secure_boot_modes := _dict.get('secure_boot_modes')) is not None:
            args['secure_boot_modes'] = InstanceProfileSupportedSecureBootModes.from_dict(secure_boot_modes)
        else:
            raise ValueError('Required property \'secure_boot_modes\' not present in InstanceProfile JSON')
        if (status := _dict.get('status')) is not None:
            args['status'] = status
        else:
            raise ValueError('Required property \'status\' not present in InstanceProfile JSON')
        if (supported_cluster_network_profiles := _dict.get('supported_cluster_network_profiles')) is not None:
            args['supported_cluster_network_profiles'] = [ClusterNetworkProfileReference.from_dict(v) for v in supported_cluster_network_profiles]
        else:
            raise ValueError('Required property \'supported_cluster_network_profiles\' not present in InstanceProfile JSON')
        if (total_volume_bandwidth := _dict.get('total_volume_bandwidth')) is not None:
            args['total_volume_bandwidth'] = total_volume_bandwidth
        else:
            raise ValueError('Required property \'total_volume_bandwidth\' not present in InstanceProfile JSON')
        if (vcpu_architecture := _dict.get('vcpu_architecture')) is not None:
            args['vcpu_architecture'] = InstanceProfileVCPUArchitecture.from_dict(vcpu_architecture)
        else:
            raise ValueError('Required property \'vcpu_architecture\' not present in InstanceProfile JSON')
        if (vcpu_count := _dict.get('vcpu_count')) is not None:
            args['vcpu_count'] = vcpu_count
        else:
            raise ValueError('Required property \'vcpu_count\' not present in InstanceProfile JSON')
        if (vcpu_manufacturer := _dict.get('vcpu_manufacturer')) is not None:
            args['vcpu_manufacturer'] = InstanceProfileVCPUManufacturer.from_dict(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, 'cluster_network_attachment_count') and self.cluster_network_attachment_count is not None:
            if isinstance(self.cluster_network_attachment_count, dict):
                _dict['cluster_network_attachment_count'] = self.cluster_network_attachment_count
            else:
                _dict['cluster_network_attachment_count'] = self.cluster_network_attachment_count.to_dict()
        if hasattr(self, 'confidential_compute_modes') and self.confidential_compute_modes is not None:
            if isinstance(self.confidential_compute_modes, dict):
                _dict['confidential_compute_modes'] = self.confidential_compute_modes
            else:
                _dict['confidential_compute_modes'] = self.confidential_compute_modes.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_attachment_count') and self.network_attachment_count is not None:
            if isinstance(self.network_attachment_count, dict):
                _dict['network_attachment_count'] = self.network_attachment_count
            else:
                _dict['network_attachment_count'] = self.network_attachment_count.to_dict()
        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, 'reservation_terms') and self.reservation_terms is not None:
            if isinstance(self.reservation_terms, dict):
                _dict['reservation_terms'] = self.reservation_terms
            else:
                _dict['reservation_terms'] = self.reservation_terms.to_dict()
        if hasattr(self, 'resource_type') and self.resource_type is not None:
            _dict['resource_type'] = self.resource_type
        if hasattr(self, 'secure_boot_modes') and self.secure_boot_modes is not None:
            if isinstance(self.secure_boot_modes, dict):
                _dict['secure_boot_modes'] = self.secure_boot_modes
            else:
                _dict['secure_boot_modes'] = self.secure_boot_modes.to_dict()
        if hasattr(self, 'status') and self.status is not None:
            _dict['status'] = self.status
        if hasattr(self, 'supported_cluster_network_profiles') and self.supported_cluster_network_profiles is not None:
            supported_cluster_network_profiles_list = []
            for v in self.supported_cluster_network_profiles:
                if isinstance(v, dict):
                    supported_cluster_network_profiles_list.append(v)
                else:
                    supported_cluster_network_profiles_list.append(v.to_dict())
            _dict['supported_cluster_network_profiles'] = supported_cluster_network_profiles_list
        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 ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        INSTANCE_PROFILE = 'instance_profile'


    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.
        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 may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        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 InstanceProfileClusterNetworkAttachmentCount:
    """
    InstanceProfileClusterNetworkAttachmentCount.

    """

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

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


class InstanceProfileCollection:
    """
    InstanceProfileCollection.

    :param List[InstanceProfile] profiles: A page of virtual server instance
          profiles.
    """

    def __init__(
        self,
        profiles: List['InstanceProfile'],
    ) -> None:
        """
        Initialize a InstanceProfileCollection object.

        :param List[InstanceProfile] profiles: A page 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 := _dict.get('profiles')) is not None:
            args['profiles'] = [InstanceProfile.from_dict(v) for v in 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.

    :param InstanceProfileDiskQuantity quantity:
    :param InstanceProfileDiskSize size:
    :param 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 := _dict.get('quantity')) is not None:
            args['quantity'] = quantity
        else:
            raise ValueError('Required property \'quantity\' not present in InstanceProfileDisk JSON')
        if (size := _dict.get('size')) is not None:
            args['size'] = size
        else:
            raise ValueError('Required property \'size\' not present in InstanceProfileDisk JSON')
        if (supported_interface_types := _dict.get('supported_interface_types')) is not None:
            args['supported_interface_types'] = InstanceProfileDiskSupportedInterfaces.from_dict(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.

    :param str default: The disk interface used for attaching the disk.
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :param str type: The type for this profile field.
    :param 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 may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :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 := _dict.get('default')) is not None:
            args['default'] = default
        else:
            raise ValueError('Required property \'default\' not present in InstanceProfileDiskSupportedInterfaces JSON')
        if (type := _dict.get('type')) is not None:
            args['type'] = type
        else:
            raise ValueError('Required property \'type\' not present in InstanceProfileDiskSupportedInterfaces JSON')
        if (values := _dict.get('values')) is not None:
            args['values'] = 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 may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        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 may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        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.

    :param str type: The type for this profile field.
    :param 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 := _dict.get('type')) is not None:
            args['type'] = type
        else:
            raise ValueError('Required property \'type\' not present in InstanceProfileGPUManufacturer JSON')
        if (values := _dict.get('values')) is not None:
            args['values'] = 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.

    :param str type: The type for this profile field.
    :param 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 := _dict.get('type')) is not None:
            args['type'] = type
        else:
            raise ValueError('Required property \'type\' not present in InstanceProfileGPUModel JSON')
        if (values := _dict.get('values')) is not None:
            args['values'] = 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 InstanceProfileNetworkAttachmentCount:
    """
    InstanceProfileNetworkAttachmentCount.

    """

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

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['InstanceProfileNetworkAttachmentCountRange', 'InstanceProfileNetworkAttachmentCountDependent'])
        )
        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.

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

    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 := _dict.get('default')) is not None:
            args['default'] = default
        else:
            raise ValueError('Required property \'default\' not present in InstanceProfileOSArchitecture JSON')
        if (type := _dict.get('type')) is not None:
            args['type'] = type
        else:
            raise ValueError('Required property \'type\' not present in InstanceProfileOSArchitecture JSON')
        if (values := _dict.get('values')) is not None:
            args['values'] = 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.

    :param str href: The URL for this virtual server instance profile.
    :param str name: The globally unique name for this virtual server instance
          profile.
    :param str resource_type: The resource type.
    """

    def __init__(
        self,
        href: str,
        name: str,
        resource_type: 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.
        :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) -> 'InstanceProfileReference':
        """Initialize a InstanceProfileReference object from a json dictionary."""
        args = {}
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in InstanceProfileReference JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in InstanceProfileReference JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = resource_type
        else:
            raise ValueError('Required property \'resource_type\' 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
        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 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 ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        INSTANCE_PROFILE = 'instance_profile'



class InstanceProfileReservationTerms:
    """
    InstanceProfileReservationTerms.

    :param str type: The type for this profile field.
    :param List[str] values: The supported committed use terms for a reservation
          using this profile.
    """

    def __init__(
        self,
        type: str,
        values: List[str],
    ) -> None:
        """
        Initialize a InstanceProfileReservationTerms object.

        :param str type: The type for this profile field.
        :param List[str] values: The supported committed use terms for a
               reservation using this profile.
        """
        self.type = type
        self.values = values

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

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

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

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

        ONE_YEAR = 'one_year'
        THREE_YEAR = 'three_year'



class InstanceProfileSupportedConfidentialComputeModes:
    """
    InstanceProfileSupportedConfidentialComputeModes.

    :param str default: The default confidential compute mode for this profile.
    :param str type: The type for this profile field.
    :param List[str] values: The supported confidential compute modes.
    """

    def __init__(
        self,
        default: str,
        type: str,
        values: List[str],
    ) -> None:
        """
        Initialize a InstanceProfileSupportedConfidentialComputeModes object.

        :param str default: The default confidential compute mode for this profile.
        :param str type: The type for this profile field.
        :param List[str] values: The supported confidential compute modes.
        """
        self.default = default
        self.type = type
        self.values = values

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

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

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

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

    class DefaultEnum(str, Enum):
        """
        The default confidential compute mode for this profile.
        """

        DISABLED = 'disabled'
        SGX = 'sgx'


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

        ENUM = 'enum'


    class ValuesEnum(str, Enum):
        """
        The confidential compute modes:
        - `sgx`: Intel Software Guard Extensions
        - `disabled`: No confidential compute functionality
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        DISABLED = 'disabled'
        SGX = 'sgx'



class InstanceProfileSupportedSecureBootModes:
    """
    InstanceProfileSupportedSecureBootModes.

    :param bool default: The default secure boot mode for this profile.
    :param str type: The type for this profile field.
    :param List[bool] values: The supported `enable_secure_boot` values for an
          instance using this profile.
    """

    def __init__(
        self,
        default: bool,
        type: str,
        values: List[bool],
    ) -> None:
        """
        Initialize a InstanceProfileSupportedSecureBootModes object.

        :param bool default: The default secure boot mode for this profile.
        :param str type: The type for this profile field.
        :param List[bool] values: The supported `enable_secure_boot` values for an
               instance using this profile.
        """
        self.default = default
        self.type = type
        self.values = values

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

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

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

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

    :param str default: (optional) The default VCPU architecture for an instance
          with this profile.
    :param str type: The type for this profile field.
    :param str value: The VCPU architecture for an instance with this profile.
    """

    def __init__(
        self,
        type: str,
        value: str,
        *,
        default: Optional[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 := _dict.get('default')) is not None:
            args['default'] = default
        if (type := _dict.get('type')) is not None:
            args['type'] = type
        else:
            raise ValueError('Required property \'type\' not present in InstanceProfileVCPUArchitecture JSON')
        if (value := _dict.get('value')) is not None:
            args['value'] = 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.

    :param str default: (optional) The default VCPU manufacturer for an instance
          with this profile.
    :param str type: The type for this profile field.
    :param str value: The VCPU manufacturer for an instance with this profile.
    """

    def __init__(
        self,
        type: str,
        value: str,
        *,
        default: Optional[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 := _dict.get('default')) is not None:
            args['default'] = default
        if (type := _dict.get('type')) is not None:
            args['type'] = type
        else:
            raise ValueError('Required property \'type\' not present in InstanceProfileVCPUManufacturer JSON')
        if (value := _dict.get('value')) is not None:
            args['value'] = 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.

    :param InstanceAvailabilityPolicyPrototype availability_policy: (optional) The
          availability policy to use for this virtual server instance.
    :param List[InstanceClusterNetworkAttachmentPrototypeInstanceContext]
          cluster_network_attachments: (optional) The cluster network attachments to
          create for this virtual server instance. A cluster network attachment represents
          a device that is connected to a cluster network. The number of network
          attachments must match one of the values from the instance profile's
          `cluster_network_attachment_count` before the instance can be started.
    :param str confidential_compute_mode: (optional) The confidential compute mode
          to use for this virtual server instance.
          If unspecified, the default confidential compute mode from the profile will be
          used.
    :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 bool enable_secure_boot: (optional) Indicates whether secure boot is
          enabled for this virtual server instance.
          If unspecified, the default secure boot mode from the profile will be used.
    :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.
          If specified, `reservation_affinity.policy` must be `disabled`.
    :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 InstanceReservationAffinityPrototype reservation_affinity: (optional)
    :param ResourceGroupIdentity resource_group: (optional) The resource group to
          use. If unspecified, the account's [default resource
          group](https://cloud.ibm.com/apidocs/resource-manager#introduction) 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
          attachments or instance network interfaces.
    """

    def __init__(
        self,
        *,
        availability_policy: Optional['InstanceAvailabilityPolicyPrototype'] = None,
        cluster_network_attachments: Optional[List['InstanceClusterNetworkAttachmentPrototypeInstanceContext']] = None,
        confidential_compute_mode: Optional[str] = None,
        default_trusted_profile: Optional['InstanceDefaultTrustedProfilePrototype'] = None,
        enable_secure_boot: Optional[bool] = None,
        keys: Optional[List['KeyIdentity']] = None,
        metadata_service: Optional['InstanceMetadataServicePrototype'] = None,
        name: Optional[str] = None,
        placement_target: Optional['InstancePlacementTargetPrototype'] = None,
        profile: Optional['InstanceProfileIdentity'] = None,
        reservation_affinity: Optional['InstanceReservationAffinityPrototype'] = None,
        resource_group: Optional['ResourceGroupIdentity'] = None,
        total_volume_bandwidth: Optional[int] = None,
        user_data: Optional[str] = None,
        volume_attachments: Optional[List['VolumeAttachmentPrototype']] = None,
        vpc: Optional['VPCIdentity'] = None,
    ) -> None:
        """
        Initialize a InstancePrototype object.

        :param InstanceAvailabilityPolicyPrototype availability_policy: (optional)
               The availability policy to use for this virtual server instance.
        :param List[InstanceClusterNetworkAttachmentPrototypeInstanceContext]
               cluster_network_attachments: (optional) The cluster network attachments to
               create for this virtual server instance. A cluster network attachment
               represents a device that is connected to a cluster network. The number of
               network attachments must match one of the values from the instance
               profile's `cluster_network_attachment_count` before the instance can be
               started.
        :param str confidential_compute_mode: (optional) The confidential compute
               mode to use for this virtual server instance.
               If unspecified, the default confidential compute mode from the profile will
               be used.
        :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 bool enable_secure_boot: (optional) Indicates whether secure boot is
               enabled for this virtual server instance.
               If unspecified, the default secure boot mode from the profile will be used.
        :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.
               If specified, `reservation_affinity.policy` must be `disabled`.
        :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 InstanceReservationAffinityPrototype reservation_affinity:
               (optional)
        :param ResourceGroupIdentity resource_group: (optional) The resource group
               to use. If unspecified, the account's [default resource
               group](https://cloud.ibm.com/apidocs/resource-manager#introduction) 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
               attachments or 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 ConfidentialComputeModeEnum(str, Enum):
        """
        The confidential compute mode to use for this virtual server instance.
        If unspecified, the default confidential compute mode from the profile will be
        used.
        """

        DISABLED = 'disabled'
        SGX = 'sgx'



class InstanceReference:
    """
    InstanceReference.

    :param str crn: The CRN for this virtual server instance.
    :param Deleted deleted: (optional) If present, this property indicates the
          referenced resource has been deleted, and provides
          some supplementary information.
    :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.
    """

    def __init__(
        self,
        crn: str,
        href: str,
        id: str,
        name: str,
        *,
        deleted: Optional['Deleted'] = 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 Deleted 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 := _dict.get('crn')) is not None:
            args['crn'] = crn
        else:
            raise ValueError('Required property \'crn\' not present in InstanceReference JSON')
        if (deleted := _dict.get('deleted')) is not None:
            args['deleted'] = Deleted.from_dict(deleted)
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in InstanceReference JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in InstanceReference JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = 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 InstanceReservationAffinity:
    """
    InstanceReservationAffinity.

    :param str policy: The reservation affinity policy to use for this virtual
          server instance:
          - `disabled`: Reservations will not be used
          - `manual`: Reservations in `pool` are available for use.
    :param List[ReservationReference] pool: The pool of reservations available for
          use by this virtual server instance.
    """

    def __init__(
        self,
        policy: str,
        pool: List['ReservationReference'],
    ) -> None:
        """
        Initialize a InstanceReservationAffinity object.

        :param str policy: The reservation affinity policy to use for this virtual
               server instance:
               - `disabled`: Reservations will not be used
               - `manual`: Reservations in `pool` are available for use.
        :param List[ReservationReference] pool: The pool of reservations available
               for use by this virtual server instance.
        """
        self.policy = policy
        self.pool = pool

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

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

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'policy') and self.policy is not None:
            _dict['policy'] = self.policy
        if hasattr(self, 'pool') and self.pool is not None:
            pool_list = []
            for v in self.pool:
                if isinstance(v, dict):
                    pool_list.append(v)
                else:
                    pool_list.append(v.to_dict())
            _dict['pool'] = pool_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 InstanceReservationAffinity object."""
        return json.dumps(self.to_dict(), indent=2)

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

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

    class PolicyEnum(str, Enum):
        """
        The reservation affinity policy to use for this virtual server instance:
        - `disabled`: Reservations will not be used
        - `manual`: Reservations in `pool` are available for use.
        """

        DISABLED = 'disabled'
        MANUAL = 'manual'



class InstanceReservationAffinityPatch:
    """
    InstanceReservationAffinityPatch.

    :param str policy: (optional) The reservation affinity policy to use for this
          virtual server instance:
          - `disabled`: Reservations will not be used
          - `manual`: Reservations in `pool` will be available for use
          The policy must be `disabled` if `placement_target` is set.
    :param List[ReservationIdentity] pool: (optional) The pool of reservations
          available for use by this virtual server instance, replacing the existing pool
          of reservations.
          Specified reservations must have a `status` of `active`, and have the same
          `profile` and `zone` as this virtual server instance.
          If `policy` is `manual`, `pool` must have one reservation. If `policy` is
          `disabled`, `pool` must be empty.
    """

    def __init__(
        self,
        *,
        policy: Optional[str] = None,
        pool: Optional[List['ReservationIdentity']] = None,
    ) -> None:
        """
        Initialize a InstanceReservationAffinityPatch object.

        :param str policy: (optional) The reservation affinity policy to use for
               this virtual server instance:
               - `disabled`: Reservations will not be used
               - `manual`: Reservations in `pool` will be available for use
               The policy must be `disabled` if `placement_target` is set.
        :param List[ReservationIdentity] pool: (optional) The pool of reservations
               available for use by this virtual server instance, replacing the existing
               pool of reservations.
               Specified reservations must have a `status` of `active`, and have the same
               `profile` and `zone` as this virtual server instance.
               If `policy` is `manual`, `pool` must have one reservation. If `policy` is
               `disabled`, `pool` must be empty.
        """
        self.policy = policy
        self.pool = pool

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceReservationAffinityPatch':
        """Initialize a InstanceReservationAffinityPatch object from a json dictionary."""
        args = {}
        if (policy := _dict.get('policy')) is not None:
            args['policy'] = policy
        if (pool := _dict.get('pool')) is not None:
            args['pool'] = pool
        return cls(**args)

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

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'policy') and self.policy is not None:
            _dict['policy'] = self.policy
        if hasattr(self, 'pool') and self.pool is not None:
            pool_list = []
            for v in self.pool:
                if isinstance(v, dict):
                    pool_list.append(v)
                else:
                    pool_list.append(v.to_dict())
            _dict['pool'] = pool_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 InstanceReservationAffinityPatch object."""
        return json.dumps(self.to_dict(), indent=2)

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

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

    class PolicyEnum(str, Enum):
        """
        The reservation affinity policy to use for this virtual server instance:
        - `disabled`: Reservations will not be used
        - `manual`: Reservations in `pool` will be available for use
        The policy must be `disabled` if `placement_target` is set.
        """

        DISABLED = 'disabled'
        MANUAL = 'manual'



class InstanceReservationAffinityPrototype:
    """
    InstanceReservationAffinityPrototype.

    :param str policy: (optional) The reservation affinity policy to use for this
          virtual server instance:
          - `disabled`: Reservations will not be used
          - `manual`: Reservations in `pool` will be available for use
          The policy will default to `manual` if `pool` is not empty, and `disabled`
          otherwise.
    :param List[ReservationIdentity] pool: (optional) The pool of reservations
          available for use by this virtual server instance.
          Specified reservations must have a `status` of `active`, and have the same
          `profile` and `zone` as this virtual server instance.
          If `policy` is `manual`, a pool must be specified with at least one reservation.
          If
          `policy` is `disabled` and a pool is specified, it must be empty.
    """

    def __init__(
        self,
        *,
        policy: Optional[str] = None,
        pool: Optional[List['ReservationIdentity']] = None,
    ) -> None:
        """
        Initialize a InstanceReservationAffinityPrototype object.

        :param str policy: (optional) The reservation affinity policy to use for
               this virtual server instance:
               - `disabled`: Reservations will not be used
               - `manual`: Reservations in `pool` will be available for use
               The policy will default to `manual` if `pool` is not empty, and `disabled`
               otherwise.
        :param List[ReservationIdentity] pool: (optional) The pool of reservations
               available for use by this virtual server instance.
               Specified reservations must have a `status` of `active`, and have the same
               `profile` and `zone` as this virtual server instance.
               If `policy` is `manual`, a pool must be specified with at least one
               reservation. If
               `policy` is `disabled` and a pool is specified, it must be empty.
        """
        self.policy = policy
        self.pool = pool

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceReservationAffinityPrototype':
        """Initialize a InstanceReservationAffinityPrototype object from a json dictionary."""
        args = {}
        if (policy := _dict.get('policy')) is not None:
            args['policy'] = policy
        if (pool := _dict.get('pool')) is not None:
            args['pool'] = pool
        return cls(**args)

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

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'policy') and self.policy is not None:
            _dict['policy'] = self.policy
        if hasattr(self, 'pool') and self.pool is not None:
            pool_list = []
            for v in self.pool:
                if isinstance(v, dict):
                    pool_list.append(v)
                else:
                    pool_list.append(v.to_dict())
            _dict['pool'] = pool_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 InstanceReservationAffinityPrototype object."""
        return json.dumps(self.to_dict(), indent=2)

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

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

    class PolicyEnum(str, Enum):
        """
        The reservation affinity policy to use for this virtual server instance:
        - `disabled`: Reservations will not be used
        - `manual`: Reservations in `pool` will be available for use
        The policy will default to `manual` if `pool` is not empty, and `disabled`
        otherwise.
        """

        DISABLED = 'disabled'
        MANUAL = 'manual'



class InstanceStatusReason:
    """
    InstanceStatusReason.

    :param str code: A snake case string succinctly identifying the status reason.
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :param str message: An explanation of the status reason.
    :param str more_info: (optional) Link to documentation about this status reason.
    """

    def __init__(
        self,
        code: str,
        message: str,
        *,
        more_info: Optional[str] = None,
    ) -> None:
        """
        Initialize a InstanceStatusReason object.

        :param str code: A snake case string succinctly identifying the status
               reason.
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :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 := _dict.get('code')) is not None:
            args['code'] = code
        else:
            raise ValueError('Required property \'code\' not present in InstanceStatusReason JSON')
        if (message := _dict.get('message')) is not None:
            args['message'] = message
        else:
            raise ValueError('Required property \'message\' not present in InstanceStatusReason JSON')
        if (more_info := _dict.get('more_info')) is not None:
            args['more_info'] = 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.
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        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_RESERVATION_CAPACITY = 'cannot_start_reservation_capacity'
        CANNOT_START_RESERVATION_EXPIRED = 'cannot_start_reservation_expired'
        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.

    :param InstanceAvailabilityPolicyPrototype availability_policy: (optional) The
          availability policy to use for this virtual server instance.
    :param List[InstanceClusterNetworkAttachmentPrototypeInstanceContext]
          cluster_network_attachments: (optional) The cluster network attachments to
          create for this virtual server instance. A cluster network attachment represents
          a device that is connected to a cluster network. The number of network
          attachments must match one of the values from the instance profile's
          `cluster_network_attachment_count` before the instance can be started.
    :param str confidential_compute_mode: (optional) The confidential compute mode
          to use for this virtual server instance.
          If unspecified, the default confidential compute mode from the profile will be
          used.
    :param datetime created_at: The date and time that the instance template was
          created.
    :param str crn: The CRN for this instance template.
    :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 bool enable_secure_boot: (optional) Indicates whether secure boot is
          enabled for this virtual server instance.
          If unspecified, the default secure boot mode from the profile will be used.
    :param str href: The URL for this instance template.
    :param str id: The unique identifier for this instance template.
    :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: The name for this instance template. The name is unique across
          all instance templates in the region.
    :param InstancePlacementTargetPrototype placement_target: (optional) The
          placement restrictions to use for the virtual server instance.
          If specified, `reservation_affinity.policy` must be `disabled`.
    :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 InstanceReservationAffinityPrototype reservation_affinity: (optional)
    :param ResourceGroupReference resource_group: The resource group for this
          instance template.
    :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
          attachments or instance network interfaces.
    """

    def __init__(
        self,
        created_at: datetime,
        crn: str,
        href: str,
        id: str,
        name: str,
        resource_group: 'ResourceGroupReference',
        *,
        availability_policy: Optional['InstanceAvailabilityPolicyPrototype'] = None,
        cluster_network_attachments: Optional[List['InstanceClusterNetworkAttachmentPrototypeInstanceContext']] = None,
        confidential_compute_mode: Optional[str] = None,
        default_trusted_profile: Optional['InstanceDefaultTrustedProfilePrototype'] = None,
        enable_secure_boot: Optional[bool] = None,
        keys: Optional[List['KeyIdentity']] = None,
        metadata_service: Optional['InstanceMetadataServicePrototype'] = None,
        placement_target: Optional['InstancePlacementTargetPrototype'] = None,
        profile: Optional['InstanceProfileIdentity'] = None,
        reservation_affinity: Optional['InstanceReservationAffinityPrototype'] = None,
        total_volume_bandwidth: Optional[int] = None,
        user_data: Optional[str] = None,
        volume_attachments: Optional[List['VolumeAttachmentPrototype']] = None,
        vpc: Optional['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 List[InstanceClusterNetworkAttachmentPrototypeInstanceContext]
               cluster_network_attachments: (optional) The cluster network attachments to
               create for this virtual server instance. A cluster network attachment
               represents a device that is connected to a cluster network. The number of
               network attachments must match one of the values from the instance
               profile's `cluster_network_attachment_count` before the instance can be
               started.
        :param str confidential_compute_mode: (optional) The confidential compute
               mode to use for this virtual server instance.
               If unspecified, the default confidential compute mode from the profile will
               be used.
        :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 bool enable_secure_boot: (optional) Indicates whether secure boot is
               enabled for this virtual server instance.
               If unspecified, the default secure boot mode from the profile will be used.
        :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.
               If specified, `reservation_affinity.policy` must be `disabled`.
        :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 InstanceReservationAffinityPrototype reservation_affinity:
               (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
               attachments or 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 ConfidentialComputeModeEnum(str, Enum):
        """
        The confidential compute mode to use for this virtual server instance.
        If unspecified, the default confidential compute mode from the profile will be
        used.
        """

        DISABLED = 'disabled'
        SGX = 'sgx'



class InstanceTemplateCollection:
    """
    InstanceTemplateCollection.

    :param PageLink 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 PageLink next: (optional) A link to the next page of resources. This
          property is present for all pages
          except the last page.
    :param List[InstanceTemplate] templates: A page of instance templates.
    :param int total_count: The total number of resources across all pages.
    """

    def __init__(
        self,
        first: 'PageLink',
        limit: int,
        templates: List['InstanceTemplate'],
        total_count: int,
        *,
        next: Optional['PageLink'] = None,
    ) -> None:
        """
        Initialize a InstanceTemplateCollection object.

        :param PageLink 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: A page of instance templates.
        :param int total_count: The total number of resources across all pages.
        :param PageLink 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 := _dict.get('first')) is not None:
            args['first'] = PageLink.from_dict(first)
        else:
            raise ValueError('Required property \'first\' not present in InstanceTemplateCollection JSON')
        if (limit := _dict.get('limit')) is not None:
            args['limit'] = limit
        else:
            raise ValueError('Required property \'limit\' not present in InstanceTemplateCollection JSON')
        if (next := _dict.get('next')) is not None:
            args['next'] = PageLink.from_dict(next)
        if (templates := _dict.get('templates')) is not None:
            args['templates'] = templates
        else:
            raise ValueError('Required property \'templates\' not present in InstanceTemplateCollection JSON')
        if (total_count := _dict.get('total_count')) is not None:
            args['total_count'] = 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 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.

    :param 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: Optional[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 := _dict.get('name')) is not None:
            args['name'] = 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.

    :param InstanceAvailabilityPolicyPrototype availability_policy: (optional) The
          availability policy to use for this virtual server instance.
    :param List[InstanceClusterNetworkAttachmentPrototypeInstanceContext]
          cluster_network_attachments: (optional) The cluster network attachments to
          create for this virtual server instance. A cluster network attachment represents
          a device that is connected to a cluster network. The number of network
          attachments must match one of the values from the instance profile's
          `cluster_network_attachment_count` before the instance can be started.
    :param str confidential_compute_mode: (optional) The confidential compute mode
          to use for this virtual server instance.
          If unspecified, the default confidential compute mode from the profile will be
          used.
    :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 bool enable_secure_boot: (optional) Indicates whether secure boot is
          enabled for this virtual server instance.
          If unspecified, the default secure boot mode from the profile will be used.
    :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.
          If specified, `reservation_affinity.policy` must be `disabled`.
    :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 InstanceReservationAffinityPrototype reservation_affinity: (optional)
    :param ResourceGroupIdentity resource_group: (optional) The resource group to
          use. If unspecified, the account's [default resource
          group](https://cloud.ibm.com/apidocs/resource-manager#introduction) 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
          attachments or instance network interfaces.
    """

    def __init__(
        self,
        *,
        availability_policy: Optional['InstanceAvailabilityPolicyPrototype'] = None,
        cluster_network_attachments: Optional[List['InstanceClusterNetworkAttachmentPrototypeInstanceContext']] = None,
        confidential_compute_mode: Optional[str] = None,
        default_trusted_profile: Optional['InstanceDefaultTrustedProfilePrototype'] = None,
        enable_secure_boot: Optional[bool] = None,
        keys: Optional[List['KeyIdentity']] = None,
        metadata_service: Optional['InstanceMetadataServicePrototype'] = None,
        name: Optional[str] = None,
        placement_target: Optional['InstancePlacementTargetPrototype'] = None,
        profile: Optional['InstanceProfileIdentity'] = None,
        reservation_affinity: Optional['InstanceReservationAffinityPrototype'] = None,
        resource_group: Optional['ResourceGroupIdentity'] = None,
        total_volume_bandwidth: Optional[int] = None,
        user_data: Optional[str] = None,
        volume_attachments: Optional[List['VolumeAttachmentPrototype']] = None,
        vpc: Optional['VPCIdentity'] = None,
    ) -> None:
        """
        Initialize a InstanceTemplatePrototype object.

        :param InstanceAvailabilityPolicyPrototype availability_policy: (optional)
               The availability policy to use for this virtual server instance.
        :param List[InstanceClusterNetworkAttachmentPrototypeInstanceContext]
               cluster_network_attachments: (optional) The cluster network attachments to
               create for this virtual server instance. A cluster network attachment
               represents a device that is connected to a cluster network. The number of
               network attachments must match one of the values from the instance
               profile's `cluster_network_attachment_count` before the instance can be
               started.
        :param str confidential_compute_mode: (optional) The confidential compute
               mode to use for this virtual server instance.
               If unspecified, the default confidential compute mode from the profile will
               be used.
        :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 bool enable_secure_boot: (optional) Indicates whether secure boot is
               enabled for this virtual server instance.
               If unspecified, the default secure boot mode from the profile will be used.
        :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.
               If specified, `reservation_affinity.policy` must be `disabled`.
        :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 InstanceReservationAffinityPrototype reservation_affinity:
               (optional)
        :param ResourceGroupIdentity resource_group: (optional) The resource group
               to use. If unspecified, the account's [default resource
               group](https://cloud.ibm.com/apidocs/resource-manager#introduction) 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
               attachments or 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 ConfidentialComputeModeEnum(str, Enum):
        """
        The confidential compute mode to use for this virtual server instance.
        If unspecified, the default confidential compute mode from the profile will be
        used.
        """

        DISABLED = 'disabled'
        SGX = 'sgx'



class InstanceTemplateReference:
    """
    InstanceTemplateReference.

    :param str crn: The CRN for this instance template.
    :param Deleted deleted: (optional) If present, this property indicates the
          referenced resource has been deleted, and provides
          some supplementary information.
    :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.
    """

    def __init__(
        self,
        crn: str,
        href: str,
        id: str,
        name: str,
        *,
        deleted: Optional['Deleted'] = 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 Deleted 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 := _dict.get('crn')) is not None:
            args['crn'] = crn
        else:
            raise ValueError('Required property \'crn\' not present in InstanceTemplateReference JSON')
        if (deleted := _dict.get('deleted')) is not None:
            args['deleted'] = Deleted.from_dict(deleted)
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in InstanceTemplateReference JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in InstanceTemplateReference JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = 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 InstanceVCPU:
    """
    The virtual server instance VCPU configuration.

    :param str architecture: The VCPU architecture.
    :param int count: The number of VCPUs assigned.
    :param 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 := _dict.get('architecture')) is not None:
            args['architecture'] = architecture
        else:
            raise ValueError('Required property \'architecture\' not present in InstanceVCPU JSON')
        if (count := _dict.get('count')) is not None:
            args['count'] = count
        else:
            raise ValueError('Required property \'count\' not present in InstanceVCPU JSON')
        if (manufacturer := _dict.get('manufacturer')) is not None:
            args['manufacturer'] = 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.

    :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 for this key.
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    """

    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 for this key.
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        """
        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 := _dict.get('created_at')) is not None:
            args['created_at'] = string_to_datetime(created_at)
        else:
            raise ValueError('Required property \'created_at\' not present in Key JSON')
        if (crn := _dict.get('crn')) is not None:
            args['crn'] = crn
        else:
            raise ValueError('Required property \'crn\' not present in Key JSON')
        if (fingerprint := _dict.get('fingerprint')) is not None:
            args['fingerprint'] = fingerprint
        else:
            raise ValueError('Required property \'fingerprint\' not present in Key JSON')
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in Key JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in Key JSON')
        if (length := _dict.get('length')) is not None:
            args['length'] = length
        else:
            raise ValueError('Required property \'length\' not present in Key JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in Key JSON')
        if (public_key := _dict.get('public_key')) is not None:
            args['public_key'] = public_key
        else:
            raise ValueError('Required property \'public_key\' not present in Key JSON')
        if (resource_group := _dict.get('resource_group')) is not None:
            args['resource_group'] = ResourceGroupReference.from_dict(resource_group)
        else:
            raise ValueError('Required property \'resource_group\' not present in Key JSON')
        if (type := _dict.get('type')) is not None:
            args['type'] = 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 for this key.
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        ED25519 = 'ed25519'
        RSA = 'rsa'



class KeyCollection:
    """
    KeyCollection.

    :param PageLink first: A link to the first page of resources.
    :param List[Key] keys: A page of keys.
    :param int limit: The maximum number of resources that can be returned by the
          request.
    :param PageLink next: (optional) A link to the next page of resources. This
          property is present for all pages
          except the last page.
    :param int total_count: The total number of resources across all pages.
    """

    def __init__(
        self,
        first: 'PageLink',
        keys: List['Key'],
        limit: int,
        total_count: int,
        *,
        next: Optional['PageLink'] = None,
    ) -> None:
        """
        Initialize a KeyCollection object.

        :param PageLink first: A link to the first page of resources.
        :param List[Key] keys: A page 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 PageLink 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 := _dict.get('first')) is not None:
            args['first'] = PageLink.from_dict(first)
        else:
            raise ValueError('Required property \'first\' not present in KeyCollection JSON')
        if (keys := _dict.get('keys')) is not None:
            args['keys'] = [Key.from_dict(v) for v in keys]
        else:
            raise ValueError('Required property \'keys\' not present in KeyCollection JSON')
        if (limit := _dict.get('limit')) is not None:
            args['limit'] = limit
        else:
            raise ValueError('Required property \'limit\' not present in KeyCollection JSON')
        if (next := _dict.get('next')) is not None:
            args['next'] = PageLink.from_dict(next)
        if (total_count := _dict.get('total_count')) is not None:
            args['total_count'] = 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 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.

    :param str name: (optional) The name for this key. The name must not be used by
          another key in the region.
    """

    def __init__(
        self,
        *,
        name: Optional[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 := _dict.get('name')) is not None:
            args['name'] = 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.

    :param str crn: The CRN for this key.
    :param Deleted deleted: (optional) If present, this property indicates the
          referenced resource has been deleted, and provides
          some supplementary information.
    :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.
    """

    def __init__(
        self,
        crn: str,
        fingerprint: str,
        href: str,
        id: str,
        name: str,
        *,
        deleted: Optional['Deleted'] = 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 Deleted 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 := _dict.get('crn')) is not None:
            args['crn'] = crn
        else:
            raise ValueError('Required property \'crn\' not present in KeyReference JSON')
        if (deleted := _dict.get('deleted')) is not None:
            args['deleted'] = Deleted.from_dict(deleted)
        if (fingerprint := _dict.get('fingerprint')) is not None:
            args['fingerprint'] = fingerprint
        else:
            raise ValueError('Required property \'fingerprint\' not present in KeyReference JSON')
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in KeyReference JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in KeyReference JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = 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 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.

    :param 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 := _dict.get('name')) is not None:
            args['name'] = 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.

    :param str access_mode: The access mode for this load balancer:
          - `private`: reachable from within its VPC, at IP addresses in `private_ips`
          - `private_path`: reachable through an endpoint gateway
          - `public`: reachable from the internet at the IP addresses in `public_ips`.
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :param str availability: The availability of this load balancer:
          - `subnet`: remains available if at least one zone that the load balancer's
          subnets reside
            in is available
          - `region`: remains available if at least one zone in the region is available.
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :param datetime created_at: The date and time that this load balancer was
          created.
    :param str crn: The CRN for this load balancer.
    :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`.
          Not supported by private path load balancers.
    :param str hostname: Fully qualified domain name assigned to this load balancer.
    :param str href: The URL for this load balancer.
    :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_private_path: Indicates whether this is a private path load
          balancer.
    :param bool is_public: The type of this load balancer, public or private.
    :param List[LoadBalancerListenerReference] listeners: The listeners of this load
          balancer.
    :param LoadBalancerLogging logging: The logging configuration for this load
          balancer.
    :param str name: The 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.
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :param List[LoadBalancerPoolReference] pools: The pools of this load balancer.
    :param List[ReservedIPReference] private_ips: The private IP addresses assigned
          to this load balancer.
          Will be empty if `is_private` is `false`.
    :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 may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :param List[IP] public_ips: The public IP addresses assigned to this load
          balancer.
          Will be empty if `is_public` is `false`.
    :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.
    :param bool security_groups_supported: Indicates whether this load balancer
          supports security groups.
    :param bool source_ip_session_persistence_supported: Indicates whether this load
          balancer supports source IP session persistence.
    :param List[SubnetReference] subnets: The subnets this load balancer is
          provisioned in.
          All subnets will be in the same VPC.
    :param bool udp_supported: Indicates whether this load balancer supports UDP.
    """

    def __init__(
        self,
        access_mode: str,
        availability: str,
        created_at: datetime,
        crn: str,
        hostname: str,
        href: str,
        id: str,
        instance_groups_supported: bool,
        is_private_path: bool,
        is_public: bool,
        listeners: List['LoadBalancerListenerReference'],
        logging: 'LoadBalancerLogging',
        name: str,
        operating_status: str,
        pools: List['LoadBalancerPoolReference'],
        private_ips: List['ReservedIPReference'],
        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,
        source_ip_session_persistence_supported: bool,
        subnets: List['SubnetReference'],
        udp_supported: bool,
        *,
        dns: Optional['LoadBalancerDNS'] = None,
    ) -> None:
        """
        Initialize a LoadBalancer object.

        :param str access_mode: The access mode for this load balancer:
               - `private`: reachable from within its VPC, at IP addresses in
               `private_ips`
               - `private_path`: reachable through an endpoint gateway
               - `public`: reachable from the internet at the IP addresses in
               `public_ips`.
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :param str availability: The availability of this load balancer:
               - `subnet`: remains available if at least one zone that the load balancer's
               subnets reside
                 in is available
               - `region`: remains available if at least one zone in the region is
               available.
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :param datetime created_at: The date and time that this load balancer was
               created.
        :param str crn: The CRN for this load balancer.
        :param str hostname: Fully qualified domain name assigned to this load
               balancer.
        :param str href: The URL for this load balancer.
        :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_private_path: Indicates whether this is a private path load
               balancer.
        :param bool is_public: The type of this load balancer, public or private.
        :param List[LoadBalancerListenerReference] listeners: The listeners of this
               load balancer.
        :param LoadBalancerLogging logging: The logging configuration for this load
               balancer.
        :param str name: The 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.
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :param List[LoadBalancerPoolReference] pools: The pools of this load
               balancer.
        :param List[ReservedIPReference] private_ips: The private IP addresses
               assigned to this load balancer.
               Will be empty if `is_private` is `false`.
        :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 may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :param List[IP] public_ips: The public IP addresses assigned to this load
               balancer.
               Will be empty if `is_public` is `false`.
        :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.
        :param bool security_groups_supported: Indicates whether this load balancer
               supports security groups.
        :param bool source_ip_session_persistence_supported: Indicates whether this
               load balancer supports source IP session persistence.
        :param List[SubnetReference] subnets: The subnets this load balancer is
               provisioned 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`.
               Not supported by private path load balancers.
        """
        self.access_mode = access_mode
        self.availability = availability
        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_private_path = is_private_path
        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.source_ip_session_persistence_supported = source_ip_session_persistence_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 (access_mode := _dict.get('access_mode')) is not None:
            args['access_mode'] = access_mode
        else:
            raise ValueError('Required property \'access_mode\' not present in LoadBalancer JSON')
        if (availability := _dict.get('availability')) is not None:
            args['availability'] = availability
        else:
            raise ValueError('Required property \'availability\' not present in LoadBalancer JSON')
        if (created_at := _dict.get('created_at')) is not None:
            args['created_at'] = string_to_datetime(created_at)
        else:
            raise ValueError('Required property \'created_at\' not present in LoadBalancer JSON')
        if (crn := _dict.get('crn')) is not None:
            args['crn'] = crn
        else:
            raise ValueError('Required property \'crn\' not present in LoadBalancer JSON')
        if (dns := _dict.get('dns')) is not None:
            args['dns'] = LoadBalancerDNS.from_dict(dns)
        if (hostname := _dict.get('hostname')) is not None:
            args['hostname'] = hostname
        else:
            raise ValueError('Required property \'hostname\' not present in LoadBalancer JSON')
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in LoadBalancer JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in LoadBalancer JSON')
        if (instance_groups_supported := _dict.get('instance_groups_supported')) is not None:
            args['instance_groups_supported'] = instance_groups_supported
        else:
            raise ValueError('Required property \'instance_groups_supported\' not present in LoadBalancer JSON')
        if (is_private_path := _dict.get('is_private_path')) is not None:
            args['is_private_path'] = is_private_path
        else:
            raise ValueError('Required property \'is_private_path\' not present in LoadBalancer JSON')
        if (is_public := _dict.get('is_public')) is not None:
            args['is_public'] = is_public
        else:
            raise ValueError('Required property \'is_public\' not present in LoadBalancer JSON')
        if (listeners := _dict.get('listeners')) is not None:
            args['listeners'] = [LoadBalancerListenerReference.from_dict(v) for v in listeners]
        else:
            raise ValueError('Required property \'listeners\' not present in LoadBalancer JSON')
        if (logging := _dict.get('logging')) is not None:
            args['logging'] = LoadBalancerLogging.from_dict(logging)
        else:
            raise ValueError('Required property \'logging\' not present in LoadBalancer JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in LoadBalancer JSON')
        if (operating_status := _dict.get('operating_status')) is not None:
            args['operating_status'] = operating_status
        else:
            raise ValueError('Required property \'operating_status\' not present in LoadBalancer JSON')
        if (pools := _dict.get('pools')) is not None:
            args['pools'] = [LoadBalancerPoolReference.from_dict(v) for v in pools]
        else:
            raise ValueError('Required property \'pools\' not present in LoadBalancer JSON')
        if (private_ips := _dict.get('private_ips')) is not None:
            args['private_ips'] = [ReservedIPReference.from_dict(v) for v in private_ips]
        else:
            raise ValueError('Required property \'private_ips\' not present in LoadBalancer JSON')
        if (profile := _dict.get('profile')) is not None:
            args['profile'] = LoadBalancerProfileReference.from_dict(profile)
        else:
            raise ValueError('Required property \'profile\' not present in LoadBalancer JSON')
        if (provisioning_status := _dict.get('provisioning_status')) is not None:
            args['provisioning_status'] = provisioning_status
        else:
            raise ValueError('Required property \'provisioning_status\' not present in LoadBalancer JSON')
        if (public_ips := _dict.get('public_ips')) is not None:
            args['public_ips'] = [IP.from_dict(v) for v in public_ips]
        else:
            raise ValueError('Required property \'public_ips\' not present in LoadBalancer JSON')
        if (resource_group := _dict.get('resource_group')) is not None:
            args['resource_group'] = ResourceGroupReference.from_dict(resource_group)
        else:
            raise ValueError('Required property \'resource_group\' not present in LoadBalancer JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = resource_type
        else:
            raise ValueError('Required property \'resource_type\' not present in LoadBalancer JSON')
        if (route_mode := _dict.get('route_mode')) is not None:
            args['route_mode'] = route_mode
        else:
            raise ValueError('Required property \'route_mode\' not present in LoadBalancer JSON')
        if (security_groups := _dict.get('security_groups')) is not None:
            args['security_groups'] = [SecurityGroupReference.from_dict(v) for v in security_groups]
        else:
            raise ValueError('Required property \'security_groups\' not present in LoadBalancer JSON')
        if (security_groups_supported := _dict.get('security_groups_supported')) is not None:
            args['security_groups_supported'] = security_groups_supported
        else:
            raise ValueError('Required property \'security_groups_supported\' not present in LoadBalancer JSON')
        if (source_ip_session_persistence_supported := _dict.get('source_ip_session_persistence_supported')) is not None:
            args['source_ip_session_persistence_supported'] = source_ip_session_persistence_supported
        else:
            raise ValueError('Required property \'source_ip_session_persistence_supported\' not present in LoadBalancer JSON')
        if (subnets := _dict.get('subnets')) is not None:
            args['subnets'] = [SubnetReference.from_dict(v) for v in subnets]
        else:
            raise ValueError('Required property \'subnets\' not present in LoadBalancer JSON')
        if (udp_supported := _dict.get('udp_supported')) is not None:
            args['udp_supported'] = 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, 'access_mode') and self.access_mode is not None:
            _dict['access_mode'] = self.access_mode
        if hasattr(self, 'availability') and self.availability is not None:
            _dict['availability'] = self.availability
        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_private_path') and self.is_private_path is not None:
            _dict['is_private_path'] = self.is_private_path
        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, 'source_ip_session_persistence_supported') and self.source_ip_session_persistence_supported is not None:
            _dict['source_ip_session_persistence_supported'] = self.source_ip_session_persistence_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 AccessModeEnum(str, Enum):
        """
        The access mode for this load balancer:
        - `private`: reachable from within its VPC, at IP addresses in `private_ips`
        - `private_path`: reachable through an endpoint gateway
        - `public`: reachable from the internet at the IP addresses in `public_ips`.
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        PRIVATE = 'private'
        PRIVATE_PATH = 'private_path'
        PUBLIC = 'public'


    class AvailabilityEnum(str, Enum):
        """
        The availability of this load balancer:
        - `subnet`: remains available if at least one zone that the load balancer's
        subnets reside
          in is available
        - `region`: remains available if at least one zone in the region is available.
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        REGION = 'region'
        SUBNET = 'subnet'


    class OperatingStatusEnum(str, Enum):
        """
        The operating status of this load balancer.
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        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 may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        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.

    :param PageLink 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: A page of load balancers.
    :param PageLink next: (optional) A link to the next page of resources. This
          property is present for all pages
          except the last page.
    :param int total_count: The total number of resources across all pages.
    """

    def __init__(
        self,
        first: 'PageLink',
        limit: int,
        load_balancers: List['LoadBalancer'],
        total_count: int,
        *,
        next: Optional['PageLink'] = None,
    ) -> None:
        """
        Initialize a LoadBalancerCollection object.

        :param PageLink 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: A page of load balancers.
        :param int total_count: The total number of resources across all pages.
        :param PageLink 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 := _dict.get('first')) is not None:
            args['first'] = PageLink.from_dict(first)
        else:
            raise ValueError('Required property \'first\' not present in LoadBalancerCollection JSON')
        if (limit := _dict.get('limit')) is not None:
            args['limit'] = limit
        else:
            raise ValueError('Required property \'limit\' not present in LoadBalancerCollection JSON')
        if (load_balancers := _dict.get('load_balancers')) is not None:
            args['load_balancers'] = [LoadBalancer.from_dict(v) for v in load_balancers]
        else:
            raise ValueError('Required property \'load_balancers\' not present in LoadBalancerCollection JSON')
        if (next := _dict.get('next')) is not None:
            args['next'] = PageLink.from_dict(next)
        if (total_count := _dict.get('total_count')) is not None:
            args['total_count'] = 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 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`.
    Not supported by private path load balancers.

    :param DNSInstanceReferenceLoadBalancerDNSContext instance: The DNS instance
          associated with this load balancer.
    :param DNSZoneReference zone: The DNS zone associated with this load balancer.
    """

    def __init__(
        self,
        instance: 'DNSInstanceReferenceLoadBalancerDNSContext',
        zone: 'DNSZoneReference',
    ) -> None:
        """
        Initialize a LoadBalancerDNS object.

        :param DNSInstanceReferenceLoadBalancerDNSContext 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 := _dict.get('instance')) is not None:
            args['instance'] = DNSInstanceReferenceLoadBalancerDNSContext.from_dict(instance)
        else:
            raise ValueError('Required property \'instance\' not present in LoadBalancerDNS JSON')
        if (zone := _dict.get('zone')) is not None:
            args['zone'] = DNSZoneReference.from_dict(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`.
    Not supported by private path load balancers.

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

    def __init__(
        self,
        *,
        instance: Optional['DNSInstanceIdentity'] = None,
        zone: Optional['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 := _dict.get('instance')) is not None:
            args['instance'] = instance
        if (zone := _dict.get('zone')) is not None:
            args['zone'] = 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`.
    Not supported by private path load balancers.

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

    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 := _dict.get('instance')) is not None:
            args['instance'] = instance
        else:
            raise ValueError('Required property \'instance\' not present in LoadBalancerDNSPrototype JSON')
        if (zone := _dict.get('zone')) is not None:
            args['zone'] = 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.

    :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 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 concurrent connection limit for the
          listener. If reached, incoming connections may be queued or rejected.
          This property will be present for load balancers in the `application` family.
    :param datetime created_at: The date and time that this listener was created.
    :param LoadBalancerPoolReference default_pool: (optional) The default pool for
          this listener. If absent, this listener has no default pool.
          If `https_redirect` is set, the default pool will not be used.
    :param str href: The URL for this load balancer listener.
    :param LoadBalancerListenerHTTPSRedirect https_redirect: (optional) If present,
          the target listener that requests are redirected to if none of the
          listener's `policies` match.
    :param str id: The unique identifier for this load balancer listener.
    :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.
    :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 may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :param str provisioning_status: The provisioning status of this listener
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    """

    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: Optional['CertificateInstanceReference'] = None,
        connection_limit: Optional[int] = None,
        default_pool: Optional['LoadBalancerPoolReference'] = None,
        https_redirect: Optional['LoadBalancerListenerHTTPSRedirect'] = None,
        idle_connection_timeout: Optional[int] = None,
        policies: Optional[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 URL for this load balancer listener.
        :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 may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :param str provisioning_status: The provisioning status of this listener
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :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 concurrent connection limit for
               the listener. If reached, incoming connections may be queued or rejected.
               This property will be present for load balancers in the `application`
               family.
        :param LoadBalancerPoolReference default_pool: (optional) The default pool
               for this listener. If absent, this listener has no default pool.
               If `https_redirect` is set, the default pool will not be used.
        :param LoadBalancerListenerHTTPSRedirect https_redirect: (optional) If
               present, the target listener that requests are redirected to if none of the
               listener's `policies` match.
        :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 := _dict.get('accept_proxy_protocol')) is not None:
            args['accept_proxy_protocol'] = accept_proxy_protocol
        else:
            raise ValueError('Required property \'accept_proxy_protocol\' not present in LoadBalancerListener JSON')
        if (certificate_instance := _dict.get('certificate_instance')) is not None:
            args['certificate_instance'] = CertificateInstanceReference.from_dict(certificate_instance)
        if (connection_limit := _dict.get('connection_limit')) is not None:
            args['connection_limit'] = connection_limit
        if (created_at := _dict.get('created_at')) is not None:
            args['created_at'] = string_to_datetime(created_at)
        else:
            raise ValueError('Required property \'created_at\' not present in LoadBalancerListener JSON')
        if (default_pool := _dict.get('default_pool')) is not None:
            args['default_pool'] = LoadBalancerPoolReference.from_dict(default_pool)
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in LoadBalancerListener JSON')
        if (https_redirect := _dict.get('https_redirect')) is not None:
            args['https_redirect'] = LoadBalancerListenerHTTPSRedirect.from_dict(https_redirect)
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in LoadBalancerListener JSON')
        if (idle_connection_timeout := _dict.get('idle_connection_timeout')) is not None:
            args['idle_connection_timeout'] = idle_connection_timeout
        if (policies := _dict.get('policies')) is not None:
            args['policies'] = [LoadBalancerListenerPolicyReference.from_dict(v) for v in policies]
        if (port := _dict.get('port')) is not None:
            args['port'] = port
        else:
            raise ValueError('Required property \'port\' not present in LoadBalancerListener JSON')
        if (port_max := _dict.get('port_max')) is not None:
            args['port_max'] = port_max
        else:
            raise ValueError('Required property \'port_max\' not present in LoadBalancerListener JSON')
        if (port_min := _dict.get('port_min')) is not None:
            args['port_min'] = port_min
        else:
            raise ValueError('Required property \'port_min\' not present in LoadBalancerListener JSON')
        if (protocol := _dict.get('protocol')) is not None:
            args['protocol'] = protocol
        else:
            raise ValueError('Required property \'protocol\' not present in LoadBalancerListener JSON')
        if (provisioning_status := _dict.get('provisioning_status')) is not None:
            args['provisioning_status'] = 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 may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        HTTP = 'http'
        HTTPS = 'https'
        TCP = 'tcp'
        UDP = 'udp'


    class ProvisioningStatusEnum(str, Enum):
        """
        The provisioning status of this listener
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        ACTIVE = 'active'
        CREATE_PENDING = 'create_pending'
        DELETE_PENDING = 'delete_pending'
        FAILED = 'failed'
        UPDATE_PENDING = 'update_pending'



class LoadBalancerListenerCollection:
    """
    LoadBalancerListenerCollection.

    :param List[LoadBalancerListener] listeners: The listeners for the load
          balancer.
    """

    def __init__(
        self,
        listeners: List['LoadBalancerListener'],
    ) -> None:
        """
        Initialize a LoadBalancerListenerCollection object.

        :param List[LoadBalancerListener] listeners: The listeners for the load
               balancer.
        """
        self.listeners = listeners

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerListenerCollection':
        """Initialize a LoadBalancerListenerCollection object from a json dictionary."""
        args = {}
        if (listeners := _dict.get('listeners')) is not None:
            args['listeners'] = [LoadBalancerListener.from_dict(v) for v in 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 LoadBalancerListenerDefaultPoolPatch:
    """
    The default pool for this listener. If `https_redirect` is set, the default pool will
    not be used. 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.

    """

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

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


class LoadBalancerListenerHTTPSRedirect:
    """
    LoadBalancerListenerHTTPSRedirect.

    :param int http_status_code: The HTTP status code for this redirect.
    :param LoadBalancerListenerReference listener:
    :param str uri: (optional) The redirect relative target URI.
    """

    def __init__(
        self,
        http_status_code: int,
        listener: 'LoadBalancerListenerReference',
        *,
        uri: Optional[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 := _dict.get('http_status_code')) is not None:
            args['http_status_code'] = http_status_code
        else:
            raise ValueError('Required property \'http_status_code\' not present in LoadBalancerListenerHTTPSRedirect JSON')
        if (listener := _dict.get('listener')) is not None:
            args['listener'] = LoadBalancerListenerReference.from_dict(listener)
        else:
            raise ValueError('Required property \'listener\' not present in LoadBalancerListenerHTTPSRedirect JSON')
        if (uri := _dict.get('uri')) is not None:
            args['uri'] = 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.

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

    def __init__(
        self,
        *,
        http_status_code: Optional[int] = None,
        listener: Optional['LoadBalancerListenerIdentity'] = None,
        uri: Optional[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 := _dict.get('http_status_code')) is not None:
            args['http_status_code'] = http_status_code
        if (listener := _dict.get('listener')) is not None:
            args['listener'] = listener
        if (uri := _dict.get('uri')) is not None:
            args['uri'] = 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.

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

    def __init__(
        self,
        http_status_code: int,
        listener: 'LoadBalancerListenerIdentity',
        *,
        uri: Optional[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 := _dict.get('http_status_code')) is not None:
            args['http_status_code'] = http_status_code
        else:
            raise ValueError('Required property \'http_status_code\' not present in LoadBalancerListenerHTTPSRedirectPrototype JSON')
        if (listener := _dict.get('listener')) is not None:
            args['listener'] = listener
        else:
            raise ValueError('Required property \'listener\' not present in LoadBalancerListenerHTTPSRedirectPrototype JSON')
        if (uri := _dict.get('uri')) is not None:
            args['uri'] = 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.

    :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 concurrent connection limit for the
          listener. If reached, incoming connections may be queued or rejected.
          Supported for load balancers in the `application` family.
    :param LoadBalancerListenerDefaultPoolPatch default_pool: (optional) The default
          pool for this listener. If `https_redirect` is set, the default pool will not
          be used. 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 if none of the listener's
          `policies` match.
          If specified, 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`.
          Only load balancers with route mode enabled, or network load balancers with
          `is_public` or `is_private_path` set to `true` 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`.
          Only load balancers with route mode enabled, or network load balancers with
          `is_public` or `is_private_path` set to `true` 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`.
    """

    def __init__(
        self,
        *,
        accept_proxy_protocol: Optional[bool] = None,
        certificate_instance: Optional['CertificateInstanceIdentity'] = None,
        connection_limit: Optional[int] = None,
        default_pool: Optional['LoadBalancerListenerDefaultPoolPatch'] = None,
        https_redirect: Optional['LoadBalancerListenerHTTPSRedirectPatch'] = None,
        idle_connection_timeout: Optional[int] = None,
        port: Optional[int] = None,
        port_max: Optional[int] = None,
        port_min: Optional[int] = None,
        protocol: Optional[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 concurrent connection limit for
               the listener. If reached, incoming connections may be queued or rejected.
               Supported for load balancers in the `application` family.
        :param LoadBalancerListenerDefaultPoolPatch default_pool: (optional) The
               default pool for this listener. If `https_redirect` is set, the default
               pool will not
               be used. 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 if none of the
               listener's
               `policies` match.
               If specified, 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`.
               Only load balancers with route mode enabled, or network load balancers with
               `is_public` or `is_private_path` set to `true` 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`.
               Only load balancers with route mode enabled, or network load balancers with
               `is_public` or `is_private_path` set to `true` 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 := _dict.get('accept_proxy_protocol')) is not None:
            args['accept_proxy_protocol'] = accept_proxy_protocol
        if (certificate_instance := _dict.get('certificate_instance')) is not None:
            args['certificate_instance'] = certificate_instance
        if (connection_limit := _dict.get('connection_limit')) is not None:
            args['connection_limit'] = connection_limit
        if (default_pool := _dict.get('default_pool')) is not None:
            args['default_pool'] = default_pool
        if (https_redirect := _dict.get('https_redirect')) is not None:
            args['https_redirect'] = LoadBalancerListenerHTTPSRedirectPatch.from_dict(https_redirect)
        if (idle_connection_timeout := _dict.get('idle_connection_timeout')) is not None:
            args['idle_connection_timeout'] = idle_connection_timeout
        if (port := _dict.get('port')) is not None:
            args['port'] = port
        if (port_max := _dict.get('port_max')) is not None:
            args['port_max'] = port_max
        if (port_min := _dict.get('port_min')) is not None:
            args['port_min'] = port_min
        if (protocol := _dict.get('protocol')) is not None:
            args['protocol'] = 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.

    :param str action: The policy action:
          - `forward`: Requests will be forwarded to the specified `target` pool
          - `https_redirect`: Requests will be redirected to the specified target
          listener. The
            listener must have a `protocol` of `http`, and the target listener must have a
            `protocol` of `https`
          - `redirect`: Requests will be redirected to the specified `target.url`
          - `reject`: Requests will be rejected with a `403` status code
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :param datetime created_at: The date and time that this policy was created.
    :param str href: The URL for this load balancer policy.
    :param str id: The unique identifier for this load balancer policy.
    :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. The priority is unique across all
          policies for this load balancer listener. Lower value indicates higher priority.
    :param str provisioning_status: The provisioning status of this policy
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :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 `https_redirect`, the response is a
          `LoadBalancerListenerPolicyHTTPSRedirect`
          - If `action` is `redirect`, the response is a
          `LoadBalancerListenerPolicyRedirectURL`.
    """

    def __init__(
        self,
        action: str,
        created_at: datetime,
        href: str,
        id: str,
        name: str,
        priority: int,
        provisioning_status: str,
        rules: List['LoadBalancerListenerPolicyRuleReference'],
        *,
        target: Optional['LoadBalancerListenerPolicyTarget'] = None,
    ) -> None:
        """
        Initialize a LoadBalancerListenerPolicy object.

        :param str action: The policy action:
               - `forward`: Requests will be forwarded to the specified `target` pool
               - `https_redirect`: Requests will be redirected to the specified target
               listener. The
                 listener must have a `protocol` of `http`, and the target listener must
               have a
                 `protocol` of `https`
               - `redirect`: Requests will be redirected to the specified `target.url`
               - `reject`: Requests will be rejected with a `403` status code
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :param datetime created_at: The date and time that this policy was created.
        :param str href: The URL for this load balancer policy.
        :param str id: The unique identifier for this load balancer policy.
        :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. The priority is unique across
               all policies for this load balancer listener. Lower value indicates higher
               priority.
        :param str provisioning_status: The provisioning status of this policy
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :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 `https_redirect`, the response is a
               `LoadBalancerListenerPolicyHTTPSRedirect`
               - If `action` is `redirect`, the response is a
               `LoadBalancerListenerPolicyRedirectURL`.
        """
        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 := _dict.get('action')) is not None:
            args['action'] = action
        else:
            raise ValueError('Required property \'action\' not present in LoadBalancerListenerPolicy JSON')
        if (created_at := _dict.get('created_at')) is not None:
            args['created_at'] = string_to_datetime(created_at)
        else:
            raise ValueError('Required property \'created_at\' not present in LoadBalancerListenerPolicy JSON')
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in LoadBalancerListenerPolicy JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in LoadBalancerListenerPolicy JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in LoadBalancerListenerPolicy JSON')
        if (priority := _dict.get('priority')) is not None:
            args['priority'] = priority
        else:
            raise ValueError('Required property \'priority\' not present in LoadBalancerListenerPolicy JSON')
        if (provisioning_status := _dict.get('provisioning_status')) is not None:
            args['provisioning_status'] = provisioning_status
        else:
            raise ValueError('Required property \'provisioning_status\' not present in LoadBalancerListenerPolicy JSON')
        if (rules := _dict.get('rules')) is not None:
            args['rules'] = [LoadBalancerListenerPolicyRuleReference.from_dict(v) for v in rules]
        else:
            raise ValueError('Required property \'rules\' not present in LoadBalancerListenerPolicy JSON')
        if (target := _dict.get('target')) is not None:
            args['target'] = 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:
        - `forward`: Requests will be forwarded to the specified `target` pool
        - `https_redirect`: Requests will be redirected to the specified target listener.
        The
          listener must have a `protocol` of `http`, and the target listener must have a
          `protocol` of `https`
        - `redirect`: Requests will be redirected to the specified `target.url`
        - `reject`: Requests will be rejected with a `403` status code
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        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 may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        ACTIVE = 'active'
        CREATE_PENDING = 'create_pending'
        DELETE_PENDING = 'delete_pending'
        FAILED = 'failed'
        UPDATE_PENDING = 'update_pending'



class LoadBalancerListenerPolicyCollection:
    """
    LoadBalancerListenerPolicyCollection.

    :param List[LoadBalancerListenerPolicy] policies: The policies for the load
          balancer listener.
    """

    def __init__(
        self,
        policies: List['LoadBalancerListenerPolicy'],
    ) -> None:
        """
        Initialize a LoadBalancerListenerPolicyCollection object.

        :param List[LoadBalancerListenerPolicy] policies: The policies for the load
               balancer listener.
        """
        self.policies = policies

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerListenerPolicyCollection':
        """Initialize a LoadBalancerListenerPolicyCollection object from a json dictionary."""
        args = {}
        if (policies := _dict.get('policies')) is not None:
            args['policies'] = [LoadBalancerListenerPolicy.from_dict(v) for v in 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.

    :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. The priority is unique
          across all policies for this load balancer listener. Lower value indicates
          higher priority.
    :param LoadBalancerListenerPolicyTargetPatch target: (optional) - If `action` is
          `forward`, specify a `LoadBalancerPoolIdentity`.
          - If `action` is `https_redirect`, specify a
          `LoadBalancerListenerPolicyHTTPSRedirectPatch`.
          - If `action` is `redirect`, specify a
          `LoadBalancerListenerPolicyRedirectURLPatch`.
    """

    def __init__(
        self,
        *,
        name: Optional[str] = None,
        priority: Optional[int] = None,
        target: Optional['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. The priority is
               unique across all policies for this load balancer listener. Lower value
               indicates higher priority.
        :param LoadBalancerListenerPolicyTargetPatch target: (optional) - If
               `action` is `forward`, specify a `LoadBalancerPoolIdentity`.
               - If `action` is `https_redirect`, specify a
               `LoadBalancerListenerPolicyHTTPSRedirectPatch`.
               - If `action` is `redirect`, specify a
               `LoadBalancerListenerPolicyRedirectURLPatch`.
        """
        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 := _dict.get('name')) is not None:
            args['name'] = name
        if (priority := _dict.get('priority')) is not None:
            args['priority'] = priority
        if (target := _dict.get('target')) is not None:
            args['target'] = 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.

    :param str action: The policy action:
          - `forward`: Requests will be forwarded to the specified `target` pool
          - `https_redirect`: Requests will be redirected to the specified
          `target.listener`.
             This listener must have a `protocol` of `http`, and the target listener must
             have a `protocol` of `https`.
          - `redirect`: Requests will be redirected to the specified `target.url`
          - `reject`: Requests will be rejected with a `403` status code.
    :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 int priority: Priority of the policy. The priority is unique across all
          policies for this load balancer listener. Lower value indicates higher priority.
    :param List[LoadBalancerListenerPolicyRulePrototype] rules: (optional) The rule
          prototype objects for this policy.
    :param LoadBalancerListenerPolicyTargetPrototype target: (optional) - If
          `action` is `forward`, use `LoadBalancerPoolIdentity` to specify a pool in this
            load balancer to forward to.
          - If `action` is `https_redirect`, use
            `LoadBalancerListenerPolicyHTTPSRedirectPrototype` to specify a listener on
          this
            load balancer to redirect to.
          - If `action` is `redirect`, use
          `LoadBalancerListenerPolicyRedirectURLPrototype`to
            specify a URL to redirect to.
    """

    def __init__(
        self,
        action: str,
        priority: int,
        *,
        name: Optional[str] = None,
        rules: Optional[List['LoadBalancerListenerPolicyRulePrototype']] = None,
        target: Optional['LoadBalancerListenerPolicyTargetPrototype'] = None,
    ) -> None:
        """
        Initialize a LoadBalancerListenerPolicyPrototype object.

        :param str action: The policy action:
               - `forward`: Requests will be forwarded to the specified `target` pool
               - `https_redirect`: Requests will be redirected to the specified
               `target.listener`.
                  This listener must have a `protocol` of `http`, and the target listener
               must
                  have a `protocol` of `https`.
               - `redirect`: Requests will be redirected to the specified `target.url`
               - `reject`: Requests will be rejected with a `403` status code.
        :param int priority: Priority of the policy. The priority is unique across
               all policies for this load balancer listener. 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`, use `LoadBalancerPoolIdentity` to specify a pool in
               this
                 load balancer to forward to.
               - If `action` is `https_redirect`, use
                 `LoadBalancerListenerPolicyHTTPSRedirectPrototype` to specify a listener
               on this
                 load balancer to redirect to.
               - If `action` is `redirect`, use
               `LoadBalancerListenerPolicyRedirectURLPrototype`to
                 specify a URL to redirect to.
        """
        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 := _dict.get('action')) is not None:
            args['action'] = action
        else:
            raise ValueError('Required property \'action\' not present in LoadBalancerListenerPolicyPrototype JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        if (priority := _dict.get('priority')) is not None:
            args['priority'] = priority
        else:
            raise ValueError('Required property \'priority\' not present in LoadBalancerListenerPolicyPrototype JSON')
        if (rules := _dict.get('rules')) is not None:
            args['rules'] = [LoadBalancerListenerPolicyRulePrototype.from_dict(v) for v in rules]
        if (target := _dict.get('target')) is not None:
            args['target'] = 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:
        - `forward`: Requests will be forwarded to the specified `target` pool
        - `https_redirect`: Requests will be redirected to the specified
        `target.listener`.
           This listener must have a `protocol` of `http`, and the target listener must
           have a `protocol` of `https`.
        - `redirect`: Requests will be redirected to the specified `target.url`
        - `reject`: Requests will be rejected with a `403` status code.
        """

        FORWARD = 'forward'
        HTTPS_REDIRECT = 'https_redirect'
        REDIRECT = 'redirect'
        REJECT = 'reject'



class LoadBalancerListenerPolicyReference:
    """
    LoadBalancerListenerPolicyReference.

    :param Deleted deleted: (optional) If present, this property indicates the
          referenced resource has been deleted, and provides
          some supplementary information.
    :param str href: The URL for this load balancer policy.
    :param str id: The unique identifier for this load balancer policy.
    :param str name: The name for this load balancer listener policy. The name is
          unique across all policies for the load balancer listener.
    """

    def __init__(
        self,
        href: str,
        id: str,
        name: str,
        *,
        deleted: Optional['Deleted'] = None,
    ) -> None:
        """
        Initialize a LoadBalancerListenerPolicyReference object.

        :param str href: The URL for this load balancer policy.
        :param str id: The unique identifier for this load balancer policy.
        :param str name: The name for this load balancer listener policy. The name
               is unique across all policies for the load balancer listener.
        :param Deleted 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 := _dict.get('deleted')) is not None:
            args['deleted'] = Deleted.from_dict(deleted)
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in LoadBalancerListenerPolicyReference JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in LoadBalancerListenerPolicyReference JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = 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 LoadBalancerListenerPolicyRule:
    """
    LoadBalancerListenerPolicyRule.

    :param str condition: The condition for the rule.
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :param datetime created_at: The date and time that this rule was created.
    :param str field: (optional) The field to match for this rule. If `condition` is
          not `matches_regex`, the value is percent-encoded.
    :param str href: The URL for this load balancer listener policy rule.
    :param str id: The unique identifier for this load balancer listener policy
          rule.
    :param str provisioning_status: The provisioning status of this rule
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :param str type: The type of the rule. Body rules are applied to form-encoded
          request bodies using the
          `UTF-8` character set.
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :param str value: The value to be matched for the 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: Optional[str] = None,
    ) -> None:
        """
        Initialize a LoadBalancerListenerPolicyRule object.

        :param str condition: The condition for the rule.
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :param datetime created_at: The date and time that this rule was created.
        :param str href: The URL for this load balancer listener policy rule.
        :param str id: The unique identifier for this load balancer listener policy
               rule.
        :param str provisioning_status: The provisioning status of this rule
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :param str type: The type of the rule. Body rules are applied to
               form-encoded request bodies using the
               `UTF-8` character set.
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :param str value: The value to be matched for the 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 to match for this rule. If
               `condition` is not `matches_regex`, the value is percent-encoded.
        """
        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 := _dict.get('condition')) is not None:
            args['condition'] = condition
        else:
            raise ValueError('Required property \'condition\' not present in LoadBalancerListenerPolicyRule JSON')
        if (created_at := _dict.get('created_at')) is not None:
            args['created_at'] = string_to_datetime(created_at)
        else:
            raise ValueError('Required property \'created_at\' not present in LoadBalancerListenerPolicyRule JSON')
        if (field := _dict.get('field')) is not None:
            args['field'] = field
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in LoadBalancerListenerPolicyRule JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in LoadBalancerListenerPolicyRule JSON')
        if (provisioning_status := _dict.get('provisioning_status')) is not None:
            args['provisioning_status'] = provisioning_status
        else:
            raise ValueError('Required property \'provisioning_status\' not present in LoadBalancerListenerPolicyRule JSON')
        if (type := _dict.get('type')) is not None:
            args['type'] = type
        else:
            raise ValueError('Required property \'type\' not present in LoadBalancerListenerPolicyRule JSON')
        if (value := _dict.get('value')) is not None:
            args['value'] = 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 for the rule.
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        CONTAINS = 'contains'
        EQUALS = 'equals'
        MATCHES_REGEX = 'matches_regex'


    class ProvisioningStatusEnum(str, Enum):
        """
        The provisioning status of this rule
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        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.
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        BODY = 'body'
        HEADER = 'header'
        HOSTNAME = 'hostname'
        PATH = 'path'
        QUERY = 'query'



class LoadBalancerListenerPolicyRuleCollection:
    """
    LoadBalancerListenerPolicyRuleCollection.

    :param List[LoadBalancerListenerPolicyRule] rules: The rules for the load
          balancer listener policy.
    """

    def __init__(
        self,
        rules: List['LoadBalancerListenerPolicyRule'],
    ) -> None:
        """
        Initialize a LoadBalancerListenerPolicyRuleCollection object.

        :param List[LoadBalancerListenerPolicyRule] rules: The rules for the load
               balancer listener policy.
        """
        self.rules = rules

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerListenerPolicyRuleCollection':
        """Initialize a LoadBalancerListenerPolicyRuleCollection object from a json dictionary."""
        args = {}
        if (rules := _dict.get('rules')) is not None:
            args['rules'] = [LoadBalancerListenerPolicyRule.from_dict(v) for v in 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.

    :param str condition: (optional) The condition for the rule.
    :param str field: (optional) The field to match for this rule. This property
          must be specified if the rule type is
          `header`, may be specified if the rule type is `body` or `query`, and must not
          be specified if the rule type is `hostname` or `path`.
          If the rule condition is not `matches_regex`, the value must be percent-encoded.
    :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) The value to be matched for the 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: Optional[str] = None,
        field: Optional[str] = None,
        type: Optional[str] = None,
        value: Optional[str] = None,
    ) -> None:
        """
        Initialize a LoadBalancerListenerPolicyRulePatch object.

        :param str condition: (optional) The condition for the rule.
        :param str field: (optional) The field to match for this rule. This
               property must be specified if the rule type is
               `header`, may be specified if the rule type is `body` or `query`, and must
               not be specified if the rule type is `hostname` or `path`.
               If the rule condition is not `matches_regex`, the value must be
               percent-encoded.
        :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) The value to be matched for the 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 := _dict.get('condition')) is not None:
            args['condition'] = condition
        if (field := _dict.get('field')) is not None:
            args['field'] = field
        if (type := _dict.get('type')) is not None:
            args['type'] = type
        if (value := _dict.get('value')) is not None:
            args['value'] = 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 for 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.

    :param str condition: The condition for the rule.
    :param str field: (optional) The field to match for this rule. This property
          must be specified if the rule type is
          `header`, may be specified if the rule type is `body` or `query`, and must not
          be specified if the rule type is `hostname` or `path`.
          If the rule condition is not `matches_regex`, the value must be percent-encoded.
    :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: The value to be matched for the 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: Optional[str] = None,
    ) -> None:
        """
        Initialize a LoadBalancerListenerPolicyRulePrototype object.

        :param str condition: The condition for 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: The value to be matched for the 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 to match for this rule. This
               property must be specified if the rule type is
               `header`, may be specified if the rule type is `body` or `query`, and must
               not be specified if the rule type is `hostname` or `path`.
               If 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) -> 'LoadBalancerListenerPolicyRulePrototype':
        """Initialize a LoadBalancerListenerPolicyRulePrototype object from a json dictionary."""
        args = {}
        if (condition := _dict.get('condition')) is not None:
            args['condition'] = condition
        else:
            raise ValueError('Required property \'condition\' not present in LoadBalancerListenerPolicyRulePrototype JSON')
        if (field := _dict.get('field')) is not None:
            args['field'] = field
        if (type := _dict.get('type')) is not None:
            args['type'] = type
        else:
            raise ValueError('Required property \'type\' not present in LoadBalancerListenerPolicyRulePrototype JSON')
        if (value := _dict.get('value')) is not None:
            args['value'] = 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 for 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.

    :param Deleted deleted: (optional) If present, this property indicates the
          referenced resource has been deleted, and provides
          some supplementary information.
    :param str href: The URL for this load balancer listener policy rule.
    :param str id: The unique identifier for this load balancer listener policy
          rule.
    """

    def __init__(
        self,
        href: str,
        id: str,
        *,
        deleted: Optional['Deleted'] = None,
    ) -> None:
        """
        Initialize a LoadBalancerListenerPolicyRuleReference object.

        :param str href: The URL for this load balancer listener policy rule.
        :param str id: The unique identifier for this load balancer listener policy
               rule.
        :param Deleted 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 := _dict.get('deleted')) is not None:
            args['deleted'] = Deleted.from_dict(deleted)
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in LoadBalancerListenerPolicyRuleReference JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = 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 LoadBalancerListenerPolicyTarget:
    """
    - If `action` is `forward`, the response is a `LoadBalancerPoolReference`
    - If `action` is `https_redirect`, the response is a
    `LoadBalancerListenerPolicyHTTPSRedirect`
    - If `action` is `redirect`, the response is a
    `LoadBalancerListenerPolicyRedirectURL`.

    """

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

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


class LoadBalancerListenerPolicyTargetPatch:
    """
    - If `action` is `forward`, specify a `LoadBalancerPoolIdentity`.
    - If `action` is `https_redirect`, specify a
    `LoadBalancerListenerPolicyHTTPSRedirectPatch`.
    - If `action` is `redirect`, specify a `LoadBalancerListenerPolicyRedirectURLPatch`.

    """

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

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


class LoadBalancerListenerPolicyTargetPrototype:
    """
    - If `action` is `forward`, use `LoadBalancerPoolIdentity` to specify a pool in this
      load balancer to forward to.
    - If `action` is `https_redirect`, use
      `LoadBalancerListenerPolicyHTTPSRedirectPrototype` to specify a listener on this
      load balancer to redirect to.
    - If `action` is `redirect`, use `LoadBalancerListenerPolicyRedirectURLPrototype`to
      specify a URL to redirect to.

    """

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

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


class LoadBalancerListenerPrototypeLoadBalancerContext:
    """
    LoadBalancerListenerPrototypeLoadBalancerContext.

    :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 concurrent connection limit for the
          listener. If reached, incoming connections may be queued or rejected.
          This property will be present for load balancers in the `application` family.
    :param LoadBalancerPoolIdentityByName default_pool: (optional) The default pool
          for this listener.  If `https_redirect` is specified,
          the default pool will not be used. 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 if none of the listener's
          `policies` match.
          If specified, 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`.
          Only load balancers with route mode enabled, or network load balancers with
          `is_public` or `is_private_path` set to `true` 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`.
          Only load balancers with route mode enabled, or network load balancers with
          `is_public` or `is_private_path` set to `true` 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: 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: Optional[bool] = None,
        certificate_instance: Optional['CertificateInstanceIdentity'] = None,
        connection_limit: Optional[int] = None,
        default_pool: Optional['LoadBalancerPoolIdentityByName'] = None,
        https_redirect: Optional['LoadBalancerListenerHTTPSRedirectPrototype'] = None,
        idle_connection_timeout: Optional[int] = None,
        port: Optional[int] = None,
        port_max: Optional[int] = None,
        port_min: Optional[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 concurrent connection limit for
               the listener. If reached, incoming connections may be queued or rejected.
               This property will be present for load balancers in the `application`
               family.
        :param LoadBalancerPoolIdentityByName default_pool: (optional) The default
               pool for this listener.  If `https_redirect` is specified,
               the default pool will not be used. 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 if none
               of the listener's
               `policies` match.
               If specified, 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`.
               Only load balancers with route mode enabled, or network load balancers with
               `is_public` or `is_private_path` set to `true` 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`.
               Only load balancers with route mode enabled, or network load balancers with
               `is_public` or `is_private_path` set to `true` 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 := _dict.get('accept_proxy_protocol')) is not None:
            args['accept_proxy_protocol'] = accept_proxy_protocol
        if (certificate_instance := _dict.get('certificate_instance')) is not None:
            args['certificate_instance'] = certificate_instance
        if (connection_limit := _dict.get('connection_limit')) is not None:
            args['connection_limit'] = connection_limit
        if (default_pool := _dict.get('default_pool')) is not None:
            args['default_pool'] = LoadBalancerPoolIdentityByName.from_dict(default_pool)
        if (https_redirect := _dict.get('https_redirect')) is not None:
            args['https_redirect'] = LoadBalancerListenerHTTPSRedirectPrototype.from_dict(https_redirect)
        if (idle_connection_timeout := _dict.get('idle_connection_timeout')) is not None:
            args['idle_connection_timeout'] = idle_connection_timeout
        if (port := _dict.get('port')) is not None:
            args['port'] = port
        if (port_max := _dict.get('port_max')) is not None:
            args['port_max'] = port_max
        if (port_min := _dict.get('port_min')) is not None:
            args['port_min'] = port_min
        if (protocol := _dict.get('protocol')) is not None:
            args['protocol'] = 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.

    :param Deleted deleted: (optional) If present, this property indicates the
          referenced resource has been deleted, and provides
          some supplementary information.
    :param str href: The URL for this load balancer listener.
    :param str id: The unique identifier for this load balancer listener.
    """

    def __init__(
        self,
        href: str,
        id: str,
        *,
        deleted: Optional['Deleted'] = None,
    ) -> None:
        """
        Initialize a LoadBalancerListenerReference object.

        :param str href: The URL for this load balancer listener.
        :param str id: The unique identifier for this load balancer listener.
        :param Deleted 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 := _dict.get('deleted')) is not None:
            args['deleted'] = Deleted.from_dict(deleted)
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in LoadBalancerListenerReference JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = 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 LoadBalancerLogging:
    """
    LoadBalancerLogging.

    :param 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 := _dict.get('datapath')) is not None:
            args['datapath'] = LoadBalancerLoggingDatapath.from_dict(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.

    :param 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 := _dict.get('active')) is not None:
            args['active'] = 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.

    :param bool active: (optional) Indicates whether datapath logging will be active
          for this load balancer.
    """

    def __init__(
        self,
        *,
        active: Optional[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 := _dict.get('active')) is not None:
            args['active'] = 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.

    :param bool active: (optional) Indicates whether datapath logging will be active
          for this load balancer.
    """

    def __init__(
        self,
        *,
        active: Optional[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 := _dict.get('active')) is not None:
            args['active'] = 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.

    :param LoadBalancerLoggingDatapathPatch datapath: (optional) The datapath
          logging configuration for this load balancer.
    """

    def __init__(
        self,
        *,
        datapath: Optional['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 := _dict.get('datapath')) is not None:
            args['datapath'] = LoadBalancerLoggingDatapathPatch.from_dict(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.

    :param LoadBalancerLoggingDatapathPrototype datapath: (optional) The datapath
          logging configuration for this load balancer.
    """

    def __init__(
        self,
        *,
        datapath: Optional['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 := _dict.get('datapath')) is not None:
            args['datapath'] = LoadBalancerLoggingDatapathPrototype.from_dict(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.

    :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`.
          Not supported by private path load balancers.
    :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.
    """

    def __init__(
        self,
        *,
        dns: Optional['LoadBalancerDNSPatch'] = None,
        logging: Optional['LoadBalancerLoggingPatch'] = None,
        name: Optional[str] = None,
        subnets: Optional[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`.
               Not supported by private path load balancers.
        :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 := _dict.get('dns')) is not None:
            args['dns'] = LoadBalancerDNSPatch.from_dict(dns)
        if (logging := _dict.get('logging')) is not None:
            args['logging'] = LoadBalancerLoggingPatch.from_dict(logging)
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        if (subnets := _dict.get('subnets')) is not None:
            args['subnets'] = 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.

    :param str algorithm: The load balancing algorithm.
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :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 URL for this load balancer pool.
    :param str id: The unique identifier for this load balancer pool.
    :param InstanceGroupReference instance_group: (optional) The instance group that
          is managing this pool.
    :param List[LoadBalancerPoolMemberReference] members: (optional) The backend
          server members of the pool.
    :param 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 may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :param str provisioning_status: The provisioning status of this pool
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :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
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :param LoadBalancerPoolSessionPersistence session_persistence: (optional) The
          session persistence of this pool.
          If absent, session persistence will be disabled, and traffic will be distributed
          across backend server members of the pool.
    """

    def __init__(
        self,
        algorithm: str,
        created_at: datetime,
        health_monitor: 'LoadBalancerPoolHealthMonitor',
        href: str,
        id: str,
        name: str,
        protocol: str,
        provisioning_status: str,
        proxy_protocol: str,
        *,
        instance_group: Optional['InstanceGroupReference'] = None,
        members: Optional[List['LoadBalancerPoolMemberReference']] = None,
        session_persistence: Optional['LoadBalancerPoolSessionPersistence'] = None,
    ) -> None:
        """
        Initialize a LoadBalancerPool object.

        :param str algorithm: The load balancing algorithm.
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :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 URL for this load balancer pool.
        :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 may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :param str provisioning_status: The provisioning status of this pool
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :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
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :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.
               If absent, session persistence will be disabled, and traffic will be
               distributed
               across backend server members of the pool.
        """
        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 := _dict.get('algorithm')) is not None:
            args['algorithm'] = algorithm
        else:
            raise ValueError('Required property \'algorithm\' not present in LoadBalancerPool JSON')
        if (created_at := _dict.get('created_at')) is not None:
            args['created_at'] = string_to_datetime(created_at)
        else:
            raise ValueError('Required property \'created_at\' not present in LoadBalancerPool JSON')
        if (health_monitor := _dict.get('health_monitor')) is not None:
            args['health_monitor'] = LoadBalancerPoolHealthMonitor.from_dict(health_monitor)
        else:
            raise ValueError('Required property \'health_monitor\' not present in LoadBalancerPool JSON')
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in LoadBalancerPool JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in LoadBalancerPool JSON')
        if (instance_group := _dict.get('instance_group')) is not None:
            args['instance_group'] = InstanceGroupReference.from_dict(instance_group)
        if (members := _dict.get('members')) is not None:
            args['members'] = [LoadBalancerPoolMemberReference.from_dict(v) for v in members]
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in LoadBalancerPool JSON')
        if (protocol := _dict.get('protocol')) is not None:
            args['protocol'] = protocol
        else:
            raise ValueError('Required property \'protocol\' not present in LoadBalancerPool JSON')
        if (provisioning_status := _dict.get('provisioning_status')) is not None:
            args['provisioning_status'] = provisioning_status
        else:
            raise ValueError('Required property \'provisioning_status\' not present in LoadBalancerPool JSON')
        if (proxy_protocol := _dict.get('proxy_protocol')) is not None:
            args['proxy_protocol'] = proxy_protocol
        else:
            raise ValueError('Required property \'proxy_protocol\' not present in LoadBalancerPool JSON')
        if (session_persistence := _dict.get('session_persistence')) is not None:
            args['session_persistence'] = LoadBalancerPoolSessionPersistence.from_dict(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.
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        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 may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        HTTP = 'http'
        HTTPS = 'https'
        TCP = 'tcp'
        UDP = 'udp'


    class ProvisioningStatusEnum(str, Enum):
        """
        The provisioning status of this pool
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        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
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        DISABLED = 'disabled'
        V1 = 'v1'
        V2 = 'v2'



class LoadBalancerPoolCollection:
    """
    LoadBalancerPoolCollection.

    :param List[LoadBalancerPool] pools: The pools for the load balancer.
    """

    def __init__(
        self,
        pools: List['LoadBalancerPool'],
    ) -> None:
        """
        Initialize a LoadBalancerPoolCollection object.

        :param List[LoadBalancerPool] pools: The pools for the load balancer.
        """
        self.pools = pools

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerPoolCollection':
        """Initialize a LoadBalancerPoolCollection object from a json dictionary."""
        args = {}
        if (pools := _dict.get('pools')) is not None:
            args['pools'] = [LoadBalancerPool.from_dict(v) for v in 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.

    :param int delay: The seconds to wait between health checks.
    :param int max_retries: The health check max retries.
    :param int port: (optional) The health check port.
          If present, this overrides the pool member port values.
    :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 may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :param str url_path: (optional) The health check URL path, in the format of an
          [origin-form request target](https://tools.ietf.org/html/rfc7230#section-5.3.1).
          If `type` is `tcp`, this property will be absent.
    """

    def __init__(
        self,
        delay: int,
        max_retries: int,
        timeout: int,
        type: str,
        *,
        port: Optional[int] = None,
        url_path: Optional[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 may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :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, in the format of
               an [origin-form request
               target](https://tools.ietf.org/html/rfc7230#section-5.3.1).
               If `type` is `tcp`, this property will be absent.
        """
        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 := _dict.get('delay')) is not None:
            args['delay'] = delay
        else:
            raise ValueError('Required property \'delay\' not present in LoadBalancerPoolHealthMonitor JSON')
        if (max_retries := _dict.get('max_retries')) is not None:
            args['max_retries'] = max_retries
        else:
            raise ValueError('Required property \'max_retries\' not present in LoadBalancerPoolHealthMonitor JSON')
        if (port := _dict.get('port')) is not None:
            args['port'] = port
        if (timeout := _dict.get('timeout')) is not None:
            args['timeout'] = timeout
        else:
            raise ValueError('Required property \'timeout\' not present in LoadBalancerPoolHealthMonitor JSON')
        if (type := _dict.get('type')) is not None:
            args['type'] = type
        else:
            raise ValueError('Required property \'type\' not present in LoadBalancerPoolHealthMonitor JSON')
        if (url_path := _dict.get('url_path')) is not None:
            args['url_path'] = 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 may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        HTTP = 'http'
        HTTPS = 'https'
        TCP = 'tcp'



class LoadBalancerPoolHealthMonitorPatch:
    """
    LoadBalancerPoolHealthMonitorPatch.

    :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 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 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 str url_path: (optional) The health check URL path.  If specified, `type`
          must be `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: Optional[int] = None,
        url_path: Optional[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.  If specified,
               `type` must be `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 := _dict.get('delay')) is not None:
            args['delay'] = delay
        else:
            raise ValueError('Required property \'delay\' not present in LoadBalancerPoolHealthMonitorPatch JSON')
        if (max_retries := _dict.get('max_retries')) is not None:
            args['max_retries'] = max_retries
        else:
            raise ValueError('Required property \'max_retries\' not present in LoadBalancerPoolHealthMonitorPatch JSON')
        if (port := _dict.get('port')) is not None:
            args['port'] = port
        if (timeout := _dict.get('timeout')) is not None:
            args['timeout'] = timeout
        else:
            raise ValueError('Required property \'timeout\' not present in LoadBalancerPoolHealthMonitorPatch JSON')
        if (type := _dict.get('type')) is not None:
            args['type'] = type
        else:
            raise ValueError('Required property \'type\' not present in LoadBalancerPoolHealthMonitorPatch JSON')
        if (url_path := _dict.get('url_path')) is not None:
            args['url_path'] = 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.

    :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 port: (optional) The health check port.
          If specified, this overrides the pool member port values.
    :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 str url_path: (optional) The health check URL path.  If specified, `type`
          must be `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: Optional[int] = None,
        url_path: Optional[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.  If specified,
               `type` must be `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 := _dict.get('delay')) is not None:
            args['delay'] = delay
        else:
            raise ValueError('Required property \'delay\' not present in LoadBalancerPoolHealthMonitorPrototype JSON')
        if (max_retries := _dict.get('max_retries')) is not None:
            args['max_retries'] = max_retries
        else:
            raise ValueError('Required property \'max_retries\' not present in LoadBalancerPoolHealthMonitorPrototype JSON')
        if (port := _dict.get('port')) is not None:
            args['port'] = port
        if (timeout := _dict.get('timeout')) is not None:
            args['timeout'] = timeout
        else:
            raise ValueError('Required property \'timeout\' not present in LoadBalancerPoolHealthMonitorPrototype JSON')
        if (type := _dict.get('type')) is not None:
            args['type'] = type
        else:
            raise ValueError('Required property \'type\' not present in LoadBalancerPoolHealthMonitorPrototype JSON')
        if (url_path := _dict.get('url_path')) is not None:
            args['url_path'] = 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(['LoadBalancerPoolIdentityLoadBalancerPoolIdentityById', 'LoadBalancerPoolIdentityLoadBalancerPoolIdentityByHref'])
        )
        raise Exception(msg)


class LoadBalancerPoolIdentityByName:
    """
    LoadBalancerPoolIdentityByName.

    :param 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 := _dict.get('name')) is not None:
            args['name'] = 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.

    :param datetime created_at: The date and time that this member was created.
    :param str health: Health of the server member in the pool.
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :param str href: The URL for this load balancer pool member.
    :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 may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :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) The weight of the server member.
          This property will be present 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: Optional[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.
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :param str href: The URL for this load balancer pool member.
        :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 may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :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) The weight of the server member.
               This property will be present 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 := _dict.get('created_at')) is not None:
            args['created_at'] = string_to_datetime(created_at)
        else:
            raise ValueError('Required property \'created_at\' not present in LoadBalancerPoolMember JSON')
        if (health := _dict.get('health')) is not None:
            args['health'] = health
        else:
            raise ValueError('Required property \'health\' not present in LoadBalancerPoolMember JSON')
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in LoadBalancerPoolMember JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in LoadBalancerPoolMember JSON')
        if (port := _dict.get('port')) is not None:
            args['port'] = port
        else:
            raise ValueError('Required property \'port\' not present in LoadBalancerPoolMember JSON')
        if (provisioning_status := _dict.get('provisioning_status')) is not None:
            args['provisioning_status'] = provisioning_status
        else:
            raise ValueError('Required property \'provisioning_status\' not present in LoadBalancerPoolMember JSON')
        if (target := _dict.get('target')) is not None:
            args['target'] = target
        else:
            raise ValueError('Required property \'target\' not present in LoadBalancerPoolMember JSON')
        if (weight := _dict.get('weight')) is not None:
            args['weight'] = 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.
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        FAULTED = 'faulted'
        OK = 'ok'
        UNKNOWN = 'unknown'


    class ProvisioningStatusEnum(str, Enum):
        """
        The provisioning status of this member
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        ACTIVE = 'active'
        CREATE_PENDING = 'create_pending'
        DELETE_PENDING = 'delete_pending'
        FAILED = 'failed'
        UPDATE_PENDING = 'update_pending'



class LoadBalancerPoolMemberCollection:
    """
    LoadBalancerPoolMemberCollection.

    :param List[LoadBalancerPoolMember] members: The members for the load balancer
          pool.
    """

    def __init__(
        self,
        members: List['LoadBalancerPoolMember'],
    ) -> None:
        """
        Initialize a LoadBalancerPoolMemberCollection object.

        :param List[LoadBalancerPoolMember] members: The members for the load
               balancer pool.
        """
        self.members = members

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerPoolMemberCollection':
        """Initialize a LoadBalancerPoolMemberCollection object from a json dictionary."""
        args = {}
        if (members := _dict.get('members')) is not None:
            args['members'] = [LoadBalancerPoolMember.from_dict(v) for v in 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.

    :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) The weight of the server member.
          If specified, the pool algorithm must be `weighted_round_robin`.
    """

    def __init__(
        self,
        *,
        port: Optional[int] = None,
        target: Optional['LoadBalancerPoolMemberTargetPrototype'] = None,
        weight: Optional[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) The weight of the server member.
               If specified, the pool algorithm must be `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 := _dict.get('port')) is not None:
            args['port'] = port
        if (target := _dict.get('target')) is not None:
            args['target'] = target
        if (weight := _dict.get('weight')) is not None:
            args['weight'] = 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.

    :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) The weight of the server member.
          If specified, the pool algorithm must be `weighted_round_robin`.
    """

    def __init__(
        self,
        port: int,
        target: 'LoadBalancerPoolMemberTargetPrototype',
        *,
        weight: Optional[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) The weight of the server member.
               If specified, the pool algorithm must be `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 := _dict.get('port')) is not None:
            args['port'] = port
        else:
            raise ValueError('Required property \'port\' not present in LoadBalancerPoolMemberPrototype JSON')
        if (target := _dict.get('target')) is not None:
            args['target'] = target
        else:
            raise ValueError('Required property \'target\' not present in LoadBalancerPoolMemberPrototype JSON')
        if (weight := _dict.get('weight')) is not None:
            args['weight'] = 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.

    :param Deleted deleted: (optional) If present, this property indicates the
          referenced resource has been deleted, and provides
          some supplementary information.
    :param str href: The URL for this load balancer pool member.
    :param str id: The unique identifier for this load balancer pool member.
    """

    def __init__(
        self,
        href: str,
        id: str,
        *,
        deleted: Optional['Deleted'] = None,
    ) -> None:
        """
        Initialize a LoadBalancerPoolMemberReference object.

        :param str href: The URL for this load balancer pool member.
        :param str id: The unique identifier for this load balancer pool member.
        :param Deleted 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 := _dict.get('deleted')) is not None:
            args['deleted'] = Deleted.from_dict(deleted)
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in LoadBalancerPoolMemberReference JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = 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 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.

    :param str algorithm: (optional) The load balancing algorithm. The
          `least_connections` algorithm is only supported for load balancers that have
          `availability` with value `subnet` in the profile.
    :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
          For load balancers in the `network` family, this property must be `disabled`.
    :param LoadBalancerPoolSessionPersistencePatch session_persistence: (optional)
          The session persistence of this pool.
    """

    def __init__(
        self,
        *,
        algorithm: Optional[str] = None,
        health_monitor: Optional['LoadBalancerPoolHealthMonitorPatch'] = None,
        name: Optional[str] = None,
        protocol: Optional[str] = None,
        proxy_protocol: Optional[str] = None,
        session_persistence: Optional['LoadBalancerPoolSessionPersistencePatch'] = None,
    ) -> None:
        """
        Initialize a LoadBalancerPoolPatch object.

        :param str algorithm: (optional) The load balancing algorithm. The
               `least_connections` algorithm is only supported for load balancers that
               have `availability` with value `subnet` in the profile.
        :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
               For load balancers in the `network` family, this property must be
               `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 := _dict.get('algorithm')) is not None:
            args['algorithm'] = algorithm
        if (health_monitor := _dict.get('health_monitor')) is not None:
            args['health_monitor'] = LoadBalancerPoolHealthMonitorPatch.from_dict(health_monitor)
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        if (protocol := _dict.get('protocol')) is not None:
            args['protocol'] = protocol
        if (proxy_protocol := _dict.get('proxy_protocol')) is not None:
            args['proxy_protocol'] = proxy_protocol
        if (session_persistence := _dict.get('session_persistence')) is not None:
            args['session_persistence'] = LoadBalancerPoolSessionPersistencePatch.from_dict(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. The `least_connections` algorithm is only supported
        for load balancers that have `availability` with value `subnet` in the profile.
        """

        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
        For load balancers in the `network` family, this property must be `disabled`.
        """

        DISABLED = 'disabled'
        V1 = 'v1'
        V2 = 'v2'



class LoadBalancerPoolPrototype:
    """
    LoadBalancerPoolPrototype.

    :param str algorithm: The load balancing algorithm. The `least_connections`
          algorithm is only supported for load balancers that have `availability` with
          value `subnet` in the profile.
    :param LoadBalancerPoolHealthMonitorPrototype health_monitor: The health monitor
          of this pool.
    :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 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 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
          For load balancers in the `network` family, this property must be `disabled`.
    :param LoadBalancerPoolSessionPersistencePrototype session_persistence:
          (optional) The session persistence of this pool. If specified, the load balancer
          must have
          `source_ip_session_persistence_supported` set to `true` in its profile. If
          unspecified, session persistence will be disabled, and traffic will be
          distributed
          across backend server members of the pool.
    """

    def __init__(
        self,
        algorithm: str,
        health_monitor: 'LoadBalancerPoolHealthMonitorPrototype',
        protocol: str,
        *,
        members: Optional[List['LoadBalancerPoolMemberPrototype']] = None,
        name: Optional[str] = None,
        proxy_protocol: Optional[str] = None,
        session_persistence: Optional['LoadBalancerPoolSessionPersistencePrototype'] = None,
    ) -> None:
        """
        Initialize a LoadBalancerPoolPrototype object.

        :param str algorithm: The load balancing algorithm. The `least_connections`
               algorithm is only supported for load balancers that have `availability`
               with value `subnet` in the profile.
        :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
               For load balancers in the `network` family, this property must be
               `disabled`.
        :param LoadBalancerPoolSessionPersistencePrototype session_persistence:
               (optional) The session persistence of this pool. If specified, the load
               balancer must have
               `source_ip_session_persistence_supported` set to `true` in its profile. If
               unspecified, session persistence will be disabled, and traffic will be
               distributed
               across backend server members of the 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 := _dict.get('algorithm')) is not None:
            args['algorithm'] = algorithm
        else:
            raise ValueError('Required property \'algorithm\' not present in LoadBalancerPoolPrototype JSON')
        if (health_monitor := _dict.get('health_monitor')) is not None:
            args['health_monitor'] = LoadBalancerPoolHealthMonitorPrototype.from_dict(health_monitor)
        else:
            raise ValueError('Required property \'health_monitor\' not present in LoadBalancerPoolPrototype JSON')
        if (members := _dict.get('members')) is not None:
            args['members'] = [LoadBalancerPoolMemberPrototype.from_dict(v) for v in members]
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        if (protocol := _dict.get('protocol')) is not None:
            args['protocol'] = protocol
        else:
            raise ValueError('Required property \'protocol\' not present in LoadBalancerPoolPrototype JSON')
        if (proxy_protocol := _dict.get('proxy_protocol')) is not None:
            args['proxy_protocol'] = proxy_protocol
        if (session_persistence := _dict.get('session_persistence')) is not None:
            args['session_persistence'] = LoadBalancerPoolSessionPersistencePrototype.from_dict(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. The `least_connections` algorithm is only supported
        for load balancers that have `availability` with value `subnet` in the profile.
        """

        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
        For load balancers in the `network` family, this property must be `disabled`.
        """

        DISABLED = 'disabled'
        V1 = 'v1'
        V2 = 'v2'



class LoadBalancerPoolReference:
    """
    LoadBalancerPoolReference.

    :param Deleted deleted: (optional) If present, this property indicates the
          referenced resource has been deleted, and provides
          some supplementary information.
    :param str href: The URL for this load balancer pool.
    :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.
    """

    def __init__(
        self,
        href: str,
        id: str,
        name: str,
        *,
        deleted: Optional['Deleted'] = None,
    ) -> None:
        """
        Initialize a LoadBalancerPoolReference object.

        :param str href: The URL for this load balancer pool.
        :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 Deleted 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 := _dict.get('deleted')) is not None:
            args['deleted'] = Deleted.from_dict(deleted)
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in LoadBalancerPoolReference JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in LoadBalancerPoolReference JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = 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 LoadBalancerPoolSessionPersistence:
    """
    LoadBalancerPoolSessionPersistence.

    :param str cookie_name: (optional) The session persistence cookie name.
    :param str type: The session persistence type.
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    """

    def __init__(
        self,
        type: str,
        *,
        cookie_name: Optional[str] = None,
    ) -> None:
        """
        Initialize a LoadBalancerPoolSessionPersistence object.

        :param str type: The session persistence type.
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :param str cookie_name: (optional) The session persistence cookie name.
        """
        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 := _dict.get('cookie_name')) is not None:
            args['cookie_name'] = cookie_name
        if (type := _dict.get('type')) is not None:
            args['type'] = 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 enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        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.

    :param str cookie_name: (optional) The session persistence cookie name. Names
          starting with `IBM` are not allowed.
          If specified, the session persistence type must be `app_cookie`.
    :param str type: (optional) The session persistence type.
          If `http_cookie` or `app_cookie` is specified, the pool protocol must be `http`
          or
          `https`.
    """

    def __init__(
        self,
        *,
        cookie_name: Optional[str] = None,
        type: Optional[str] = None,
    ) -> None:
        """
        Initialize a LoadBalancerPoolSessionPersistencePatch object.

        :param str cookie_name: (optional) The session persistence cookie name.
               Names starting with `IBM` are not allowed.
               If specified, the session persistence type must be `app_cookie`.
        :param str type: (optional) The session persistence type.
               If `http_cookie` or `app_cookie` is specified, the pool protocol must be
               `http` or
               `https`.
        """
        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 := _dict.get('cookie_name')) is not None:
            args['cookie_name'] = cookie_name
        if (type := _dict.get('type')) is not None:
            args['type'] = 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.
        If `http_cookie` or `app_cookie` is specified, the pool protocol must be `http` or
        `https`.
        """

        APP_COOKIE = 'app_cookie'
        HTTP_COOKIE = 'http_cookie'
        SOURCE_IP = 'source_ip'



class LoadBalancerPoolSessionPersistencePrototype:
    """
    LoadBalancerPoolSessionPersistencePrototype.

    :param str cookie_name: (optional) The session persistence cookie name. Names
          starting with `IBM` are not allowed.
          If specified, the session persistence type must be `app_cookie`.
    :param str type: The session persistence type.
          If `http_cookie` or `app_cookie` is specified, the pool protocol must be `http`
          or
          `https`.
    """

    def __init__(
        self,
        type: str,
        *,
        cookie_name: Optional[str] = None,
    ) -> None:
        """
        Initialize a LoadBalancerPoolSessionPersistencePrototype object.

        :param str type: The session persistence type.
               If `http_cookie` or `app_cookie` is specified, the pool protocol must be
               `http` or
               `https`.
        :param str cookie_name: (optional) The session persistence cookie name.
               Names starting with `IBM` are not allowed.
               If specified, the session persistence type must be `app_cookie`.
        """
        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 := _dict.get('cookie_name')) is not None:
            args['cookie_name'] = cookie_name
        if (type := _dict.get('type')) is not None:
            args['type'] = 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.
        If `http_cookie` or `app_cookie` is specified, the pool protocol must be `http` or
        `https`.
        """

        APP_COOKIE = 'app_cookie'
        HTTP_COOKIE = 'http_cookie'
        SOURCE_IP = 'source_ip'



class LoadBalancerProfile:
    """
    LoadBalancerProfile.

    :param LoadBalancerProfileAccessModes access_modes:
    :param LoadBalancerProfileAvailability availability:
    :param str family: The product family this load balancer profile belongs to.
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :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 LoadBalancerProfileSourceIPSessionPersistenceSupported
          source_ip_session_persistence_supported:
    :param LoadBalancerProfileUDPSupported udp_supported:
    """

    def __init__(
        self,
        access_modes: 'LoadBalancerProfileAccessModes',
        availability: 'LoadBalancerProfileAvailability',
        family: str,
        href: str,
        instance_groups_supported: 'LoadBalancerProfileInstanceGroupsSupported',
        logging_supported: 'LoadBalancerProfileLoggingSupported',
        name: str,
        route_mode_supported: 'LoadBalancerProfileRouteModeSupported',
        security_groups_supported: 'LoadBalancerProfileSecurityGroupsSupported',
        source_ip_session_persistence_supported: 'LoadBalancerProfileSourceIPSessionPersistenceSupported',
        udp_supported: 'LoadBalancerProfileUDPSupported',
    ) -> None:
        """
        Initialize a LoadBalancerProfile object.

        :param LoadBalancerProfileAccessModes access_modes:
        :param LoadBalancerProfileAvailability availability:
        :param str family: The product family this load balancer profile belongs
               to.
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :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 LoadBalancerProfileSourceIPSessionPersistenceSupported
               source_ip_session_persistence_supported:
        :param LoadBalancerProfileUDPSupported udp_supported:
        """
        self.access_modes = access_modes
        self.availability = availability
        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.source_ip_session_persistence_supported = source_ip_session_persistence_supported
        self.udp_supported = udp_supported

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerProfile':
        """Initialize a LoadBalancerProfile object from a json dictionary."""
        args = {}
        if (access_modes := _dict.get('access_modes')) is not None:
            args['access_modes'] = LoadBalancerProfileAccessModes.from_dict(access_modes)
        else:
            raise ValueError('Required property \'access_modes\' not present in LoadBalancerProfile JSON')
        if (availability := _dict.get('availability')) is not None:
            args['availability'] = availability
        else:
            raise ValueError('Required property \'availability\' not present in LoadBalancerProfile JSON')
        if (family := _dict.get('family')) is not None:
            args['family'] = family
        else:
            raise ValueError('Required property \'family\' not present in LoadBalancerProfile JSON')
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in LoadBalancerProfile JSON')
        if (instance_groups_supported := _dict.get('instance_groups_supported')) is not None:
            args['instance_groups_supported'] = instance_groups_supported
        else:
            raise ValueError('Required property \'instance_groups_supported\' not present in LoadBalancerProfile JSON')
        if (logging_supported := _dict.get('logging_supported')) is not None:
            args['logging_supported'] = LoadBalancerProfileLoggingSupported.from_dict(logging_supported)
        else:
            raise ValueError('Required property \'logging_supported\' not present in LoadBalancerProfile JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in LoadBalancerProfile JSON')
        if (route_mode_supported := _dict.get('route_mode_supported')) is not None:
            args['route_mode_supported'] = route_mode_supported
        else:
            raise ValueError('Required property \'route_mode_supported\' not present in LoadBalancerProfile JSON')
        if (security_groups_supported := _dict.get('security_groups_supported')) is not None:
            args['security_groups_supported'] = security_groups_supported
        else:
            raise ValueError('Required property \'security_groups_supported\' not present in LoadBalancerProfile JSON')
        if (source_ip_session_persistence_supported := _dict.get('source_ip_session_persistence_supported')) is not None:
            args['source_ip_session_persistence_supported'] = source_ip_session_persistence_supported
        else:
            raise ValueError('Required property \'source_ip_session_persistence_supported\' not present in LoadBalancerProfile JSON')
        if (udp_supported := _dict.get('udp_supported')) is not None:
            args['udp_supported'] = 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, 'access_modes') and self.access_modes is not None:
            if isinstance(self.access_modes, dict):
                _dict['access_modes'] = self.access_modes
            else:
                _dict['access_modes'] = self.access_modes.to_dict()
        if hasattr(self, 'availability') and self.availability is not None:
            if isinstance(self.availability, dict):
                _dict['availability'] = self.availability
            else:
                _dict['availability'] = self.availability.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, '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, 'source_ip_session_persistence_supported') and self.source_ip_session_persistence_supported is not None:
            if isinstance(self.source_ip_session_persistence_supported, dict):
                _dict['source_ip_session_persistence_supported'] = self.source_ip_session_persistence_supported
            else:
                _dict['source_ip_session_persistence_supported'] = self.source_ip_session_persistence_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 FamilyEnum(str, Enum):
        """
        The product family this load balancer profile belongs to.
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        APPLICATION = 'application'
        NETWORK = 'network'



class LoadBalancerProfileAccessModes:
    """
    LoadBalancerProfileAccessModes.

    :param str type: The type for this profile field.
    :param List[str] values: The access modes supported by load balancers with this
          profile.
    """

    def __init__(
        self,
        type: str,
        values: List[str],
    ) -> None:
        """
        Initialize a LoadBalancerProfileAccessModes object.

        :param str type: The type for this profile field.
        :param List[str] values: The access modes supported by load balancers with
               this profile.
        """
        self.type = type
        self.values = values

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

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

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

    def __ne__(self, other: 'LoadBalancerProfileAccessModes') -> 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 access mode for this load balancer:
        - `private`: reachable from within its VPC, at IP addresses in `private_ips`
        - `private_path`: reachable through an endpoint gateway
        - `public`: reachable from the internet at the IP addresses in `public_ips`.
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        PRIVATE = 'private'
        PRIVATE_PATH = 'private_path'
        PUBLIC = 'public'



class LoadBalancerProfileAvailability:
    """
    LoadBalancerProfileAvailability.

    """

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

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


class LoadBalancerProfileCollection:
    """
    LoadBalancerProfileCollection.

    :param PageLink 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 PageLink next: (optional) A link to the next page of resources. This
          property is present for all pages
          except the last page.
    :param List[LoadBalancerProfile] profiles: A page of load balancer profiles.
    :param int total_count: The total number of resources across all pages.
    """

    def __init__(
        self,
        first: 'PageLink',
        limit: int,
        profiles: List['LoadBalancerProfile'],
        total_count: int,
        *,
        next: Optional['PageLink'] = None,
    ) -> None:
        """
        Initialize a LoadBalancerProfileCollection object.

        :param PageLink 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: A page of load balancer
               profiles.
        :param int total_count: The total number of resources across all pages.
        :param PageLink 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 := _dict.get('first')) is not None:
            args['first'] = PageLink.from_dict(first)
        else:
            raise ValueError('Required property \'first\' not present in LoadBalancerProfileCollection JSON')
        if (limit := _dict.get('limit')) is not None:
            args['limit'] = limit
        else:
            raise ValueError('Required property \'limit\' not present in LoadBalancerProfileCollection JSON')
        if (next := _dict.get('next')) is not None:
            args['next'] = PageLink.from_dict(next)
        if (profiles := _dict.get('profiles')) is not None:
            args['profiles'] = [LoadBalancerProfile.from_dict(v) for v in profiles]
        else:
            raise ValueError('Required property \'profiles\' not present in LoadBalancerProfileCollection JSON')
        if (total_count := _dict.get('total_count')) is not None:
            args['total_count'] = 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 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.

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

    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 := _dict.get('type')) is not None:
            args['type'] = type
        else:
            raise ValueError('Required property \'type\' not present in LoadBalancerProfileLoggingSupported JSON')
        if (value := _dict.get('value')) is not None:
            args['value'] = 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.

    :param str family: The product family this load balancer profile belongs to.
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :param str href: The URL for this load balancer profile.
    :param 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.
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :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 := _dict.get('family')) is not None:
            args['family'] = family
        else:
            raise ValueError('Required property \'family\' not present in LoadBalancerProfileReference JSON')
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in LoadBalancerProfileReference JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = 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 FamilyEnum(str, Enum):
        """
        The product family this load balancer profile belongs to.
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        APPLICATION = 'application'
        NETWORK = 'network'



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 LoadBalancerProfileSourceIPSessionPersistenceSupported:
    """
    LoadBalancerProfileSourceIPSessionPersistenceSupported.

    """

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

        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['LoadBalancerProfileSourceIPSessionPersistenceSupportedFixed', 'LoadBalancerProfileSourceIPSessionPersistenceSupportedDependent'])
        )
        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 LoadBalancerReference:
    """
    LoadBalancerReference.

    :param str crn: The CRN for this load balancer.
    :param Deleted deleted: (optional) If present, this property indicates the
          referenced resource has been deleted, and provides
          some supplementary information.
    :param str href: The URL for this load balancer.
    :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.
    """

    def __init__(
        self,
        crn: str,
        href: str,
        id: str,
        name: str,
        resource_type: str,
        *,
        deleted: Optional['Deleted'] = None,
    ) -> None:
        """
        Initialize a LoadBalancerReference object.

        :param str crn: The CRN for this load balancer.
        :param str href: The URL for this load balancer.
        :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 Deleted 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) -> 'LoadBalancerReference':
        """Initialize a LoadBalancerReference object from a json dictionary."""
        args = {}
        if (crn := _dict.get('crn')) is not None:
            args['crn'] = crn
        else:
            raise ValueError('Required property \'crn\' not present in LoadBalancerReference JSON')
        if (deleted := _dict.get('deleted')) is not None:
            args['deleted'] = Deleted.from_dict(deleted)
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in LoadBalancerReference JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in LoadBalancerReference JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in LoadBalancerReference JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = resource_type
        else:
            raise ValueError('Required property \'resource_type\' not present in LoadBalancerReference JSON')
        return cls(**args)

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

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

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

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

    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 := _dict.get('active_connections')) is not None:
            args['active_connections'] = active_connections
        else:
            raise ValueError('Required property \'active_connections\' not present in LoadBalancerStatistics JSON')
        if (connection_rate := _dict.get('connection_rate')) is not None:
            args['connection_rate'] = connection_rate
        else:
            raise ValueError('Required property \'connection_rate\' not present in LoadBalancerStatistics JSON')
        if (data_processed_this_month := _dict.get('data_processed_this_month')) is not None:
            args['data_processed_this_month'] = data_processed_this_month
        else:
            raise ValueError('Required property \'data_processed_this_month\' not present in LoadBalancerStatistics JSON')
        if (throughput := _dict.get('throughput')) is not None:
            args['throughput'] = 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.

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

    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 := _dict.get('created_at')) is not None:
            args['created_at'] = string_to_datetime(created_at)
        else:
            raise ValueError('Required property \'created_at\' not present in NetworkACL JSON')
        if (crn := _dict.get('crn')) is not None:
            args['crn'] = crn
        else:
            raise ValueError('Required property \'crn\' not present in NetworkACL JSON')
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in NetworkACL JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in NetworkACL JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in NetworkACL JSON')
        if (resource_group := _dict.get('resource_group')) is not None:
            args['resource_group'] = ResourceGroupReference.from_dict(resource_group)
        else:
            raise ValueError('Required property \'resource_group\' not present in NetworkACL JSON')
        if (rules := _dict.get('rules')) is not None:
            args['rules'] = [NetworkACLRuleItem.from_dict(v) for v in rules]
        else:
            raise ValueError('Required property \'rules\' not present in NetworkACL JSON')
        if (subnets := _dict.get('subnets')) is not None:
            args['subnets'] = [SubnetReference.from_dict(v) for v in subnets]
        else:
            raise ValueError('Required property \'subnets\' not present in NetworkACL JSON')
        if (vpc := _dict.get('vpc')) is not None:
            args['vpc'] = VPCReference.from_dict(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.

    :param PageLink 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: A page of network ACLs.
    :param PageLink next: (optional) A link to the next page of resources. This
          property is present for all pages
          except the last page.
    :param int total_count: The total number of resources across all pages.
    """

    def __init__(
        self,
        first: 'PageLink',
        limit: int,
        network_acls: List['NetworkACL'],
        total_count: int,
        *,
        next: Optional['PageLink'] = None,
    ) -> None:
        """
        Initialize a NetworkACLCollection object.

        :param PageLink 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: A page of network ACLs.
        :param int total_count: The total number of resources across all pages.
        :param PageLink 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 := _dict.get('first')) is not None:
            args['first'] = PageLink.from_dict(first)
        else:
            raise ValueError('Required property \'first\' not present in NetworkACLCollection JSON')
        if (limit := _dict.get('limit')) is not None:
            args['limit'] = limit
        else:
            raise ValueError('Required property \'limit\' not present in NetworkACLCollection JSON')
        if (network_acls := _dict.get('network_acls')) is not None:
            args['network_acls'] = [NetworkACL.from_dict(v) for v in network_acls]
        else:
            raise ValueError('Required property \'network_acls\' not present in NetworkACLCollection JSON')
        if (next := _dict.get('next')) is not None:
            args['next'] = PageLink.from_dict(next)
        if (total_count := _dict.get('total_count')) is not None:
            args['total_count'] = 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 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.

    :param 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: Optional[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 := _dict.get('name')) is not None:
            args['name'] = 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.

    :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.
    :param VPCIdentity vpc: The VPC this network ACL will reside in.
    """

    def __init__(
        self,
        vpc: 'VPCIdentity',
        *,
        name: Optional[str] = None,
        resource_group: Optional['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.

    :param str crn: The CRN for this network ACL.
    :param Deleted deleted: (optional) If present, this property indicates the
          referenced resource has been deleted, and provides
          some supplementary information.
    :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.
    """

    def __init__(
        self,
        crn: str,
        href: str,
        id: str,
        name: str,
        *,
        deleted: Optional['Deleted'] = 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 Deleted 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 := _dict.get('crn')) is not None:
            args['crn'] = crn
        else:
            raise ValueError('Required property \'crn\' not present in NetworkACLReference JSON')
        if (deleted := _dict.get('deleted')) is not None:
            args['deleted'] = Deleted.from_dict(deleted)
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in NetworkACLReference JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in NetworkACLReference JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = 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 NetworkACLRule:
    """
    NetworkACLRule.

    :param str action: The action to perform for a packet matching the rule.
    :param NetworkACLRuleReference before: (optional) The rule that this rule is
          immediately before. If absent, this is the last 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 network protocol.
    :param 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: Optional['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 network protocol.
        :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 network protocol.
        """

        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.

    :param PageLink 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 PageLink next: (optional) A link to the next page of resources. This
          property is present for all pages
          except the last page.
    :param List[NetworkACLRuleItem] rules: A page of ordered rules (sorted based on
          the `before` property) for the network ACL.
    :param int total_count: The total number of resources across all pages.
    """

    def __init__(
        self,
        first: 'PageLink',
        limit: int,
        rules: List['NetworkACLRuleItem'],
        total_count: int,
        *,
        next: Optional['PageLink'] = None,
    ) -> None:
        """
        Initialize a NetworkACLRuleCollection object.

        :param PageLink 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: A page of ordered rules (sorted
               based on the `before` property) for the network ACL.
        :param int total_count: The total number of resources across all pages.
        :param PageLink 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 := _dict.get('first')) is not None:
            args['first'] = PageLink.from_dict(first)
        else:
            raise ValueError('Required property \'first\' not present in NetworkACLRuleCollection JSON')
        if (limit := _dict.get('limit')) is not None:
            args['limit'] = limit
        else:
            raise ValueError('Required property \'limit\' not present in NetworkACLRuleCollection JSON')
        if (next := _dict.get('next')) is not None:
            args['next'] = PageLink.from_dict(next)
        if (rules := _dict.get('rules')) is not None:
            args['rules'] = [NetworkACLRuleItem.from_dict(v) for v in rules]
        else:
            raise ValueError('Required property \'rules\' not present in NetworkACLRuleCollection JSON')
        if (total_count := _dict.get('total_count')) is not None:
            args['total_count'] = 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 NetworkACLRuleItem:
    """
    NetworkACLRuleItem.

    :param str action: The action to perform for a packet matching the rule.
    :param NetworkACLRuleReference before: (optional) The rule that this rule is
          immediately before. In a rule collection, this always
          refers to the next item in the collection. If absent, this is the last rule.
    :param 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 network protocol.
    :param 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: Optional['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 network protocol.
        :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 network protocol.
        """

        ALL = 'all'
        ICMP = 'icmp'
        TCP = 'tcp'
        UDP = 'udp'



class NetworkACLRulePatch:
    """
    NetworkACLRulePatch.

    :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 network protocol.
    :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.
    """

    def __init__(
        self,
        *,
        action: Optional[str] = None,
        before: Optional['NetworkACLRuleBeforePatch'] = None,
        code: Optional[int] = None,
        destination: Optional[str] = None,
        destination_port_max: Optional[int] = None,
        destination_port_min: Optional[int] = None,
        direction: Optional[str] = None,
        name: Optional[str] = None,
        protocol: Optional[str] = None,
        source: Optional[str] = None,
        source_port_max: Optional[int] = None,
        source_port_min: Optional[int] = None,
        type: Optional[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 network protocol.
        :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 := _dict.get('action')) is not None:
            args['action'] = action
        if (before := _dict.get('before')) is not None:
            args['before'] = before
        if (code := _dict.get('code')) is not None:
            args['code'] = code
        if (destination := _dict.get('destination')) is not None:
            args['destination'] = destination
        if (destination_port_max := _dict.get('destination_port_max')) is not None:
            args['destination_port_max'] = destination_port_max
        if (destination_port_min := _dict.get('destination_port_min')) is not None:
            args['destination_port_min'] = destination_port_min
        if (direction := _dict.get('direction')) is not None:
            args['direction'] = direction
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        if (protocol := _dict.get('protocol')) is not None:
            args['protocol'] = protocol
        if (source := _dict.get('source')) is not None:
            args['source'] = source
        if (source_port_max := _dict.get('source_port_max')) is not None:
            args['source_port_max'] = source_port_max
        if (source_port_min := _dict.get('source_port_min')) is not None:
            args['source_port_min'] = source_port_min
        if (type := _dict.get('type')) is not None:
            args['type'] = 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 network protocol.
        """

        ALL = 'all'
        ICMP = 'icmp'
        TCP = 'tcp'
        UDP = 'udp'



class NetworkACLRulePrototype:
    """
    NetworkACLRulePrototype.

    :param str action: The action to perform for a packet matching the rule.
    :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 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 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 str protocol: The network protocol.
    :param 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: Optional['NetworkACLRuleBeforePrototype'] = None,
        ip_version: Optional[str] = None,
        name: Optional[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 network protocol.
        :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 network protocol.
        """

        ALL = 'all'
        ICMP = 'icmp'
        TCP = 'tcp'
        UDP = 'udp'



class NetworkACLRulePrototypeNetworkACLContext:
    """
    NetworkACLRulePrototypeNetworkACLContext.

    :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 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 str protocol: The network protocol.
    :param 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: Optional[str] = None,
        name: Optional[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 network protocol.
        :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 network protocol.
        """

        ALL = 'all'
        ICMP = 'icmp'
        TCP = 'tcp'
        UDP = 'udp'



class NetworkACLRuleReference:
    """
    NetworkACLRuleReference.

    :param Deleted deleted: (optional) If present, this property indicates the
          referenced resource has been deleted, and provides
          some supplementary information.
    :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.
    """

    def __init__(
        self,
        href: str,
        id: str,
        name: str,
        *,
        deleted: Optional['Deleted'] = 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 Deleted 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 := _dict.get('deleted')) is not None:
            args['deleted'] = Deleted.from_dict(deleted)
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in NetworkACLRuleReference JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in NetworkACLRuleReference JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = 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 NetworkInterface:
    """
    NetworkInterface.

    :param bool allow_ip_spoofing: Indicates whether source IP spoofing is allowed
          on this instance network interface.
          If this instance has network attachments, this network interface is a
          [read-only
          representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
          of its corresponding network attachment and its attached virtual network
          interface, and source IP spoofing is managed on the attached virtual network
          interface.
    :param datetime created_at: The date and time that the instance network
          interface was created.
          If this instance has network attachments, this network interface was created as
          a [read-only
          representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
          when its corresponding network attachment was created.
    :param List[FloatingIPReference] floating_ips: The floating IPs associated with
          this instance network interface.
          If this instance has network attachments, this network interface is a
          [read-only
          representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
          of its corresponding network attachment and its attached virtual network
          interface, and the floating IPs are associated with the attached virtual network
          interface.
    :param str href: The URL for this instance network interface.
          If this instance has network attachments, this network interface is a
          [read-only
          representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
          of its corresponding network attachment.
    :param str id: The unique identifier for this instance network interface.
          If this instance has network attachments, this network interface is a
          [read-only
          representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
          of its corresponding network attachment and its attached virtual network
          interface, and the identifier is that of the corresponding network attachment.
    :param str name: The name for this instance network interface.
          If this instance has network attachments, this network interface is a
          [read-only
          representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
          of its corresponding network attachment and its attached virtual network
          interface, and the name matches its corresponding network attachment.
    :param int port_speed: The instance network interface port speed in Mbps.
          If this instance has network attachments, this network interface is a
          [read-only
          representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
          of its corresponding network attachment and its attached virtual network
          interface, and the port speed is that of its corresponding network attachment.
    :param ReservedIPReference primary_ip:
    :param str resource_type: The resource type.
    :param List[SecurityGroupReference] security_groups: The security groups
          targeting this instance network interface.
          If this instance has network attachments, this network interface is a
          [read-only
          representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
          of its corresponding network attachment and its attached virtual network
          interface, and the security groups are associated with the attached virtual
          network interface.
    :param str status: The status of the instance network interface.
          If this instance has network attachments, this network interface is a read-only
          representation of its corresponding network attachment and its attached virtual
          network interface, and the status is [computed from
          them](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients).
    :param SubnetReference subnet: The associated subnet.
    :param str type: The instance network interface type.
          If this instance has network attachments, this network interface is a
          [read-only
          representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
          of its corresponding network attachment and its attached virtual network
          interface, and the type is that of its corresponding network attachment.
    """

    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.
               If this instance has network attachments, this network interface is a
               [read-only
               representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
               of its corresponding network attachment and its attached virtual network
               interface, and source IP spoofing is managed on the attached virtual
               network interface.
        :param datetime created_at: The date and time that the instance network
               interface was created.
               If this instance has network attachments, this network interface was
               created as a [read-only
               representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
               when its corresponding network attachment was created.
        :param List[FloatingIPReference] floating_ips: The floating IPs associated
               with this instance network interface.
               If this instance has network attachments, this network interface is a
               [read-only
               representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
               of its corresponding network attachment and its attached virtual network
               interface, and the floating IPs are associated with the attached virtual
               network interface.
        :param str href: The URL for this instance network interface.
               If this instance has network attachments, this network interface is a
               [read-only
               representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
               of its corresponding network attachment.
        :param str id: The unique identifier for this instance network interface.
               If this instance has network attachments, this network interface is a
               [read-only
               representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
               of its corresponding network attachment and its attached virtual network
               interface, and the identifier is that of the corresponding network
               attachment.
        :param str name: The name for this instance network interface.
               If this instance has network attachments, this network interface is a
               [read-only
               representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
               of its corresponding network attachment and its attached virtual network
               interface, and the name matches its corresponding network attachment.
        :param int port_speed: The instance network interface port speed in Mbps.
               If this instance has network attachments, this network interface is a
               [read-only
               representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
               of its corresponding network attachment and its attached virtual network
               interface, and the port speed is that of its corresponding network
               attachment.
        :param ReservedIPReference primary_ip:
        :param str resource_type: The resource type.
        :param List[SecurityGroupReference] security_groups: The security groups
               targeting this instance network interface.
               If this instance has network attachments, this network interface is a
               [read-only
               representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
               of its corresponding network attachment and its attached virtual network
               interface, and the security groups are associated with the attached virtual
               network interface.
        :param str status: The status of the instance network interface.
               If this instance has network attachments, this network interface is a
               read-only representation of its corresponding network attachment and its
               attached virtual network interface, and the status is [computed from
               them](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients).
        :param SubnetReference subnet: The associated subnet.
        :param str type: The instance network interface type.
               If this instance has network attachments, this network interface is a
               [read-only
               representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
               of its corresponding network attachment and its attached virtual network
               interface, and the type is that of its corresponding network attachment.
        """
        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 := _dict.get('allow_ip_spoofing')) is not None:
            args['allow_ip_spoofing'] = allow_ip_spoofing
        else:
            raise ValueError('Required property \'allow_ip_spoofing\' not present in NetworkInterface JSON')
        if (created_at := _dict.get('created_at')) is not None:
            args['created_at'] = string_to_datetime(created_at)
        else:
            raise ValueError('Required property \'created_at\' not present in NetworkInterface JSON')
        if (floating_ips := _dict.get('floating_ips')) is not None:
            args['floating_ips'] = [FloatingIPReference.from_dict(v) for v in floating_ips]
        else:
            raise ValueError('Required property \'floating_ips\' not present in NetworkInterface JSON')
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in NetworkInterface JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in NetworkInterface JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in NetworkInterface JSON')
        if (port_speed := _dict.get('port_speed')) is not None:
            args['port_speed'] = port_speed
        else:
            raise ValueError('Required property \'port_speed\' not present in NetworkInterface JSON')
        if (primary_ip := _dict.get('primary_ip')) is not None:
            args['primary_ip'] = ReservedIPReference.from_dict(primary_ip)
        else:
            raise ValueError('Required property \'primary_ip\' not present in NetworkInterface JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = resource_type
        else:
            raise ValueError('Required property \'resource_type\' not present in NetworkInterface JSON')
        if (security_groups := _dict.get('security_groups')) is not None:
            args['security_groups'] = [SecurityGroupReference.from_dict(v) for v in security_groups]
        else:
            raise ValueError('Required property \'security_groups\' not present in NetworkInterface JSON')
        if (status := _dict.get('status')) is not None:
            args['status'] = status
        else:
            raise ValueError('Required property \'status\' not present in NetworkInterface JSON')
        if (subnet := _dict.get('subnet')) is not None:
            args['subnet'] = SubnetReference.from_dict(subnet)
        else:
            raise ValueError('Required property \'subnet\' not present in NetworkInterface JSON')
        if (type := _dict.get('type')) is not None:
            args['type'] = 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.
        If this instance has network attachments, this network interface is a read-only
        representation of its corresponding network attachment and its attached virtual
        network interface, and the status is [computed from
        them](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients).
        """

        AVAILABLE = 'available'
        DELETING = 'deleting'
        FAILED = 'failed'
        PENDING = 'pending'


    class TypeEnum(str, Enum):
        """
        The instance network interface type.
        If this instance has network attachments, this network interface is a
        [read-only
        representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
        of its corresponding network attachment and its attached virtual network
        interface, and the type is that of its corresponding network attachment.
        """

        PRIMARY = 'primary'
        SECONDARY = 'secondary'



class NetworkInterfaceBareMetalServerContextReference:
    """
    NetworkInterfaceBareMetalServerContextReference.

    :param Deleted deleted: (optional) If present, this property indicates the
          referenced resource has been deleted, and provides
          some supplementary information.
    :param str href: The URL for this bare metal server network interface.
          If this bare metal server has network attachments, this network interface is a
          [read-only
          representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
          of its corresponding network attachment.
    :param str id: The unique identifier for this bare metal server network
          interface.
          If this bare metal server has network attachments, this network interface is a
          [read-only
          representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
          of its corresponding network attachment and its attached virtual network
          interface, and the identifier is that of the corresponding network attachment.
    :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.
    """

    def __init__(
        self,
        href: str,
        id: str,
        name: str,
        primary_ip: 'ReservedIPReference',
        resource_type: str,
        subnet: 'SubnetReference',
        *,
        deleted: Optional['Deleted'] = None,
    ) -> None:
        """
        Initialize a NetworkInterfaceBareMetalServerContextReference object.

        :param str href: The URL for this bare metal server network interface.
               If this bare metal server has network attachments, this network interface
               is a
               [read-only
               representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
               of its corresponding network attachment.
        :param str id: The unique identifier for this bare metal server network
               interface.
               If this bare metal server has network attachments, this network interface
               is a
               [read-only
               representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
               of its corresponding network attachment and its attached virtual network
               interface, and the identifier is that of the corresponding network
               attachment.
        :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 Deleted 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 := _dict.get('deleted')) is not None:
            args['deleted'] = Deleted.from_dict(deleted)
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in NetworkInterfaceBareMetalServerContextReference JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in NetworkInterfaceBareMetalServerContextReference JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in NetworkInterfaceBareMetalServerContextReference JSON')
        if (primary_ip := _dict.get('primary_ip')) is not None:
            args['primary_ip'] = ReservedIPReference.from_dict(primary_ip)
        else:
            raise ValueError('Required property \'primary_ip\' not present in NetworkInterfaceBareMetalServerContextReference JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = resource_type
        else:
            raise ValueError('Required property \'resource_type\' not present in NetworkInterfaceBareMetalServerContextReference JSON')
        if (subnet := _dict.get('subnet')) is not None:
            args['subnet'] = SubnetReference.from_dict(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 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.

    :param Deleted deleted: (optional) If present, this property indicates the
          referenced resource has been deleted, and provides
          some supplementary information.
    :param str href: The URL for this instance network interface.
          If this instance has network attachments, this network interface is a
          [read-only
          representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
          of its corresponding network attachment.
    :param str id: The unique identifier for this instance network interface.
          If this instance has network attachments, this network interface is a
          [read-only
          representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
          of its corresponding network attachment and its attached virtual network
          interface, and the identifier is that of the corresponding network attachment.
    :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.
    """

    def __init__(
        self,
        href: str,
        id: str,
        name: str,
        primary_ip: 'ReservedIPReference',
        resource_type: str,
        subnet: 'SubnetReference',
        *,
        deleted: Optional['Deleted'] = None,
    ) -> None:
        """
        Initialize a NetworkInterfaceInstanceContextReference object.

        :param str href: The URL for this instance network interface.
               If this instance has network attachments, this network interface is a
               [read-only
               representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
               of its corresponding network attachment.
        :param str id: The unique identifier for this instance network interface.
               If this instance has network attachments, this network interface is a
               [read-only
               representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
               of its corresponding network attachment and its attached virtual network
               interface, and the identifier is that of the corresponding network
               attachment.
        :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 Deleted 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 := _dict.get('deleted')) is not None:
            args['deleted'] = Deleted.from_dict(deleted)
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in NetworkInterfaceInstanceContextReference JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in NetworkInterfaceInstanceContextReference JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in NetworkInterfaceInstanceContextReference JSON')
        if (primary_ip := _dict.get('primary_ip')) is not None:
            args['primary_ip'] = ReservedIPReference.from_dict(primary_ip)
        else:
            raise ValueError('Required property \'primary_ip\' not present in NetworkInterfaceInstanceContextReference JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = resource_type
        else:
            raise ValueError('Required property \'resource_type\' not present in NetworkInterfaceInstanceContextReference JSON')
        if (subnet := _dict.get('subnet')) is not None:
            args['subnet'] = SubnetReference.from_dict(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 NetworkInterfacePatch:
    """
    NetworkInterfacePatch.

    :param bool allow_ip_spoofing: (optional) Indicates whether source IP spoofing
          is allowed on this instance network interface.
          If this instance has network attachments, this network interface is a
          [read-only
          representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
          of its corresponding network attachment and its attached virtual network
          interface, and source IP spoofing is managed on the attached virtual 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.
    """

    def __init__(
        self,
        *,
        allow_ip_spoofing: Optional[bool] = None,
        name: Optional[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.
               If this instance has network attachments, this network interface is a
               [read-only
               representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
               of its corresponding network attachment and its attached virtual network
               interface, and source IP spoofing is managed on the attached virtual
               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 := _dict.get('allow_ip_spoofing')) is not None:
            args['allow_ip_spoofing'] = allow_ip_spoofing
        if (name := _dict.get('name')) is not None:
            args['name'] = 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.

    :param bool allow_ip_spoofing: (optional) Indicates whether source IP spoofing
          is allowed on this instance network interface.
          If this instance has network attachments, this network interface is a
          [read-only
          representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
          of its corresponding network attachment and its attached virtual network
          interface, and source IP spoofing is managed on the attached virtual 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 SubnetIdentity subnet: The associated subnet.
    """

    def __init__(
        self,
        subnet: 'SubnetIdentity',
        *,
        allow_ip_spoofing: Optional[bool] = None,
        name: Optional[str] = None,
        primary_ip: Optional['NetworkInterfaceIPPrototype'] = None,
        security_groups: Optional[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.
               If this instance has network attachments, this network interface is a
               [read-only
               representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
               of its corresponding network attachment and its attached virtual network
               interface, and source IP spoofing is managed on the attached virtual
               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 := _dict.get('allow_ip_spoofing')) is not None:
            args['allow_ip_spoofing'] = allow_ip_spoofing
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        if (primary_ip := _dict.get('primary_ip')) is not None:
            args['primary_ip'] = primary_ip
        if (security_groups := _dict.get('security_groups')) is not None:
            args['security_groups'] = security_groups
        if (subnet := _dict.get('subnet')) is not None:
            args['subnet'] = 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 NetworkInterfaceUnpaginatedCollection:
    """
    NetworkInterfaceUnpaginatedCollection.

    :param List[NetworkInterface] network_interfaces: The network interfaces for the
          instance.
    """

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

        :param List[NetworkInterface] network_interfaces: The network interfaces
               for the instance.
        """
        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 := _dict.get('network_interfaces')) is not None:
            args['network_interfaces'] = [NetworkInterface.from_dict(v) for v in 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.

    :param bool allow_user_image_creation: Users may create new images with this
          operating system.
    :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 user_data_format: The user data format for this operating system:
          - `cloud_init`: `user_data` will be interpreted according to the cloud-init
          standard
          - `esxi_kickstart`: `user_data` will be interpreted as a VMware ESXi
          installation script
          - `ipxe`: `user_data` will be interpreted as a single URL to an iPXE script or
          as the
            text of an iPXE script.
    :param str vendor: The vendor of the operating system.
    :param str version: The major release version of this operating system.
    """

    def __init__(
        self,
        allow_user_image_creation: bool,
        architecture: str,
        dedicated_host_only: bool,
        display_name: str,
        family: str,
        href: str,
        name: str,
        user_data_format: str,
        vendor: str,
        version: str,
    ) -> None:
        """
        Initialize a OperatingSystem object.

        :param bool allow_user_image_creation: Users may create new images with
               this operating system.
        :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 user_data_format: The user data format for this operating
               system:
               - `cloud_init`: `user_data` will be interpreted according to the cloud-init
               standard
               - `esxi_kickstart`: `user_data` will be interpreted as a VMware ESXi
               installation script
               - `ipxe`: `user_data` will be interpreted as a single URL to an iPXE script
               or as the
                 text of an iPXE script.
        :param str vendor: The vendor of the operating system.
        :param str version: The major release version of this operating system.
        """
        self.allow_user_image_creation = allow_user_image_creation
        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.user_data_format = user_data_format
        self.vendor = vendor
        self.version = version

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'OperatingSystem':
        """Initialize a OperatingSystem object from a json dictionary."""
        args = {}
        if (allow_user_image_creation := _dict.get('allow_user_image_creation')) is not None:
            args['allow_user_image_creation'] = allow_user_image_creation
        else:
            raise ValueError('Required property \'allow_user_image_creation\' not present in OperatingSystem JSON')
        if (architecture := _dict.get('architecture')) is not None:
            args['architecture'] = architecture
        else:
            raise ValueError('Required property \'architecture\' not present in OperatingSystem JSON')
        if (dedicated_host_only := _dict.get('dedicated_host_only')) is not None:
            args['dedicated_host_only'] = dedicated_host_only
        else:
            raise ValueError('Required property \'dedicated_host_only\' not present in OperatingSystem JSON')
        if (display_name := _dict.get('display_name')) is not None:
            args['display_name'] = display_name
        else:
            raise ValueError('Required property \'display_name\' not present in OperatingSystem JSON')
        if (family := _dict.get('family')) is not None:
            args['family'] = family
        else:
            raise ValueError('Required property \'family\' not present in OperatingSystem JSON')
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in OperatingSystem JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in OperatingSystem JSON')
        if (user_data_format := _dict.get('user_data_format')) is not None:
            args['user_data_format'] = user_data_format
        else:
            raise ValueError('Required property \'user_data_format\' not present in OperatingSystem JSON')
        if (vendor := _dict.get('vendor')) is not None:
            args['vendor'] = vendor
        else:
            raise ValueError('Required property \'vendor\' not present in OperatingSystem JSON')
        if (version := _dict.get('version')) is not None:
            args['version'] = 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, 'allow_user_image_creation') and self.allow_user_image_creation is not None:
            _dict['allow_user_image_creation'] = self.allow_user_image_creation
        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, 'user_data_format') and self.user_data_format is not None:
            _dict['user_data_format'] = self.user_data_format
        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 UserDataFormatEnum(str, Enum):
        """
        The user data format for this operating system:
        - `cloud_init`: `user_data` will be interpreted according to the cloud-init
        standard
        - `esxi_kickstart`: `user_data` will be interpreted as a VMware ESXi installation
        script
        - `ipxe`: `user_data` will be interpreted as a single URL to an iPXE script or as
        the
          text of an iPXE script.
        """

        CLOUD_INIT = 'cloud_init'
        ESXI_KICKSTART = 'esxi_kickstart'
        IPXE = 'ipxe'



class OperatingSystemCollection:
    """
    OperatingSystemCollection.

    :param PageLink 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 PageLink next: (optional) A link to the next page of resources. This
          property is present for all pages
          except the last page.
    :param List[OperatingSystem] operating_systems: A page of operating systems.
    :param int total_count: The total number of resources across all pages.
    """

    def __init__(
        self,
        first: 'PageLink',
        limit: int,
        operating_systems: List['OperatingSystem'],
        total_count: int,
        *,
        next: Optional['PageLink'] = None,
    ) -> None:
        """
        Initialize a OperatingSystemCollection object.

        :param PageLink 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: A page of operating
               systems.
        :param int total_count: The total number of resources across all pages.
        :param PageLink 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 := _dict.get('first')) is not None:
            args['first'] = PageLink.from_dict(first)
        else:
            raise ValueError('Required property \'first\' not present in OperatingSystemCollection JSON')
        if (limit := _dict.get('limit')) is not None:
            args['limit'] = limit
        else:
            raise ValueError('Required property \'limit\' not present in OperatingSystemCollection JSON')
        if (next := _dict.get('next')) is not None:
            args['next'] = PageLink.from_dict(next)
        if (operating_systems := _dict.get('operating_systems')) is not None:
            args['operating_systems'] = [OperatingSystem.from_dict(v) for v in operating_systems]
        else:
            raise ValueError('Required property \'operating_systems\' not present in OperatingSystemCollection JSON')
        if (total_count := _dict.get('total_count')) is not None:
            args['total_count'] = 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 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 PageLink:
    """
    PageLink.

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

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

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

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

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

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

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

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

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

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


class PlacementGroup:
    """
    PlacementGroup.

    :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](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    """

    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](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        """
        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 := _dict.get('created_at')) is not None:
            args['created_at'] = string_to_datetime(created_at)
        else:
            raise ValueError('Required property \'created_at\' not present in PlacementGroup JSON')
        if (crn := _dict.get('crn')) is not None:
            args['crn'] = crn
        else:
            raise ValueError('Required property \'crn\' not present in PlacementGroup JSON')
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in PlacementGroup JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in PlacementGroup JSON')
        if (lifecycle_state := _dict.get('lifecycle_state')) is not None:
            args['lifecycle_state'] = lifecycle_state
        else:
            raise ValueError('Required property \'lifecycle_state\' not present in PlacementGroup JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in PlacementGroup JSON')
        if (resource_group := _dict.get('resource_group')) is not None:
            args['resource_group'] = ResourceGroupReference.from_dict(resource_group)
        else:
            raise ValueError('Required property \'resource_group\' not present in PlacementGroup JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = resource_type
        else:
            raise ValueError('Required property \'resource_type\' not present in PlacementGroup JSON')
        if (strategy := _dict.get('strategy')) is not None:
            args['strategy'] = 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](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        HOST_SPREAD = 'host_spread'
        POWER_SPREAD = 'power_spread'



class PlacementGroupCollection:
    """
    PlacementGroupCollection.

    :param PageLink 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 PageLink next: (optional) A link to the next page of resources. This
          property is present for all pages
          except the last page.
    :param List[PlacementGroup] placement_groups: A page of placement groups.
    :param int total_count: The total number of resources across all pages.
    """

    def __init__(
        self,
        first: 'PageLink',
        limit: int,
        placement_groups: List['PlacementGroup'],
        total_count: int,
        *,
        next: Optional['PageLink'] = None,
    ) -> None:
        """
        Initialize a PlacementGroupCollection object.

        :param PageLink 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: A page of placement groups.
        :param int total_count: The total number of resources across all pages.
        :param PageLink 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 := _dict.get('first')) is not None:
            args['first'] = PageLink.from_dict(first)
        else:
            raise ValueError('Required property \'first\' not present in PlacementGroupCollection JSON')
        if (limit := _dict.get('limit')) is not None:
            args['limit'] = limit
        else:
            raise ValueError('Required property \'limit\' not present in PlacementGroupCollection JSON')
        if (next := _dict.get('next')) is not None:
            args['next'] = PageLink.from_dict(next)
        if (placement_groups := _dict.get('placement_groups')) is not None:
            args['placement_groups'] = [PlacementGroup.from_dict(v) for v in placement_groups]
        else:
            raise ValueError('Required property \'placement_groups\' not present in PlacementGroupCollection JSON')
        if (total_count := _dict.get('total_count')) is not None:
            args['total_count'] = 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 PlacementGroupPatch:
    """
    PlacementGroupPatch.

    :param 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: Optional[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 := _dict.get('name')) is not None:
            args['name'] = 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 PrivatePathServiceGateway:
    """
    PrivatePathServiceGateway.

    :param datetime created_at: The date and time that the private path service
          gateway was created.
    :param str crn: The CRN for this private path service gateway.
    :param str default_access_policy: The policy to use for bindings from accounts
          without an explicit account policy.
    :param bool endpoint_gateway_binding_auto_delete: Indicates whether endpoint
          gateway bindings will be automatically deleted after
          `endpoint_gateway_binding_auto_delete_timeout` hours have passed. At present,
          this is always `true`, but may be modifiable in the future.
    :param int endpoint_gateway_binding_auto_delete_timeout: If
          `endpoint_gateway_binding_auto_delete` is `true`, the hours after which endpoint
          gateway bindings will be automatically deleted. If the value is `0`, `abandoned`
          endpoint gateway bindings will be deleted immediately. At present, this is
          always set to `0`. This value may be modifiable in the future.
    :param int endpoint_gateway_count: The number of active endpoint gateways using
          this private path service gateway.
    :param str href: The URL for this private path service gateway.
    :param str id: The unique identifier for this private path service gateway.
    :param str lifecycle_state: The lifecycle state of the private path service
          gateway.
    :param LoadBalancerReference load_balancer: The load balancer for this private
          path service gateway.
    :param str name: The name for this private path service gateway. The name is
          unique across all private path service gateways in the VPC.
    :param bool published: Indicates the availability of this private path service
          gateway
          - `true`: Any account can request access to this private path service gateway.
          - `false`: Access is restricted to the account that created this private path
          service gateway.
    :param ResourceGroupReference resource_group: The resource group for this
          private path service gateway.
    :param str resource_type: The resource type.
    :param List[str] service_endpoints: The fully qualified domain names for this
          private path service gateway. The domains are used for endpoint gateways to
          connect to the service and are configured in the VPC for each endpoint gateway.
    :param VPCReference vpc: The VPC this private path service gateway resides in.
    :param bool zonal_affinity: Indicates whether this private path service gateway
          has zonal affinity.
          - `true`:  Traffic to the service from a zone the service resides in will remain
          in
                     that zone.
          - `false`: Traffic to the service from a zone will be load balanced across all
          zones
                     in the region the service resides in.
    """

    def __init__(
        self,
        created_at: datetime,
        crn: str,
        default_access_policy: str,
        endpoint_gateway_binding_auto_delete: bool,
        endpoint_gateway_binding_auto_delete_timeout: int,
        endpoint_gateway_count: int,
        href: str,
        id: str,
        lifecycle_state: str,
        load_balancer: 'LoadBalancerReference',
        name: str,
        published: bool,
        resource_group: 'ResourceGroupReference',
        resource_type: str,
        service_endpoints: List[str],
        vpc: 'VPCReference',
        zonal_affinity: bool,
    ) -> None:
        """
        Initialize a PrivatePathServiceGateway object.

        :param datetime created_at: The date and time that the private path service
               gateway was created.
        :param str crn: The CRN for this private path service gateway.
        :param str default_access_policy: The policy to use for bindings from
               accounts without an explicit account policy.
        :param bool endpoint_gateway_binding_auto_delete: Indicates whether
               endpoint gateway bindings will be automatically deleted after
               `endpoint_gateway_binding_auto_delete_timeout` hours have passed. At
               present, this is always `true`, but may be modifiable in the future.
        :param int endpoint_gateway_binding_auto_delete_timeout: If
               `endpoint_gateway_binding_auto_delete` is `true`, the hours after which
               endpoint gateway bindings will be automatically deleted. If the value is
               `0`, `abandoned` endpoint gateway bindings will be deleted immediately. At
               present, this is always set to `0`. This value may be modifiable in the
               future.
        :param int endpoint_gateway_count: The number of active endpoint gateways
               using this private path service gateway.
        :param str href: The URL for this private path service gateway.
        :param str id: The unique identifier for this private path service gateway.
        :param str lifecycle_state: The lifecycle state of the private path service
               gateway.
        :param LoadBalancerReference load_balancer: The load balancer for this
               private path service gateway.
        :param str name: The name for this private path service gateway. The name
               is unique across all private path service gateways in the VPC.
        :param bool published: Indicates the availability of this private path
               service gateway
               - `true`: Any account can request access to this private path service
               gateway.
               - `false`: Access is restricted to the account that created this private
               path service gateway.
        :param ResourceGroupReference resource_group: The resource group for this
               private path service gateway.
        :param str resource_type: The resource type.
        :param List[str] service_endpoints: The fully qualified domain names for
               this private path service gateway. The domains are used for endpoint
               gateways to connect to the service and are configured in the VPC for each
               endpoint gateway.
        :param VPCReference vpc: The VPC this private path service gateway resides
               in.
        :param bool zonal_affinity: Indicates whether this private path service
               gateway has zonal affinity.
               - `true`:  Traffic to the service from a zone the service resides in will
               remain in
                          that zone.
               - `false`: Traffic to the service from a zone will be load balanced across
               all zones
                          in the region the service resides in.
        """
        self.created_at = created_at
        self.crn = crn
        self.default_access_policy = default_access_policy
        self.endpoint_gateway_binding_auto_delete = endpoint_gateway_binding_auto_delete
        self.endpoint_gateway_binding_auto_delete_timeout = endpoint_gateway_binding_auto_delete_timeout
        self.endpoint_gateway_count = endpoint_gateway_count
        self.href = href
        self.id = id
        self.lifecycle_state = lifecycle_state
        self.load_balancer = load_balancer
        self.name = name
        self.published = published
        self.resource_group = resource_group
        self.resource_type = resource_type
        self.service_endpoints = service_endpoints
        self.vpc = vpc
        self.zonal_affinity = zonal_affinity

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'PrivatePathServiceGateway':
        """Initialize a PrivatePathServiceGateway object from a json dictionary."""
        args = {}
        if (created_at := _dict.get('created_at')) is not None:
            args['created_at'] = string_to_datetime(created_at)
        else:
            raise ValueError('Required property \'created_at\' not present in PrivatePathServiceGateway JSON')
        if (crn := _dict.get('crn')) is not None:
            args['crn'] = crn
        else:
            raise ValueError('Required property \'crn\' not present in PrivatePathServiceGateway JSON')
        if (default_access_policy := _dict.get('default_access_policy')) is not None:
            args['default_access_policy'] = default_access_policy
        else:
            raise ValueError('Required property \'default_access_policy\' not present in PrivatePathServiceGateway JSON')
        if (endpoint_gateway_binding_auto_delete := _dict.get('endpoint_gateway_binding_auto_delete')) is not None:
            args['endpoint_gateway_binding_auto_delete'] = endpoint_gateway_binding_auto_delete
        else:
            raise ValueError('Required property \'endpoint_gateway_binding_auto_delete\' not present in PrivatePathServiceGateway JSON')
        if (endpoint_gateway_binding_auto_delete_timeout := _dict.get('endpoint_gateway_binding_auto_delete_timeout')) is not None:
            args['endpoint_gateway_binding_auto_delete_timeout'] = endpoint_gateway_binding_auto_delete_timeout
        else:
            raise ValueError('Required property \'endpoint_gateway_binding_auto_delete_timeout\' not present in PrivatePathServiceGateway JSON')
        if (endpoint_gateway_count := _dict.get('endpoint_gateway_count')) is not None:
            args['endpoint_gateway_count'] = endpoint_gateway_count
        else:
            raise ValueError('Required property \'endpoint_gateway_count\' not present in PrivatePathServiceGateway JSON')
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in PrivatePathServiceGateway JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in PrivatePathServiceGateway JSON')
        if (lifecycle_state := _dict.get('lifecycle_state')) is not None:
            args['lifecycle_state'] = lifecycle_state
        else:
            raise ValueError('Required property \'lifecycle_state\' not present in PrivatePathServiceGateway JSON')
        if (load_balancer := _dict.get('load_balancer')) is not None:
            args['load_balancer'] = LoadBalancerReference.from_dict(load_balancer)
        else:
            raise ValueError('Required property \'load_balancer\' not present in PrivatePathServiceGateway JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in PrivatePathServiceGateway JSON')
        if (published := _dict.get('published')) is not None:
            args['published'] = published
        else:
            raise ValueError('Required property \'published\' not present in PrivatePathServiceGateway JSON')
        if (resource_group := _dict.get('resource_group')) is not None:
            args['resource_group'] = ResourceGroupReference.from_dict(resource_group)
        else:
            raise ValueError('Required property \'resource_group\' not present in PrivatePathServiceGateway JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = resource_type
        else:
            raise ValueError('Required property \'resource_type\' not present in PrivatePathServiceGateway JSON')
        if (service_endpoints := _dict.get('service_endpoints')) is not None:
            args['service_endpoints'] = service_endpoints
        else:
            raise ValueError('Required property \'service_endpoints\' not present in PrivatePathServiceGateway JSON')
        if (vpc := _dict.get('vpc')) is not None:
            args['vpc'] = VPCReference.from_dict(vpc)
        else:
            raise ValueError('Required property \'vpc\' not present in PrivatePathServiceGateway JSON')
        if (zonal_affinity := _dict.get('zonal_affinity')) is not None:
            args['zonal_affinity'] = zonal_affinity
        else:
            raise ValueError('Required property \'zonal_affinity\' not present in PrivatePathServiceGateway JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a PrivatePathServiceGateway object from 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, 'default_access_policy') and self.default_access_policy is not None:
            _dict['default_access_policy'] = self.default_access_policy
        if hasattr(self, 'endpoint_gateway_binding_auto_delete') and self.endpoint_gateway_binding_auto_delete is not None:
            _dict['endpoint_gateway_binding_auto_delete'] = self.endpoint_gateway_binding_auto_delete
        if hasattr(self, 'endpoint_gateway_binding_auto_delete_timeout') and self.endpoint_gateway_binding_auto_delete_timeout is not None:
            _dict['endpoint_gateway_binding_auto_delete_timeout'] = self.endpoint_gateway_binding_auto_delete_timeout
        if hasattr(self, 'endpoint_gateway_count') and self.endpoint_gateway_count is not None:
            _dict['endpoint_gateway_count'] = self.endpoint_gateway_count
        if hasattr(self, 'href') and self.href 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, '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, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'published') and self.published is not None:
            _dict['published'] = self.published
        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_endpoints') and self.service_endpoints is not None:
            _dict['service_endpoints'] = self.service_endpoints
        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, 'zonal_affinity') and self.zonal_affinity is not None:
            _dict['zonal_affinity'] = self.zonal_affinity
        return _dict

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

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

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

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

    class DefaultAccessPolicyEnum(str, Enum):
        """
        The policy to use for bindings from accounts without an explicit account policy.
        """

        DENY = 'deny'
        PERMIT = 'permit'
        REVIEW = 'review'


    class LifecycleStateEnum(str, Enum):
        """
        The lifecycle state of the private path service gateway.
        """

        DELETING = 'deleting'
        FAILED = 'failed'
        PENDING = 'pending'
        STABLE = 'stable'
        SUSPENDED = 'suspended'
        UPDATING = 'updating'
        WAITING = 'waiting'


    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        PRIVATE_PATH_SERVICE_GATEWAY = 'private_path_service_gateway'



class PrivatePathServiceGatewayAccountPolicy:
    """
    PrivatePathServiceGatewayAccountPolicy.

    :param str access_policy: The access policy for the account:
          - permit: access will be permitted
          - deny:  access will be denied
          - review: access will be manually reviewed
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :param AccountReference account: The account for this access policy.
    :param datetime created_at: The date and time that the account policy was
          created.
    :param str href: The URL for this account policy.
    :param str id: The unique identifier for this account policy.
    :param str resource_type: The resource type.
    """

    def __init__(
        self,
        access_policy: str,
        account: 'AccountReference',
        created_at: datetime,
        href: str,
        id: str,
        resource_type: str,
    ) -> None:
        """
        Initialize a PrivatePathServiceGatewayAccountPolicy object.

        :param str access_policy: The access policy for the account:
               - permit: access will be permitted
               - deny:  access will be denied
               - review: access will be manually reviewed
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :param AccountReference account: The account for this access policy.
        :param datetime created_at: The date and time that the account policy was
               created.
        :param str href: The URL for this account policy.
        :param str id: The unique identifier for this account policy.
        :param str resource_type: The resource type.
        """
        self.access_policy = access_policy
        self.account = account
        self.created_at = created_at
        self.href = href
        self.id = id
        self.resource_type = resource_type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'PrivatePathServiceGatewayAccountPolicy':
        """Initialize a PrivatePathServiceGatewayAccountPolicy object from a json dictionary."""
        args = {}
        if (access_policy := _dict.get('access_policy')) is not None:
            args['access_policy'] = access_policy
        else:
            raise ValueError('Required property \'access_policy\' not present in PrivatePathServiceGatewayAccountPolicy JSON')
        if (account := _dict.get('account')) is not None:
            args['account'] = AccountReference.from_dict(account)
        else:
            raise ValueError('Required property \'account\' not present in PrivatePathServiceGatewayAccountPolicy JSON')
        if (created_at := _dict.get('created_at')) is not None:
            args['created_at'] = string_to_datetime(created_at)
        else:
            raise ValueError('Required property \'created_at\' not present in PrivatePathServiceGatewayAccountPolicy JSON')
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in PrivatePathServiceGatewayAccountPolicy JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in PrivatePathServiceGatewayAccountPolicy JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = resource_type
        else:
            raise ValueError('Required property \'resource_type\' not present in PrivatePathServiceGatewayAccountPolicy JSON')
        return cls(**args)

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

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

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

    class AccessPolicyEnum(str, Enum):
        """
        The access policy for the account:
        - permit: access will be permitted
        - deny:  access will be denied
        - review: access will be manually reviewed
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        DENY = 'deny'
        PERMIT = 'permit'
        REVIEW = 'review'


    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        PRIVATE_PATH_SERVICE_GATEWAY_ACCOUNT_POLICY = 'private_path_service_gateway_account_policy'



class PrivatePathServiceGatewayAccountPolicyCollection:
    """
    PrivatePathServiceGatewayAccountPolicyCollection.

    :param List[PrivatePathServiceGatewayAccountPolicy] account_policies: A page of
          account policies for the private path service gateway.
    :param PageLink 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 PageLink next: (optional) A link to the next page of resources. This
          property is present for all pages
          except the last page.
    :param int total_count: The total number of resources across all pages.
    """

    def __init__(
        self,
        account_policies: List['PrivatePathServiceGatewayAccountPolicy'],
        first: 'PageLink',
        limit: int,
        total_count: int,
        *,
        next: Optional['PageLink'] = None,
    ) -> None:
        """
        Initialize a PrivatePathServiceGatewayAccountPolicyCollection object.

        :param List[PrivatePathServiceGatewayAccountPolicy] account_policies: A
               page of account policies for the private path service gateway.
        :param PageLink 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 PageLink next: (optional) A link to the next page of resources. This
               property is present for all pages
               except the last page.
        """
        self.account_policies = account_policies
        self.first = first
        self.limit = limit
        self.next = next
        self.total_count = total_count

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'PrivatePathServiceGatewayAccountPolicyCollection':
        """Initialize a PrivatePathServiceGatewayAccountPolicyCollection object from a json dictionary."""
        args = {}
        if (account_policies := _dict.get('account_policies')) is not None:
            args['account_policies'] = [PrivatePathServiceGatewayAccountPolicy.from_dict(v) for v in account_policies]
        else:
            raise ValueError('Required property \'account_policies\' not present in PrivatePathServiceGatewayAccountPolicyCollection JSON')
        if (first := _dict.get('first')) is not None:
            args['first'] = PageLink.from_dict(first)
        else:
            raise ValueError('Required property \'first\' not present in PrivatePathServiceGatewayAccountPolicyCollection JSON')
        if (limit := _dict.get('limit')) is not None:
            args['limit'] = limit
        else:
            raise ValueError('Required property \'limit\' not present in PrivatePathServiceGatewayAccountPolicyCollection JSON')
        if (next := _dict.get('next')) is not None:
            args['next'] = PageLink.from_dict(next)
        if (total_count := _dict.get('total_count')) is not None:
            args['total_count'] = total_count
        else:
            raise ValueError('Required property \'total_count\' not present in PrivatePathServiceGatewayAccountPolicyCollection JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a PrivatePathServiceGatewayAccountPolicyCollection object from 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_policies') and self.account_policies is not None:
            account_policies_list = []
            for v in self.account_policies:
                if isinstance(v, dict):
                    account_policies_list.append(v)
                else:
                    account_policies_list.append(v.to_dict())
            _dict['account_policies'] = account_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 PrivatePathServiceGatewayAccountPolicyCollection object."""
        return json.dumps(self.to_dict(), indent=2)

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

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


class PrivatePathServiceGatewayAccountPolicyPatch:
    """
    PrivatePathServiceGatewayAccountPolicyPatch.

    :param str access_policy: (optional) The access policy for the account. Updating
          the access policy only affects pending and future endpoint gateway bindings.
          - permit: access will be permitted
          - deny: access will be denied
          - review: access will be manually reviewed
          - Updating to `review` sets the status of future endpoint gateway bindings from
             this account to `pending`.
          - Updating to `permit` updates both the status of any `pending` and future
          endpoint
            gateway bindings from this account to `permitted`.
          - Updating to `deny` updates both the status of any `pending` and future
          endpoint
            gateway bindings from this account to `denied`.
    """

    def __init__(
        self,
        *,
        access_policy: Optional[str] = None,
    ) -> None:
        """
        Initialize a PrivatePathServiceGatewayAccountPolicyPatch object.

        :param str access_policy: (optional) The access policy for the account.
               Updating the access policy only affects pending and future endpoint gateway
               bindings.
               - permit: access will be permitted
               - deny: access will be denied
               - review: access will be manually reviewed
               - Updating to `review` sets the status of future endpoint gateway bindings
               from
                  this account to `pending`.
               - Updating to `permit` updates both the status of any `pending` and future
               endpoint
                 gateway bindings from this account to `permitted`.
               - Updating to `deny` updates both the status of any `pending` and future
               endpoint
                 gateway bindings from this account to `denied`.
        """
        self.access_policy = access_policy

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

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a PrivatePathServiceGatewayAccountPolicyPatch object from 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_policy') and self.access_policy is not None:
            _dict['access_policy'] = self.access_policy
        return _dict

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

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

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

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

    class AccessPolicyEnum(str, Enum):
        """
        The access policy for the account. Updating the access policy only affects pending
        and future endpoint gateway bindings.
        - permit: access will be permitted
        - deny: access will be denied
        - review: access will be manually reviewed
        - Updating to `review` sets the status of future endpoint gateway bindings from
           this account to `pending`.
        - Updating to `permit` updates both the status of any `pending` and future
        endpoint
          gateway bindings from this account to `permitted`.
        - Updating to `deny` updates both the status of any `pending` and future endpoint
          gateway bindings from this account to `denied`.
        """

        DENY = 'deny'
        PERMIT = 'permit'
        REVIEW = 'review'



class PrivatePathServiceGatewayCollection:
    """
    PrivatePathServiceGatewayCollection.

    :param PageLink 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 PageLink next: (optional) A link to the next page of resources. This
          property is present for all pages
          except the last page.
    :param List[PrivatePathServiceGateway] private_path_service_gateways: A page of
          private path service gateways.
    :param int total_count: The total number of resources across all pages.
    """

    def __init__(
        self,
        first: 'PageLink',
        limit: int,
        private_path_service_gateways: List['PrivatePathServiceGateway'],
        total_count: int,
        *,
        next: Optional['PageLink'] = None,
    ) -> None:
        """
        Initialize a PrivatePathServiceGatewayCollection object.

        :param PageLink 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[PrivatePathServiceGateway] private_path_service_gateways: A
               page of private path service gateways.
        :param int total_count: The total number of resources across all pages.
        :param PageLink 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.private_path_service_gateways = private_path_service_gateways
        self.total_count = total_count

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'PrivatePathServiceGatewayCollection':
        """Initialize a PrivatePathServiceGatewayCollection object from a json dictionary."""
        args = {}
        if (first := _dict.get('first')) is not None:
            args['first'] = PageLink.from_dict(first)
        else:
            raise ValueError('Required property \'first\' not present in PrivatePathServiceGatewayCollection JSON')
        if (limit := _dict.get('limit')) is not None:
            args['limit'] = limit
        else:
            raise ValueError('Required property \'limit\' not present in PrivatePathServiceGatewayCollection JSON')
        if (next := _dict.get('next')) is not None:
            args['next'] = PageLink.from_dict(next)
        if (private_path_service_gateways := _dict.get('private_path_service_gateways')) is not None:
            args['private_path_service_gateways'] = [PrivatePathServiceGateway.from_dict(v) for v in private_path_service_gateways]
        else:
            raise ValueError('Required property \'private_path_service_gateways\' not present in PrivatePathServiceGatewayCollection JSON')
        if (total_count := _dict.get('total_count')) is not None:
            args['total_count'] = total_count
        else:
            raise ValueError('Required property \'total_count\' not present in PrivatePathServiceGatewayCollection JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a PrivatePathServiceGatewayCollection object from 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, 'private_path_service_gateways') and self.private_path_service_gateways is not None:
            private_path_service_gateways_list = []
            for v in self.private_path_service_gateways:
                if isinstance(v, dict):
                    private_path_service_gateways_list.append(v)
                else:
                    private_path_service_gateways_list.append(v.to_dict())
            _dict['private_path_service_gateways'] = private_path_service_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 PrivatePathServiceGatewayCollection object."""
        return json.dumps(self.to_dict(), indent=2)

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

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


class PrivatePathServiceGatewayEndpointGatewayBinding:
    """
    PrivatePathServiceGatewayEndpointGatewayBinding.

    :param AccountReference account: The account that created the endpoint gateway.
    :param datetime created_at: The date and time that the endpoint gateway binding
          was created.
    :param datetime expiration_at: (optional) The expiration date and time for the
          endpoint gateway binding. At binding creation, this property will be set to 14
          days after the creation time, and will remain while the `status` of the binding
          is `pending`. If the date and time are reached while the binding is still
          `pending`, the binding will transition to `expired`.
          This property will be present if the `status` is `pending` or `expired`.
    :param str href: The URL for this endpoint gateway binding.
    :param str id: The unique identifier for this endpoint gateway binding.
    :param str lifecycle_state: The lifecycle state of the endpoint gateway binding.
    :param str resource_type: The resource type.
    :param str status: The status of the endpoint gateway binding:
          - `abandoned`: endpoint gateway binding is inactive, awaiting deletion.
          - `denied`: endpoint gateway binding was denied
          - `expired`: endpoint gateway binding has expired
          - `pending`: endpoint gateway binding is awaiting review
          - `permitted`: endpoint gateway binding was permitted
          An endpoint gateway binding will be automatically deleted when its associated
          endpoint gateway is deleted.
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    """

    def __init__(
        self,
        account: 'AccountReference',
        created_at: datetime,
        href: str,
        id: str,
        lifecycle_state: str,
        resource_type: str,
        status: str,
        *,
        expiration_at: Optional[datetime] = None,
    ) -> None:
        """
        Initialize a PrivatePathServiceGatewayEndpointGatewayBinding object.

        :param AccountReference account: The account that created the endpoint
               gateway.
        :param datetime created_at: The date and time that the endpoint gateway
               binding was created.
        :param str href: The URL for this endpoint gateway binding.
        :param str id: The unique identifier for this endpoint gateway binding.
        :param str lifecycle_state: The lifecycle state of the endpoint gateway
               binding.
        :param str resource_type: The resource type.
        :param str status: The status of the endpoint gateway binding:
               - `abandoned`: endpoint gateway binding is inactive, awaiting deletion.
               - `denied`: endpoint gateway binding was denied
               - `expired`: endpoint gateway binding has expired
               - `pending`: endpoint gateway binding is awaiting review
               - `permitted`: endpoint gateway binding was permitted
               An endpoint gateway binding will be automatically deleted when its
               associated endpoint gateway is deleted.
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :param datetime expiration_at: (optional) The expiration date and time for
               the endpoint gateway binding. At binding creation, this property will be
               set to 14 days after the creation time, and will remain while the `status`
               of the binding is `pending`. If the date and time are reached while the
               binding is still `pending`, the binding will transition to `expired`.
               This property will be present if the `status` is `pending` or `expired`.
        """
        self.account = account
        self.created_at = created_at
        self.expiration_at = expiration_at
        self.href = href
        self.id = id
        self.lifecycle_state = lifecycle_state
        self.resource_type = resource_type
        self.status = status

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'PrivatePathServiceGatewayEndpointGatewayBinding':
        """Initialize a PrivatePathServiceGatewayEndpointGatewayBinding object from a json dictionary."""
        args = {}
        if (account := _dict.get('account')) is not None:
            args['account'] = AccountReference.from_dict(account)
        else:
            raise ValueError('Required property \'account\' not present in PrivatePathServiceGatewayEndpointGatewayBinding JSON')
        if (created_at := _dict.get('created_at')) is not None:
            args['created_at'] = string_to_datetime(created_at)
        else:
            raise ValueError('Required property \'created_at\' not present in PrivatePathServiceGatewayEndpointGatewayBinding JSON')
        if (expiration_at := _dict.get('expiration_at')) is not None:
            args['expiration_at'] = string_to_datetime(expiration_at)
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in PrivatePathServiceGatewayEndpointGatewayBinding JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in PrivatePathServiceGatewayEndpointGatewayBinding JSON')
        if (lifecycle_state := _dict.get('lifecycle_state')) is not None:
            args['lifecycle_state'] = lifecycle_state
        else:
            raise ValueError('Required property \'lifecycle_state\' not present in PrivatePathServiceGatewayEndpointGatewayBinding JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = resource_type
        else:
            raise ValueError('Required property \'resource_type\' not present in PrivatePathServiceGatewayEndpointGatewayBinding JSON')
        if (status := _dict.get('status')) is not None:
            args['status'] = status
        else:
            raise ValueError('Required property \'status\' not present in PrivatePathServiceGatewayEndpointGatewayBinding JSON')
        return cls(**args)

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

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

    def __ne__(self, other: 'PrivatePathServiceGatewayEndpointGatewayBinding') -> 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 endpoint gateway binding.
        """

        DELETING = 'deleting'
        FAILED = 'failed'
        PENDING = 'pending'
        STABLE = 'stable'
        SUSPENDED = 'suspended'
        UPDATING = 'updating'
        WAITING = 'waiting'


    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        PRIVATE_PATH_SERVICE_GATEWAY_ENDPOINT_GATEWAY_BINDING = 'private_path_service_gateway_endpoint_gateway_binding'


    class StatusEnum(str, Enum):
        """
        The status of the endpoint gateway binding:
        - `abandoned`: endpoint gateway binding is inactive, awaiting deletion.
        - `denied`: endpoint gateway binding was denied
        - `expired`: endpoint gateway binding has expired
        - `pending`: endpoint gateway binding is awaiting review
        - `permitted`: endpoint gateway binding was permitted
        An endpoint gateway binding will be automatically deleted when its associated
        endpoint gateway is deleted.
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        ABANDONED = 'abandoned'
        DENIED = 'denied'
        EXPIRED = 'expired'
        PENDING = 'pending'
        PERMITTED = 'permitted'



class PrivatePathServiceGatewayEndpointGatewayBindingCollection:
    """
    PrivatePathServiceGatewayEndpointGatewayBindingCollection.

    :param List[PrivatePathServiceGatewayEndpointGatewayBinding]
          endpoint_gateway_bindings: A page of endpoint gateway bindings for the private
          path service gateway.
    :param PageLink 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 PageLink next: (optional) A link to the next page of resources. This
          property is present for all pages
          except the last page.
    :param int total_count: The total number of resources across all pages.
    """

    def __init__(
        self,
        endpoint_gateway_bindings: List['PrivatePathServiceGatewayEndpointGatewayBinding'],
        first: 'PageLink',
        limit: int,
        total_count: int,
        *,
        next: Optional['PageLink'] = None,
    ) -> None:
        """
        Initialize a PrivatePathServiceGatewayEndpointGatewayBindingCollection object.

        :param List[PrivatePathServiceGatewayEndpointGatewayBinding]
               endpoint_gateway_bindings: A page of endpoint gateway bindings for the
               private path service gateway.
        :param PageLink 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 PageLink next: (optional) A link to the next page of resources. This
               property is present for all pages
               except the last page.
        """
        self.endpoint_gateway_bindings = endpoint_gateway_bindings
        self.first = first
        self.limit = limit
        self.next = next
        self.total_count = total_count

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'PrivatePathServiceGatewayEndpointGatewayBindingCollection':
        """Initialize a PrivatePathServiceGatewayEndpointGatewayBindingCollection object from a json dictionary."""
        args = {}
        if (endpoint_gateway_bindings := _dict.get('endpoint_gateway_bindings')) is not None:
            args['endpoint_gateway_bindings'] = [PrivatePathServiceGatewayEndpointGatewayBinding.from_dict(v) for v in endpoint_gateway_bindings]
        else:
            raise ValueError('Required property \'endpoint_gateway_bindings\' not present in PrivatePathServiceGatewayEndpointGatewayBindingCollection JSON')
        if (first := _dict.get('first')) is not None:
            args['first'] = PageLink.from_dict(first)
        else:
            raise ValueError('Required property \'first\' not present in PrivatePathServiceGatewayEndpointGatewayBindingCollection JSON')
        if (limit := _dict.get('limit')) is not None:
            args['limit'] = limit
        else:
            raise ValueError('Required property \'limit\' not present in PrivatePathServiceGatewayEndpointGatewayBindingCollection JSON')
        if (next := _dict.get('next')) is not None:
            args['next'] = PageLink.from_dict(next)
        if (total_count := _dict.get('total_count')) is not None:
            args['total_count'] = total_count
        else:
            raise ValueError('Required property \'total_count\' not present in PrivatePathServiceGatewayEndpointGatewayBindingCollection JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a PrivatePathServiceGatewayEndpointGatewayBindingCollection object from 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_gateway_bindings') and self.endpoint_gateway_bindings is not None:
            endpoint_gateway_bindings_list = []
            for v in self.endpoint_gateway_bindings:
                if isinstance(v, dict):
                    endpoint_gateway_bindings_list.append(v)
                else:
                    endpoint_gateway_bindings_list.append(v.to_dict())
            _dict['endpoint_gateway_bindings'] = endpoint_gateway_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 PrivatePathServiceGatewayEndpointGatewayBindingCollection object."""
        return json.dumps(self.to_dict(), indent=2)

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

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


class PrivatePathServiceGatewayPatch:
    """
    PrivatePathServiceGatewayPatch.

    :param str default_access_policy: (optional) The policy to use for bindings from
          accounts without an explicit account policy.
    :param LoadBalancerIdentity load_balancer: (optional) The load balancer for this
          private path service gateway. The load balancer must
          have `is_private_path` set to `true`, and must be in the same VPC as the private
          path service gateway.
    :param str name: (optional) The name for this private path service gateway. The
          name must not be used by another private path service gateway in the VPC.
    :param bool zonal_affinity: (optional) Updating the value of `zonal_affinity`
          changes how traffic for existing and future endpoint gateway bindings will be
          routed:
          - `true`:  Traffic to the service from a zone the service resides in will remain
          in
                     that zone.
          - `false`: Traffic to the service from a zone will be load balanced across all
          zones
                     in the region the service resides in.
    """

    def __init__(
        self,
        *,
        default_access_policy: Optional[str] = None,
        load_balancer: Optional['LoadBalancerIdentity'] = None,
        name: Optional[str] = None,
        zonal_affinity: Optional[bool] = None,
    ) -> None:
        """
        Initialize a PrivatePathServiceGatewayPatch object.

        :param str default_access_policy: (optional) The policy to use for bindings
               from accounts without an explicit account policy.
        :param LoadBalancerIdentity load_balancer: (optional) The load balancer for
               this private path service gateway. The load balancer must
               have `is_private_path` set to `true`, and must be in the same VPC as the
               private
               path service gateway.
        :param str name: (optional) The name for this private path service gateway.
               The name must not be used by another private path service gateway in the
               VPC.
        :param bool zonal_affinity: (optional) Updating the value of
               `zonal_affinity` changes how traffic for existing and future endpoint
               gateway bindings will be routed:
               - `true`:  Traffic to the service from a zone the service resides in will
               remain in
                          that zone.
               - `false`: Traffic to the service from a zone will be load balanced across
               all zones
                          in the region the service resides in.
        """
        self.default_access_policy = default_access_policy
        self.load_balancer = load_balancer
        self.name = name
        self.zonal_affinity = zonal_affinity

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'PrivatePathServiceGatewayPatch':
        """Initialize a PrivatePathServiceGatewayPatch object from a json dictionary."""
        args = {}
        if (default_access_policy := _dict.get('default_access_policy')) is not None:
            args['default_access_policy'] = default_access_policy
        if (load_balancer := _dict.get('load_balancer')) is not None:
            args['load_balancer'] = load_balancer
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        if (zonal_affinity := _dict.get('zonal_affinity')) is not None:
            args['zonal_affinity'] = zonal_affinity
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a PrivatePathServiceGatewayPatch object from 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_access_policy') and self.default_access_policy is not None:
            _dict['default_access_policy'] = self.default_access_policy
        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, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'zonal_affinity') and self.zonal_affinity is not None:
            _dict['zonal_affinity'] = self.zonal_affinity
        return _dict

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

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

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

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

    class DefaultAccessPolicyEnum(str, Enum):
        """
        The policy to use for bindings from accounts without an explicit account policy.
        """

        DENY = 'deny'
        PERMIT = 'permit'
        REVIEW = 'review'



class PrivatePathServiceGatewayRemote:
    """
    If present, this property indicates that the resource associated with this reference
    is remote and therefore may not be directly retrievable.

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

    def __init__(
        self,
        *,
        account: Optional['AccountReference'] = None,
        region: Optional['RegionReference'] = None,
    ) -> None:
        """
        Initialize a PrivatePathServiceGatewayRemote 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) -> 'PrivatePathServiceGatewayRemote':
        """Initialize a PrivatePathServiceGatewayRemote object from a json dictionary."""
        args = {}
        if (account := _dict.get('account')) is not None:
            args['account'] = AccountReference.from_dict(account)
        if (region := _dict.get('region')) is not None:
            args['region'] = RegionReference.from_dict(region)
        return cls(**args)

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

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

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


class PublicGateway:
    """
    PublicGateway.

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

    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 := _dict.get('created_at')) is not None:
            args['created_at'] = string_to_datetime(created_at)
        else:
            raise ValueError('Required property \'created_at\' not present in PublicGateway JSON')
        if (crn := _dict.get('crn')) is not None:
            args['crn'] = crn
        else:
            raise ValueError('Required property \'crn\' not present in PublicGateway JSON')
        if (floating_ip := _dict.get('floating_ip')) is not None:
            args['floating_ip'] = PublicGatewayFloatingIp.from_dict(floating_ip)
        else:
            raise ValueError('Required property \'floating_ip\' not present in PublicGateway JSON')
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in PublicGateway JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in PublicGateway JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in PublicGateway JSON')
        if (resource_group := _dict.get('resource_group')) is not None:
            args['resource_group'] = ResourceGroupReference.from_dict(resource_group)
        else:
            raise ValueError('Required property \'resource_group\' not present in PublicGateway JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = resource_type
        else:
            raise ValueError('Required property \'resource_type\' not present in PublicGateway JSON')
        if (status := _dict.get('status')) is not None:
            args['status'] = status
        else:
            raise ValueError('Required property \'status\' not present in PublicGateway JSON')
        if (vpc := _dict.get('vpc')) is not None:
            args['vpc'] = VPCReference.from_dict(vpc)
        else:
            raise ValueError('Required property \'vpc\' not present in PublicGateway JSON')
        if (zone := _dict.get('zone')) is not None:
            args['zone'] = ZoneReference.from_dict(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.

    :param PageLink 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 PageLink next: (optional) A link to the next page of resources. This
          property is present for all pages
          except the last page.
    :param List[PublicGateway] public_gateways: A page of public gateways.
    :param int total_count: The total number of resources across all pages.
    """

    def __init__(
        self,
        first: 'PageLink',
        limit: int,
        public_gateways: List['PublicGateway'],
        total_count: int,
        *,
        next: Optional['PageLink'] = None,
    ) -> None:
        """
        Initialize a PublicGatewayCollection object.

        :param PageLink 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: A page of public gateways.
        :param int total_count: The total number of resources across all pages.
        :param PageLink 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 := _dict.get('first')) is not None:
            args['first'] = PageLink.from_dict(first)
        else:
            raise ValueError('Required property \'first\' not present in PublicGatewayCollection JSON')
        if (limit := _dict.get('limit')) is not None:
            args['limit'] = limit
        else:
            raise ValueError('Required property \'limit\' not present in PublicGatewayCollection JSON')
        if (next := _dict.get('next')) is not None:
            args['next'] = PageLink.from_dict(next)
        if (public_gateways := _dict.get('public_gateways')) is not None:
            args['public_gateways'] = [PublicGateway.from_dict(v) for v in public_gateways]
        else:
            raise ValueError('Required property \'public_gateways\' not present in PublicGatewayCollection JSON')
        if (total_count := _dict.get('total_count')) is not None:
            args['total_count'] = 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 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.

    :param str address: The globally unique IP address.
    :param str crn: The CRN for this floating IP.
    :param Deleted deleted: (optional) If present, this property indicates the
          referenced resource has been deleted, and provides
          some supplementary information.
    :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.
    """

    def __init__(
        self,
        address: str,
        crn: str,
        href: str,
        id: str,
        name: str,
        *,
        deleted: Optional['Deleted'] = 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 Deleted 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 := _dict.get('address')) is not None:
            args['address'] = address
        else:
            raise ValueError('Required property \'address\' not present in PublicGatewayFloatingIp JSON')
        if (crn := _dict.get('crn')) is not None:
            args['crn'] = crn
        else:
            raise ValueError('Required property \'crn\' not present in PublicGatewayFloatingIp JSON')
        if (deleted := _dict.get('deleted')) is not None:
            args['deleted'] = Deleted.from_dict(deleted)
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in PublicGatewayFloatingIp JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in PublicGatewayFloatingIp JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = 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.

    :param 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: Optional[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 := _dict.get('name')) is not None:
            args['name'] = 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.

    :param str crn: The CRN for this public gateway.
    :param Deleted deleted: (optional) If present, this property indicates the
          referenced resource has been deleted, and provides
          some supplementary information.
    :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.
    """

    def __init__(
        self,
        crn: str,
        href: str,
        id: str,
        name: str,
        resource_type: str,
        *,
        deleted: Optional['Deleted'] = 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 Deleted 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 := _dict.get('crn')) is not None:
            args['crn'] = crn
        else:
            raise ValueError('Required property \'crn\' not present in PublicGatewayReference JSON')
        if (deleted := _dict.get('deleted')) is not None:
            args['deleted'] = Deleted.from_dict(deleted)
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in PublicGatewayReference JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in PublicGatewayReference JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in PublicGatewayReference JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = 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 Region:
    """
    Region.

    :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.
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    """

    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.
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        """
        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 := _dict.get('endpoint')) is not None:
            args['endpoint'] = endpoint
        else:
            raise ValueError('Required property \'endpoint\' not present in Region JSON')
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in Region JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in Region JSON')
        if (status := _dict.get('status')) is not None:
            args['status'] = 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.
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        AVAILABLE = 'available'
        UNAVAILABLE = 'unavailable'



class RegionCollection:
    """
    RegionCollection.

    :param List[Region] regions: The regions for the account.
    """

    def __init__(
        self,
        regions: List['Region'],
    ) -> None:
        """
        Initialize a RegionCollection object.

        :param List[Region] regions: The regions for the account.
        """
        self.regions = regions

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'RegionCollection':
        """Initialize a RegionCollection object from a json dictionary."""
        args = {}
        if (regions := _dict.get('regions')) is not None:
            args['regions'] = [Region.from_dict(v) for v in 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.

    :param str href: The URL for this region.
    :param 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 := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in RegionReference JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = 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 Reservation:
    """
    Reservation.

    :param str affinity_policy: The affinity policy to use for this reservation:
          - `restricted`: The reservation must be manually requested
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :param ReservationCapacity capacity: (optional) The capacity configuration for
          this reservation
          If absent, this reservation has no assigned capacity.
    :param ReservationCommittedUse committed_use: (optional) The committed use
          configuration for this reservation.
          If absent, this reservation has no commitment for use.
    :param datetime created_at: The date and time that the reservation was created.
    :param str crn: The CRN for this reservation.
    :param str href: The URL for this reservation.
    :param str id: The unique identifier for this reservation.
    :param str lifecycle_state: The lifecycle state of this reservation.
    :param str name: The name for this reservation. The name is unique across all
          reservations in the region.
    :param ReservationProfile profile: The
          [profile](https://cloud.ibm.com/docs/vpc?topic=vpc-profiles) for this
          reservation.
    :param ResourceGroupReference resource_group: The resource group for this
          reservation.
    :param str resource_type: The resource type.
    :param str status: The status of the reservation.
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :param List[ReservationStatusReason] status_reasons: The reasons for the current
          status (if any).
    :param ZoneReference zone: The zone for this reservation.
    """

    def __init__(
        self,
        affinity_policy: str,
        created_at: datetime,
        crn: str,
        href: str,
        id: str,
        lifecycle_state: str,
        name: str,
        profile: 'ReservationProfile',
        resource_group: 'ResourceGroupReference',
        resource_type: str,
        status: str,
        status_reasons: List['ReservationStatusReason'],
        zone: 'ZoneReference',
        *,
        capacity: Optional['ReservationCapacity'] = None,
        committed_use: Optional['ReservationCommittedUse'] = None,
    ) -> None:
        """
        Initialize a Reservation object.

        :param str affinity_policy: The affinity policy to use for this
               reservation:
               - `restricted`: The reservation must be manually requested
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :param datetime created_at: The date and time that the reservation was
               created.
        :param str crn: The CRN for this reservation.
        :param str href: The URL for this reservation.
        :param str id: The unique identifier for this reservation.
        :param str lifecycle_state: The lifecycle state of this reservation.
        :param str name: The name for this reservation. The name is unique across
               all reservations in the region.
        :param ReservationProfile profile: The
               [profile](https://cloud.ibm.com/docs/vpc?topic=vpc-profiles) for this
               reservation.
        :param ResourceGroupReference resource_group: The resource group for this
               reservation.
        :param str resource_type: The resource type.
        :param str status: The status of the reservation.
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :param List[ReservationStatusReason] status_reasons: The reasons for the
               current status (if any).
        :param ZoneReference zone: The zone for this reservation.
        :param ReservationCapacity capacity: (optional) The capacity configuration
               for this reservation
               If absent, this reservation has no assigned capacity.
        :param ReservationCommittedUse committed_use: (optional) The committed use
               configuration for this reservation.
               If absent, this reservation has no commitment for use.
        """
        self.affinity_policy = affinity_policy
        self.capacity = capacity
        self.committed_use = committed_use
        self.created_at = created_at
        self.crn = crn
        self.href = href
        self.id = id
        self.lifecycle_state = lifecycle_state
        self.name = name
        self.profile = profile
        self.resource_group = resource_group
        self.resource_type = resource_type
        self.status = status
        self.status_reasons = status_reasons
        self.zone = zone

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'Reservation':
        """Initialize a Reservation object from a json dictionary."""
        args = {}
        if (affinity_policy := _dict.get('affinity_policy')) is not None:
            args['affinity_policy'] = affinity_policy
        else:
            raise ValueError('Required property \'affinity_policy\' not present in Reservation JSON')
        if (capacity := _dict.get('capacity')) is not None:
            args['capacity'] = ReservationCapacity.from_dict(capacity)
        if (committed_use := _dict.get('committed_use')) is not None:
            args['committed_use'] = ReservationCommittedUse.from_dict(committed_use)
        if (created_at := _dict.get('created_at')) is not None:
            args['created_at'] = string_to_datetime(created_at)
        else:
            raise ValueError('Required property \'created_at\' not present in Reservation JSON')
        if (crn := _dict.get('crn')) is not None:
            args['crn'] = crn
        else:
            raise ValueError('Required property \'crn\' not present in Reservation JSON')
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in Reservation JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in Reservation JSON')
        if (lifecycle_state := _dict.get('lifecycle_state')) is not None:
            args['lifecycle_state'] = lifecycle_state
        else:
            raise ValueError('Required property \'lifecycle_state\' not present in Reservation JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in Reservation JSON')
        if (profile := _dict.get('profile')) is not None:
            args['profile'] = ReservationProfile.from_dict(profile)
        else:
            raise ValueError('Required property \'profile\' not present in Reservation JSON')
        if (resource_group := _dict.get('resource_group')) is not None:
            args['resource_group'] = ResourceGroupReference.from_dict(resource_group)
        else:
            raise ValueError('Required property \'resource_group\' not present in Reservation JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = resource_type
        else:
            raise ValueError('Required property \'resource_type\' not present in Reservation JSON')
        if (status := _dict.get('status')) is not None:
            args['status'] = status
        else:
            raise ValueError('Required property \'status\' not present in Reservation JSON')
        if (status_reasons := _dict.get('status_reasons')) is not None:
            args['status_reasons'] = [ReservationStatusReason.from_dict(v) for v in status_reasons]
        else:
            raise ValueError('Required property \'status_reasons\' not present in Reservation JSON')
        if (zone := _dict.get('zone')) is not None:
            args['zone'] = ZoneReference.from_dict(zone)
        else:
            raise ValueError('Required property \'zone\' not present in Reservation JSON')
        return cls(**args)

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

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'affinity_policy') and self.affinity_policy is not None:
            _dict['affinity_policy'] = self.affinity_policy
        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, 'committed_use') and self.committed_use is not None:
            if isinstance(self.committed_use, dict):
                _dict['committed_use'] = self.committed_use
            else:
                _dict['committed_use'] = self.committed_use.to_dict()
        if hasattr(self, 'created_at') and self.created_at is not None:
            _dict['created_at'] = datetime_to_string(self.created_at)
        if hasattr(self, 'crn') and self.crn is not None:
            _dict['crn'] = self.crn
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, '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, '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, '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 Reservation object."""
        return json.dumps(self.to_dict(), indent=2)

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

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

    class AffinityPolicyEnum(str, Enum):
        """
        The affinity policy to use for this reservation:
        - `restricted`: The reservation must be manually requested
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        RESTRICTED = 'restricted'


    class LifecycleStateEnum(str, Enum):
        """
        The lifecycle state of this reservation.
        """

        DELETING = 'deleting'
        FAILED = 'failed'
        PENDING = 'pending'
        STABLE = 'stable'
        SUSPENDED = 'suspended'
        UPDATING = 'updating'
        WAITING = 'waiting'


    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        RESERVATION = 'reservation'


    class StatusEnum(str, Enum):
        """
        The status of the reservation.
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        ACTIVATING = 'activating'
        ACTIVE = 'active'
        DEACTIVATING = 'deactivating'
        EXPIRED = 'expired'
        FAILED = 'failed'
        INACTIVE = 'inactive'



class ReservationCapacity:
    """
    The capacity configuration for this reservation
    If absent, this reservation has no assigned capacity.

    :param int allocated: The amount allocated to this capacity reservation.
    :param int available: The amount of this capacity reservation available for new
          attachments.
    :param str status: The status of the capacity reservation:
          - `allocating`: The capacity reservation is being allocated for use
          - `allocated`: The total capacity of the reservation has been allocated for use
          - `degraded`: The capacity reservation has been allocated for use, but some of
          the
            capacity is not available. See [capacity status
          reasons](https://cloud.ibm.com/docs/vpc?topic=vpc-reserved-capacity-status-reasons)
            for more information.
          - `unallocated`: The capacity reservation is not allocated for use
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :param int total: The total amount of this capacity reservation.
    :param int used: The amount of this capacity reservation used by existing
          attachments.
    """

    def __init__(
        self,
        allocated: int,
        available: int,
        status: str,
        total: int,
        used: int,
    ) -> None:
        """
        Initialize a ReservationCapacity object.

        :param int allocated: The amount allocated to this capacity reservation.
        :param int available: The amount of this capacity reservation available for
               new attachments.
        :param str status: The status of the capacity reservation:
               - `allocating`: The capacity reservation is being allocated for use
               - `allocated`: The total capacity of the reservation has been allocated for
               use
               - `degraded`: The capacity reservation has been allocated for use, but some
               of the
                 capacity is not available. See [capacity status
               reasons](https://cloud.ibm.com/docs/vpc?topic=vpc-reserved-capacity-status-reasons)
                 for more information.
               - `unallocated`: The capacity reservation is not allocated for use
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :param int total: The total amount of this capacity reservation.
        :param int used: The amount of this capacity reservation used by existing
               attachments.
        """
        self.allocated = allocated
        self.available = available
        self.status = status
        self.total = total
        self.used = used

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

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

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

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

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

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

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

    class StatusEnum(str, Enum):
        """
        The status of the capacity reservation:
        - `allocating`: The capacity reservation is being allocated for use
        - `allocated`: The total capacity of the reservation has been allocated for use
        - `degraded`: The capacity reservation has been allocated for use, but some of the
          capacity is not available. See [capacity status
        reasons](https://cloud.ibm.com/docs/vpc?topic=vpc-reserved-capacity-status-reasons)
          for more information.
        - `unallocated`: The capacity reservation is not allocated for use
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        ALLOCATED = 'allocated'
        ALLOCATING = 'allocating'
        DEGRADED = 'degraded'
        UNALLOCATED = 'unallocated'



class ReservationCapacityPatch:
    """
    The capacity reservation configuration to use.
    The configuration can only be changed for reservations with a `status` of `inactive`.

    :param int total: (optional) The total amount to use for this capacity
          reservation.
    """

    def __init__(
        self,
        *,
        total: Optional[int] = None,
    ) -> None:
        """
        Initialize a ReservationCapacityPatch object.

        :param int total: (optional) The total amount to use for this capacity
               reservation.
        """
        self.total = total

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

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

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

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

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

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

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


class ReservationCapacityPrototype:
    """
    The capacity reservation configuration to use.

    :param int total: The total amount to use for this capacity reservation.
    """

    def __init__(
        self,
        total: int,
    ) -> None:
        """
        Initialize a ReservationCapacityPrototype object.

        :param int total: The total amount to use for this capacity reservation.
        """
        self.total = total

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

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

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

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

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

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

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


class ReservationCollection:
    """
    ReservationCollection.

    :param PageLink 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 PageLink next: (optional) A link to the next page of resources. This
          property is present for all pages
          except the last page.
    :param List[Reservation] reservations: A page of reservations.
    :param int total_count: The total number of resources across all pages.
    """

    def __init__(
        self,
        first: 'PageLink',
        limit: int,
        reservations: List['Reservation'],
        total_count: int,
        *,
        next: Optional['PageLink'] = None,
    ) -> None:
        """
        Initialize a ReservationCollection object.

        :param PageLink 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[Reservation] reservations: A page of reservations.
        :param int total_count: The total number of resources across all pages.
        :param PageLink 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.reservations = reservations
        self.total_count = total_count

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ReservationCollection':
        """Initialize a ReservationCollection object from a json dictionary."""
        args = {}
        if (first := _dict.get('first')) is not None:
            args['first'] = PageLink.from_dict(first)
        else:
            raise ValueError('Required property \'first\' not present in ReservationCollection JSON')
        if (limit := _dict.get('limit')) is not None:
            args['limit'] = limit
        else:
            raise ValueError('Required property \'limit\' not present in ReservationCollection JSON')
        if (next := _dict.get('next')) is not None:
            args['next'] = PageLink.from_dict(next)
        if (reservations := _dict.get('reservations')) is not None:
            args['reservations'] = [Reservation.from_dict(v) for v in reservations]
        else:
            raise ValueError('Required property \'reservations\' not present in ReservationCollection JSON')
        if (total_count := _dict.get('total_count')) is not None:
            args['total_count'] = total_count
        else:
            raise ValueError('Required property \'total_count\' not present in ReservationCollection JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ReservationCollection object from 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, 'reservations') and self.reservations is not None:
            reservations_list = []
            for v in self.reservations:
                if isinstance(v, dict):
                    reservations_list.append(v)
                else:
                    reservations_list.append(v.to_dict())
            _dict['reservations'] = reservations_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 ReservationCollection object."""
        return json.dumps(self.to_dict(), indent=2)

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

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


class ReservationCommittedUse:
    """
    The committed use reservation configuration.

    :param datetime expiration_at: (optional) The expiration date and time for this
          committed use reservation.
          This property will be absent if the reservation has a `status` of `inactive`.
    :param str expiration_policy: The policy to apply when the committed use term
          expires:
          - `release`: Release any available capacity and let the reservation expire.
          - `renew`: Renew for another term, provided the term remains listed in the
            `reservation_terms` for the profile. Otherwise, let the reservation expire.
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :param str term: The term for this committed use reservation:
          - `one_year`: 1 year
          - `three_year`: 3 years
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    """

    def __init__(
        self,
        expiration_policy: str,
        term: str,
        *,
        expiration_at: Optional[datetime] = None,
    ) -> None:
        """
        Initialize a ReservationCommittedUse object.

        :param str expiration_policy: The policy to apply when the committed use
               term expires:
               - `release`: Release any available capacity and let the reservation expire.
               - `renew`: Renew for another term, provided the term remains listed in the
                 `reservation_terms` for the profile. Otherwise, let the reservation
               expire.
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :param str term: The term for this committed use reservation:
               - `one_year`: 1 year
               - `three_year`: 3 years
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :param datetime expiration_at: (optional) The expiration date and time for
               this committed use reservation.
               This property will be absent if the reservation has a `status` of
               `inactive`.
        """
        self.expiration_at = expiration_at
        self.expiration_policy = expiration_policy
        self.term = term

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

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

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

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

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

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

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

    class ExpirationPolicyEnum(str, Enum):
        """
        The policy to apply when the committed use term expires:
        - `release`: Release any available capacity and let the reservation expire.
        - `renew`: Renew for another term, provided the term remains listed in the
          `reservation_terms` for the profile. Otherwise, let the reservation expire.
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        RELEASE = 'release'
        RENEW = 'renew'



class ReservationCommittedUsePatch:
    """
    ReservationCommittedUsePatch.

    :param str expiration_policy: (optional) The policy to apply when the committed
          use term expires:
          - `release`: Release any available capacity and let the reservation expire.
          - `renew`: Renew for another term, provided the term remains listed in the
            `reservation_terms` for the profile. Otherwise, let the reservation expire.
    :param str term: (optional) The term for this committed use reservation:
          - `one_year`: 1 year
          - `three_year`: 3 years
          The specified value must be listed in the `reservation_terms` in the profile for
          this reservation. The term can only be changed for a reservation with a `status`
          of
          `inactive`.
    """

    def __init__(
        self,
        *,
        expiration_policy: Optional[str] = None,
        term: Optional[str] = None,
    ) -> None:
        """
        Initialize a ReservationCommittedUsePatch object.

        :param str expiration_policy: (optional) The policy to apply when the
               committed use term expires:
               - `release`: Release any available capacity and let the reservation expire.
               - `renew`: Renew for another term, provided the term remains listed in the
                 `reservation_terms` for the profile. Otherwise, let the reservation
               expire.
        :param str term: (optional) The term for this committed use reservation:
               - `one_year`: 1 year
               - `three_year`: 3 years
               The specified value must be listed in the `reservation_terms` in the
               profile for this reservation. The term can only be changed for a
               reservation with a `status` of
               `inactive`.
        """
        self.expiration_policy = expiration_policy
        self.term = term

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ReservationCommittedUsePatch':
        """Initialize a ReservationCommittedUsePatch object from a json dictionary."""
        args = {}
        if (expiration_policy := _dict.get('expiration_policy')) is not None:
            args['expiration_policy'] = expiration_policy
        if (term := _dict.get('term')) is not None:
            args['term'] = term
        return cls(**args)

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

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

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

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

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

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

    class ExpirationPolicyEnum(str, Enum):
        """
        The policy to apply when the committed use term expires:
        - `release`: Release any available capacity and let the reservation expire.
        - `renew`: Renew for another term, provided the term remains listed in the
          `reservation_terms` for the profile. Otherwise, let the reservation expire.
        """

        RELEASE = 'release'
        RENEW = 'renew'



class ReservationCommittedUsePrototype:
    """
    ReservationCommittedUsePrototype.

    :param str expiration_policy: (optional) The policy to apply when the committed
          use term expires:
          - `release`: Release any available capacity and let the reservation expire.
          - `renew`: Renew for another term, provided the term remains listed in the
            `reservation_terms` for the profile. Otherwise, let the reservation expire.
    :param str term: The term for this committed use reservation:
          - `one_year`: 1 year
          - `three_year`: 3 years
          The specified value must be listed in the `reservation_terms` in the profile for
          this reservation.
    """

    def __init__(
        self,
        term: str,
        *,
        expiration_policy: Optional[str] = None,
    ) -> None:
        """
        Initialize a ReservationCommittedUsePrototype object.

        :param str term: The term for this committed use reservation:
               - `one_year`: 1 year
               - `three_year`: 3 years
               The specified value must be listed in the `reservation_terms` in the
               profile for this reservation.
        :param str expiration_policy: (optional) The policy to apply when the
               committed use term expires:
               - `release`: Release any available capacity and let the reservation expire.
               - `renew`: Renew for another term, provided the term remains listed in the
                 `reservation_terms` for the profile. Otherwise, let the reservation
               expire.
        """
        self.expiration_policy = expiration_policy
        self.term = term

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

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

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

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

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

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

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

    class ExpirationPolicyEnum(str, Enum):
        """
        The policy to apply when the committed use term expires:
        - `release`: Release any available capacity and let the reservation expire.
        - `renew`: Renew for another term, provided the term remains listed in the
          `reservation_terms` for the profile. Otherwise, let the reservation expire.
        """

        RELEASE = 'release'
        RENEW = 'renew'



class ReservationIdentity:
    """
    Identifies a reservation by a unique property.

    """

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

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


class ReservationPatch:
    """
    ReservationPatch.

    :param ReservationCapacityPatch capacity: (optional) The capacity reservation
          configuration to use.
          The configuration can only be changed for reservations with a `status` of
          `inactive`.
    :param ReservationCommittedUsePatch committed_use: (optional) The committed use
          configuration to use for this reservation.
    :param str name: (optional) The name for this reservation. The name must not be
          used by another reservation in the region.
    :param ReservationProfilePatch profile: (optional) The
          [profile](https://cloud.ibm.com/docs/vpc?topic=vpc-profiles) to use for this
          reservation.
    """

    def __init__(
        self,
        *,
        capacity: Optional['ReservationCapacityPatch'] = None,
        committed_use: Optional['ReservationCommittedUsePatch'] = None,
        name: Optional[str] = None,
        profile: Optional['ReservationProfilePatch'] = None,
    ) -> None:
        """
        Initialize a ReservationPatch object.

        :param ReservationCapacityPatch capacity: (optional) The capacity
               reservation configuration to use.
               The configuration can only be changed for reservations with a `status` of
               `inactive`.
        :param ReservationCommittedUsePatch committed_use: (optional) The committed
               use configuration to use for this reservation.
        :param str name: (optional) The name for this reservation. The name must
               not be used by another reservation in the region.
        :param ReservationProfilePatch profile: (optional) The
               [profile](https://cloud.ibm.com/docs/vpc?topic=vpc-profiles) to use for
               this
               reservation.
        """
        self.capacity = capacity
        self.committed_use = committed_use
        self.name = name
        self.profile = profile

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ReservationPatch':
        """Initialize a ReservationPatch object from a json dictionary."""
        args = {}
        if (capacity := _dict.get('capacity')) is not None:
            args['capacity'] = ReservationCapacityPatch.from_dict(capacity)
        if (committed_use := _dict.get('committed_use')) is not None:
            args['committed_use'] = ReservationCommittedUsePatch.from_dict(committed_use)
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        if (profile := _dict.get('profile')) is not None:
            args['profile'] = ReservationProfilePatch.from_dict(profile)
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ReservationPatch object from 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, 'committed_use') and self.committed_use is not None:
            if isinstance(self.committed_use, dict):
                _dict['committed_use'] = self.committed_use
            else:
                _dict['committed_use'] = self.committed_use.to_dict()
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'profile') and self.profile is not None:
            if isinstance(self.profile, dict):
                _dict['profile'] = self.profile
            else:
                _dict['profile'] = self.profile.to_dict()
        return _dict

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

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

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

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


class ReservationProfile:
    """
    The [profile](https://cloud.ibm.com/docs/vpc?topic=vpc-profiles) for this reservation.

    :param str href: The URL for this virtual server instance profile.
    :param str name: The globally unique name for this virtual server instance
          profile.
    :param str resource_type: The resource type.
    """

    def __init__(
        self,
        href: str,
        name: str,
        resource_type: str,
    ) -> None:
        """
        Initialize a ReservationProfile 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.
        :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) -> 'ReservationProfile':
        """Initialize a ReservationProfile object from a json dictionary."""
        args = {}
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in ReservationProfile JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in ReservationProfile JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = resource_type
        else:
            raise ValueError('Required property \'resource_type\' not present in ReservationProfile JSON')
        return cls(**args)

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

    def to_dict(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 ReservationProfile object."""
        return json.dumps(self.to_dict(), indent=2)

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

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

    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        INSTANCE_PROFILE = 'instance_profile'



class ReservationProfilePatch:
    """
    The [profile](https://cloud.ibm.com/docs/vpc?topic=vpc-profiles) to use for this
    reservation.

    :param str name: (optional) The globally unique name of the profile.
    :param str resource_type: (optional) The resource type of the profile.
    """

    def __init__(
        self,
        *,
        name: Optional[str] = None,
        resource_type: Optional[str] = None,
    ) -> None:
        """
        Initialize a ReservationProfilePatch object.

        :param str name: (optional) The globally unique name of the profile.
        :param str resource_type: (optional) The resource type of the profile.
        """
        self.name = name
        self.resource_type = resource_type

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

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

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

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

    class ResourceTypeEnum(str, Enum):
        """
        The resource type of the profile.
        """

        INSTANCE_PROFILE = 'instance_profile'



class ReservationProfilePrototype:
    """
    The [profile](https://cloud.ibm.com/docs/vpc?topic=vpc-profiles) to use for this
    reservation.

    :param str name: The globally unique name of the profile.
    :param str resource_type: The resource type of the profile.
    """

    def __init__(
        self,
        name: str,
        resource_type: str,
    ) -> None:
        """
        Initialize a ReservationProfilePrototype object.

        :param str name: The globally unique name of the profile.
        :param str resource_type: The resource type of the profile.
        """
        self.name = name
        self.resource_type = resource_type

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

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

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

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

    class ResourceTypeEnum(str, Enum):
        """
        The resource type of the profile.
        """

        INSTANCE_PROFILE = 'instance_profile'



class ReservationReference:
    """
    ReservationReference.

    :param str crn: The CRN for this reservation.
    :param Deleted deleted: (optional) If present, this property indicates the
          referenced resource has been deleted, and provides
          some supplementary information.
    :param str href: The URL for this reservation.
    :param str id: The unique identifier for this reservation.
    :param str name: The name for this reservation. The name is unique across all
          reservations in the region.
    :param str resource_type: The resource type.
    """

    def __init__(
        self,
        crn: str,
        href: str,
        id: str,
        name: str,
        resource_type: str,
        *,
        deleted: Optional['Deleted'] = None,
    ) -> None:
        """
        Initialize a ReservationReference object.

        :param str crn: The CRN for this reservation.
        :param str href: The URL for this reservation.
        :param str id: The unique identifier for this reservation.
        :param str name: The name for this reservation. The name is unique across
               all reservations in the region.
        :param str resource_type: The resource type.
        :param Deleted 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) -> 'ReservationReference':
        """Initialize a ReservationReference object from a json dictionary."""
        args = {}
        if (crn := _dict.get('crn')) is not None:
            args['crn'] = crn
        else:
            raise ValueError('Required property \'crn\' not present in ReservationReference JSON')
        if (deleted := _dict.get('deleted')) is not None:
            args['deleted'] = Deleted.from_dict(deleted)
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in ReservationReference JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in ReservationReference JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in ReservationReference JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = resource_type
        else:
            raise ValueError('Required property \'resource_type\' not present in ReservationReference JSON')
        return cls(**args)

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

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

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

    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        RESERVATION = 'reservation'



class ReservationStatusReason:
    """
    ReservationStatusReason.

    :param str code: A snake case string succinctly identifying the status reason.
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :param str message: An explanation of the status reason.
    :param str more_info: (optional) Link to documentation about this status reason.
    """

    def __init__(
        self,
        code: str,
        message: str,
        *,
        more_info: Optional[str] = None,
    ) -> None:
        """
        Initialize a ReservationStatusReason object.

        :param str code: A snake case string succinctly identifying the status
               reason.
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :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) -> 'ReservationStatusReason':
        """Initialize a ReservationStatusReason object from a json dictionary."""
        args = {}
        if (code := _dict.get('code')) is not None:
            args['code'] = code
        else:
            raise ValueError('Required property \'code\' not present in ReservationStatusReason JSON')
        if (message := _dict.get('message')) is not None:
            args['message'] = message
        else:
            raise ValueError('Required property \'message\' not present in ReservationStatusReason JSON')
        if (more_info := _dict.get('more_info')) is not None:
            args['more_info'] = more_info
        return cls(**args)

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

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

    def __ne__(self, other: 'ReservationStatusReason') -> 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.
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        CANNOT_ACTIVATE_NO_CAPACITY_AVAILABLE = 'cannot_activate_no_capacity_available'
        CANNOT_RENEW_UNSUPPORTED_PROFILE_TERM = 'cannot_renew_unsupported_profile_term'



class ReservedIP:
    """
    ReservedIP.

    :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
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) to support
          IPv6 addresses in the future.
    :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.
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :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.
          The resources supported by this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    """

    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: Optional['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
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) to
               support IPv6 addresses in the future.
        :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.
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :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.
               The resources supported by this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        """
        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 := _dict.get('address')) is not None:
            args['address'] = address
        else:
            raise ValueError('Required property \'address\' not present in ReservedIP JSON')
        if (auto_delete := _dict.get('auto_delete')) is not None:
            args['auto_delete'] = auto_delete
        else:
            raise ValueError('Required property \'auto_delete\' not present in ReservedIP JSON')
        if (created_at := _dict.get('created_at')) is not None:
            args['created_at'] = string_to_datetime(created_at)
        else:
            raise ValueError('Required property \'created_at\' not present in ReservedIP JSON')
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in ReservedIP JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in ReservedIP JSON')
        if (lifecycle_state := _dict.get('lifecycle_state')) is not None:
            args['lifecycle_state'] = lifecycle_state
        else:
            raise ValueError('Required property \'lifecycle_state\' not present in ReservedIP JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in ReservedIP JSON')
        if (owner := _dict.get('owner')) is not None:
            args['owner'] = owner
        else:
            raise ValueError('Required property \'owner\' not present in ReservedIP JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = resource_type
        else:
            raise ValueError('Required property \'resource_type\' not present in ReservedIP JSON')
        if (target := _dict.get('target')) is not None:
            args['target'] = 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.
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        PROVIDER = 'provider'
        USER = 'user'


    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        SUBNET_RESERVED_IP = 'subnet_reserved_ip'



class ReservedIPCollection:
    """
    ReservedIPCollection.

    :param PageLink 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 PageLink next: (optional) A link to the next page of resources. This
          property is present for all pages
          except the last page.
    :param List[ReservedIP] reserved_ips: A page of reserved IPs in the subnet.
    :param int total_count: The total number of resources across all pages.
    """

    def __init__(
        self,
        first: 'PageLink',
        limit: int,
        reserved_ips: List['ReservedIP'],
        total_count: int,
        *,
        next: Optional['PageLink'] = None,
    ) -> None:
        """
        Initialize a ReservedIPCollection object.

        :param PageLink 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: A page of reserved IPs in the subnet.
        :param int total_count: The total number of resources across all pages.
        :param PageLink 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 := _dict.get('first')) is not None:
            args['first'] = PageLink.from_dict(first)
        else:
            raise ValueError('Required property \'first\' not present in ReservedIPCollection JSON')
        if (limit := _dict.get('limit')) is not None:
            args['limit'] = limit
        else:
            raise ValueError('Required property \'limit\' not present in ReservedIPCollection JSON')
        if (next := _dict.get('next')) is not None:
            args['next'] = PageLink.from_dict(next)
        if (reserved_ips := _dict.get('reserved_ips')) is not None:
            args['reserved_ips'] = [ReservedIP.from_dict(v) for v in reserved_ips]
        else:
            raise ValueError('Required property \'reserved_ips\' not present in ReservedIPCollection JSON')
        if (total_count := _dict.get('total_count')) is not None:
            args['total_count'] = 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.

    :param PageLink first: A link to the first page of resources.
    :param List[ReservedIP] ips: A page of reserved IPs bound to the bare metal
          server network interface.
    :param int limit: The maximum number of resources that can be returned by the
          request.
    :param PageLink next: (optional) A link to the next page of resources. This
          property is present for all pages
          except the last page.
    :param int total_count: The total number of resources across all pages.
    """

    def __init__(
        self,
        first: 'PageLink',
        ips: List['ReservedIP'],
        limit: int,
        total_count: int,
        *,
        next: Optional['PageLink'] = None,
    ) -> None:
        """
        Initialize a ReservedIPCollectionBareMetalServerNetworkInterfaceContext object.

        :param PageLink first: A link to the first page of resources.
        :param List[ReservedIP] ips: A page of reserved IPs bound to the 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 PageLink 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 := _dict.get('first')) is not None:
            args['first'] = PageLink.from_dict(first)
        else:
            raise ValueError('Required property \'first\' not present in ReservedIPCollectionBareMetalServerNetworkInterfaceContext JSON')
        if (ips := _dict.get('ips')) is not None:
            args['ips'] = [ReservedIP.from_dict(v) for v in ips]
        else:
            raise ValueError('Required property \'ips\' not present in ReservedIPCollectionBareMetalServerNetworkInterfaceContext JSON')
        if (limit := _dict.get('limit')) is not None:
            args['limit'] = limit
        else:
            raise ValueError('Required property \'limit\' not present in ReservedIPCollectionBareMetalServerNetworkInterfaceContext JSON')
        if (next := _dict.get('next')) is not None:
            args['next'] = PageLink.from_dict(next)
        if (total_count := _dict.get('total_count')) is not None:
            args['total_count'] = 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 ReservedIPCollectionEndpointGatewayContext:
    """
    ReservedIPCollectionEndpointGatewayContext.

    :param PageLink first: A link to the first page of resources.
    :param List[ReservedIP] ips: A page of reserved IPs bound to the endpoint
          gateway.
    :param int limit: The maximum number of resources that can be returned by the
          request.
    :param PageLink next: (optional) A link to the next page of resources. This
          property is present for all pages
          except the last page.
    :param int total_count: The total number of resources across all pages.
    """

    def __init__(
        self,
        first: 'PageLink',
        ips: List['ReservedIP'],
        limit: int,
        total_count: int,
        *,
        next: Optional['PageLink'] = None,
    ) -> None:
        """
        Initialize a ReservedIPCollectionEndpointGatewayContext object.

        :param PageLink first: A link to the first page of resources.
        :param List[ReservedIP] ips: A page of reserved IPs bound to the 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 PageLink 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 := _dict.get('first')) is not None:
            args['first'] = PageLink.from_dict(first)
        else:
            raise ValueError('Required property \'first\' not present in ReservedIPCollectionEndpointGatewayContext JSON')
        if (ips := _dict.get('ips')) is not None:
            args['ips'] = [ReservedIP.from_dict(v) for v in ips]
        else:
            raise ValueError('Required property \'ips\' not present in ReservedIPCollectionEndpointGatewayContext JSON')
        if (limit := _dict.get('limit')) is not None:
            args['limit'] = limit
        else:
            raise ValueError('Required property \'limit\' not present in ReservedIPCollectionEndpointGatewayContext JSON')
        if (next := _dict.get('next')) is not None:
            args['next'] = PageLink.from_dict(next)
        if (total_count := _dict.get('total_count')) is not None:
            args['total_count'] = 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 ReservedIPCollectionInstanceNetworkInterfaceContext:
    """
    ReservedIPCollectionInstanceNetworkInterfaceContext.

    :param PageLink first: A link to the first page of resources.
    :param List[ReservedIP] ips: A page of reserved IPs bound to the instance
          network interface.
    :param int limit: The maximum number of resources that can be returned by the
          request.
    :param PageLink next: (optional) A link to the next page of resources. This
          property is present for all pages
          except the last page.
    :param int total_count: The total number of resources across all pages.
    """

    def __init__(
        self,
        first: 'PageLink',
        ips: List['ReservedIP'],
        limit: int,
        total_count: int,
        *,
        next: Optional['PageLink'] = None,
    ) -> None:
        """
        Initialize a ReservedIPCollectionInstanceNetworkInterfaceContext object.

        :param PageLink first: A link to the first page of resources.
        :param List[ReservedIP] ips: A page of reserved IPs bound to the 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 PageLink 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 := _dict.get('first')) is not None:
            args['first'] = PageLink.from_dict(first)
        else:
            raise ValueError('Required property \'first\' not present in ReservedIPCollectionInstanceNetworkInterfaceContext JSON')
        if (ips := _dict.get('ips')) is not None:
            args['ips'] = [ReservedIP.from_dict(v) for v in ips]
        else:
            raise ValueError('Required property \'ips\' not present in ReservedIPCollectionInstanceNetworkInterfaceContext JSON')
        if (limit := _dict.get('limit')) is not None:
            args['limit'] = limit
        else:
            raise ValueError('Required property \'limit\' not present in ReservedIPCollectionInstanceNetworkInterfaceContext JSON')
        if (next := _dict.get('next')) is not None:
            args['next'] = PageLink.from_dict(next)
        if (total_count := _dict.get('total_count')) is not None:
            args['total_count'] = 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 ReservedIPCollectionVirtualNetworkInterfaceContext:
    """
    ReservedIPCollectionVirtualNetworkInterfaceContext.

    :param PageLink first: A link to the first page of resources.
    :param List[ReservedIPReference] ips: A page of reserved IPs bound to the
          virtual network interface specified by the identifier in the URL.
    :param int limit: The maximum number of resources that can be returned by the
          request.
    :param PageLink next: (optional) A link to the next page of resources. This
          property is present for all pages
          except the last page.
    :param int total_count: The total number of resources across all pages.
    """

    def __init__(
        self,
        first: 'PageLink',
        ips: List['ReservedIPReference'],
        limit: int,
        total_count: int,
        *,
        next: Optional['PageLink'] = None,
    ) -> None:
        """
        Initialize a ReservedIPCollectionVirtualNetworkInterfaceContext object.

        :param PageLink first: A link to the first page of resources.
        :param List[ReservedIPReference] ips: A page of reserved IPs bound to the
               virtual network interface specified by the identifier in the URL.
        :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 PageLink 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) -> 'ReservedIPCollectionVirtualNetworkInterfaceContext':
        """Initialize a ReservedIPCollectionVirtualNetworkInterfaceContext object from a json dictionary."""
        args = {}
        if (first := _dict.get('first')) is not None:
            args['first'] = PageLink.from_dict(first)
        else:
            raise ValueError('Required property \'first\' not present in ReservedIPCollectionVirtualNetworkInterfaceContext JSON')
        if (ips := _dict.get('ips')) is not None:
            args['ips'] = [ReservedIPReference.from_dict(v) for v in ips]
        else:
            raise ValueError('Required property \'ips\' not present in ReservedIPCollectionVirtualNetworkInterfaceContext JSON')
        if (limit := _dict.get('limit')) is not None:
            args['limit'] = limit
        else:
            raise ValueError('Required property \'limit\' not present in ReservedIPCollectionVirtualNetworkInterfaceContext JSON')
        if (next := _dict.get('next')) is not None:
            args['next'] = PageLink.from_dict(next)
        if (total_count := _dict.get('total_count')) is not None:
            args['total_count'] = total_count
        else:
            raise ValueError('Required property \'total_count\' not present in ReservedIPCollectionVirtualNetworkInterfaceContext JSON')
        return cls(**args)

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

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

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


class ReservedIPPatch:
    """
    ReservedIPPatch.

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

    def __init__(
        self,
        *,
        auto_delete: Optional[bool] = None,
        name: Optional[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 := _dict.get('auto_delete')) is not None:
            args['auto_delete'] = auto_delete
        if (name := _dict.get('name')) is not None:
            args['name'] = 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.

    :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
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) to support
          IPv6 addresses in the future.
    :param Deleted deleted: (optional) If present, this property indicates the
          referenced resource has been deleted, and provides
          some supplementary information.
    :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.
    """

    def __init__(
        self,
        address: str,
        href: str,
        id: str,
        name: str,
        resource_type: str,
        *,
        deleted: Optional['Deleted'] = 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
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) to
               support IPv6 addresses in the future.
        :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 Deleted 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 := _dict.get('address')) is not None:
            args['address'] = address
        else:
            raise ValueError('Required property \'address\' not present in ReservedIPReference JSON')
        if (deleted := _dict.get('deleted')) is not None:
            args['deleted'] = Deleted.from_dict(deleted)
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in ReservedIPReference JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in ReservedIPReference JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in ReservedIPReference JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = 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 ReservedIPTarget:
    """
    The target this reserved IP is bound to.
    If absent, this reserved IP is provider-owned or unbound.
    The resources supported by this property may
    [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the future.

    """

    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.
    The following targets are supported:
    - An endpoint gateway not already bound to a reserved IP in the subnet's zone.
    - A virtual network interface.
    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', 'ReservedIPTargetPrototypeVirtualNetworkInterfaceIdentity'])
        )
        raise Exception(msg)


class ResourceFilter:
    """
    Identifies one or more resources according to the specified filter property.

    :param str resource_type: (optional) The resource type.
    """

    def __init__(
        self,
        *,
        resource_type: Optional[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 := _dict.get('resource_type')) is not None:
            args['resource_type'] = 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.

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

    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 := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in ResourceGroupReference JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in ResourceGroupReference JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = 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.

    :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
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :param bool advertise: Indicates whether this route will be advertised to the
          ingress sources specified by the `advertise_routes_to` routing table property.
    :param datetime created_at: The date and time that the route was created.
    :param 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.
    :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 str origin: 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 may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :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.
          If subnets are attached to the route's routing table, egress traffic from those
          subnets in this zone will be subject to this route. If this route's routing
          table
          has any of `route_direct_link_ingress`, `route_internet_ingress`,
          `route_transit_gateway_ingress` or `route_vpc_zone_ingress`  set to`true`,
          traffic
          from those ingress sources arriving in this zone will be subject to this route.
    """

    def __init__(
        self,
        action: str,
        advertise: bool,
        created_at: datetime,
        destination: str,
        href: str,
        id: str,
        lifecycle_state: str,
        name: str,
        next_hop: 'RouteNextHop',
        origin: str,
        priority: int,
        zone: 'ZoneReference',
        *,
        creator: Optional['RouteCreator'] = 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
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :param bool advertise: Indicates whether this route will be advertised to
               the ingress sources specified by the `advertise_routes_to` routing table
               property.
        :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 str origin: 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 may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :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.
               If subnets are attached to the route's routing table, egress traffic from
               those
               subnets in this zone will be subject to this route. If this route's routing
               table
               has any of `route_direct_link_ingress`, `route_internet_ingress`,
               `route_transit_gateway_ingress` or `route_vpc_zone_ingress`  set to`true`,
               traffic
               from those ingress sources arriving in this zone will be subject to this
               route.
        """
        self.action = action
        self.advertise = advertise
        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 := _dict.get('action')) is not None:
            args['action'] = action
        else:
            raise ValueError('Required property \'action\' not present in Route JSON')
        if (advertise := _dict.get('advertise')) is not None:
            args['advertise'] = advertise
        else:
            raise ValueError('Required property \'advertise\' not present in Route JSON')
        if (created_at := _dict.get('created_at')) is not None:
            args['created_at'] = string_to_datetime(created_at)
        else:
            raise ValueError('Required property \'created_at\' not present in Route JSON')
        if (creator := _dict.get('creator')) is not None:
            args['creator'] = creator
        if (destination := _dict.get('destination')) is not None:
            args['destination'] = destination
        else:
            raise ValueError('Required property \'destination\' not present in Route JSON')
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in Route JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in Route JSON')
        if (lifecycle_state := _dict.get('lifecycle_state')) is not None:
            args['lifecycle_state'] = lifecycle_state
        else:
            raise ValueError('Required property \'lifecycle_state\' not present in Route JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in Route JSON')
        if (next_hop := _dict.get('next_hop')) is not None:
            args['next_hop'] = next_hop
        else:
            raise ValueError('Required property \'next_hop\' not present in Route JSON')
        if (origin := _dict.get('origin')) is not None:
            args['origin'] = origin
        else:
            raise ValueError('Required property \'origin\' not present in Route JSON')
        if (priority := _dict.get('priority')) is not None:
            args['priority'] = priority
        else:
            raise ValueError('Required property \'priority\' not present in Route JSON')
        if (zone := _dict.get('zone')) is not None:
            args['zone'] = ZoneReference.from_dict(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, 'advertise') and self.advertise is not None:
            _dict['advertise'] = self.advertise
        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 self.origin is not None:
            _dict['origin'] = 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
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        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 may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        SERVICE = 'service'
        USER = 'user'



class RouteCollection:
    """
    RouteCollection.

    :param PageLink 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 PageLink next: (optional) A link to the next page of resources. This
          property is present for all pages
          except the last page.
    :param List[Route] routes: A page of routes in the routing table.
    :param int total_count: The total number of resources across all pages.
    """

    def __init__(
        self,
        first: 'PageLink',
        limit: int,
        routes: List['Route'],
        total_count: int,
        *,
        next: Optional['PageLink'] = None,
    ) -> None:
        """
        Initialize a RouteCollection object.

        :param PageLink 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: A page of routes in the routing table.
        :param int total_count: The total number of resources across all pages.
        :param PageLink 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 := _dict.get('first')) is not None:
            args['first'] = PageLink.from_dict(first)
        else:
            raise ValueError('Required property \'first\' not present in RouteCollection JSON')
        if (limit := _dict.get('limit')) is not None:
            args['limit'] = limit
        else:
            raise ValueError('Required property \'limit\' not present in RouteCollection JSON')
        if (next := _dict.get('next')) is not None:
            args['next'] = PageLink.from_dict(next)
        if (routes := _dict.get('routes')) is not None:
            args['routes'] = [Route.from_dict(v) for v in routes]
        else:
            raise ValueError('Required property \'routes\' not present in RouteCollection JSON')
        if (total_count := _dict.get('total_count')) is not None:
            args['total_count'] = 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 RouteCollectionVPCContext:
    """
    RouteCollectionVPCContext.

    :param PageLink 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 PageLink next: (optional) A link to the next page of resources. This
          property is present for all pages
          except the last page.
    :param List[Route] routes: A page of routes in the routing table.
    :param int total_count: The total number of resources across all pages.
    """

    def __init__(
        self,
        first: 'PageLink',
        limit: int,
        routes: List['Route'],
        total_count: int,
        *,
        next: Optional['PageLink'] = None,
    ) -> None:
        """
        Initialize a RouteCollectionVPCContext object.

        :param PageLink 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: A page of routes in the routing table.
        :param int total_count: The total number of resources across all pages.
        :param PageLink 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 := _dict.get('first')) is not None:
            args['first'] = PageLink.from_dict(first)
        else:
            raise ValueError('Required property \'first\' not present in RouteCollectionVPCContext JSON')
        if (limit := _dict.get('limit')) is not None:
            args['limit'] = limit
        else:
            raise ValueError('Required property \'limit\' not present in RouteCollectionVPCContext JSON')
        if (next := _dict.get('next')) is not None:
            args['next'] = PageLink.from_dict(next)
        if (routes := _dict.get('routes')) is not None:
            args['routes'] = [Route.from_dict(v) for v in routes]
        else:
            raise ValueError('Required property \'routes\' not present in RouteCollectionVPCContext JSON')
        if (total_count := _dict.get('total_count')) is not None:
            args['total_count'] = 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 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 (must not be
    `0.0.0.0`). 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 RouteNextHopPrototype:
    """
    If `action` is `deliver`, the next hop that packets will be delivered to (must not be
    `0.0.0.0`). 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 RouteNextHopPrototype object.

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


class RoutePatch:
    """
    RoutePatch.

    :param bool advertise: (optional) Indicates whether this route will be
          advertised to the ingress sources specified by the `advertise_routes_to` routing
          table property.
          Since all routes in a routing table with the same `destination` and `zone` must
          have the same `advertise` value, this property can only be changed for routes
          with a unique
          `destination` and `zone` in the routing table. For more information, see
          [Advertising
          routes](https://cloud.ibm.com/docs/vpc?topic=vpc-about-custom-routes#rt-advertising-routes).
    :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 (must not be
          `0.0.0.0`). 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.
    """

    def __init__(
        self,
        *,
        advertise: Optional[bool] = None,
        name: Optional[str] = None,
        next_hop: Optional['RouteNextHopPatch'] = None,
        priority: Optional[int] = None,
    ) -> None:
        """
        Initialize a RoutePatch object.

        :param bool advertise: (optional) Indicates whether this route will be
               advertised to the ingress sources specified by the `advertise_routes_to`
               routing table property.
               Since all routes in a routing table with the same `destination` and `zone`
               must have the same `advertise` value, this property can only be changed for
               routes with a unique
               `destination` and `zone` in the routing table. For more information, see
               [Advertising
               routes](https://cloud.ibm.com/docs/vpc?topic=vpc-about-custom-routes#rt-advertising-routes).
        :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 (must not be
               `0.0.0.0`). 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.advertise = advertise
        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 (advertise := _dict.get('advertise')) is not None:
            args['advertise'] = advertise
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        if (next_hop := _dict.get('next_hop')) is not None:
            args['next_hop'] = next_hop
        if (priority := _dict.get('priority')) is not None:
            args['priority'] = 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, 'advertise') and self.advertise is not None:
            _dict['advertise'] = self.advertise
        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.

    :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 bool advertise: (optional) Indicates whether this route will be
          advertised to the ingress sources specified by the `advertise_routes_to` routing
          table property.
          All routes in a routing table with the same `destination` and `zone` must have
          the same
          `advertise` value.
    :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 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 RouteNextHopPrototype next_hop: (optional) If `action` is `deliver`, the
          next hop that packets will be delivered to (must not be
          `0.0.0.0`). 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 ZoneIdentity zone: The zone to apply the route to.
          If subnets are attached to the route's routing table, egress traffic from those
          subnets in this zone will be subject to this route. If this route's routing
          table
          has any of `route_direct_link_ingress`, `route_internet_ingress`,
          `route_transit_gateway_ingress` or `route_vpc_zone_ingress`  set to`true`,
          traffic
          from those ingress sources arriving in this zone will be subject to this route.
    """

    def __init__(
        self,
        destination: str,
        zone: 'ZoneIdentity',
        *,
        action: Optional[str] = None,
        advertise: Optional[bool] = None,
        name: Optional[str] = None,
        next_hop: Optional['RouteNextHopPrototype'] = None,
        priority: Optional[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.
               If subnets are attached to the route's routing table, egress traffic from
               those
               subnets in this zone will be subject to this route. If this route's routing
               table
               has any of `route_direct_link_ingress`, `route_internet_ingress`,
               `route_transit_gateway_ingress` or `route_vpc_zone_ingress`  set to`true`,
               traffic
               from those ingress sources arriving 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 bool advertise: (optional) Indicates whether this route will be
               advertised to the ingress sources specified by the `advertise_routes_to`
               routing table property.
               All routes in a routing table with the same `destination` and `zone` must
               have the same
               `advertise` value.
        :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 RouteNextHopPrototype next_hop: (optional) If `action` is `deliver`,
               the next hop that packets will be delivered to (must not be
               `0.0.0.0`). 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.advertise = advertise
        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 := _dict.get('action')) is not None:
            args['action'] = action
        if (advertise := _dict.get('advertise')) is not None:
            args['advertise'] = advertise
        if (destination := _dict.get('destination')) is not None:
            args['destination'] = destination
        else:
            raise ValueError('Required property \'destination\' not present in RoutePrototype JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        if (next_hop := _dict.get('next_hop')) is not None:
            args['next_hop'] = next_hop
        if (priority := _dict.get('priority')) is not None:
            args['priority'] = priority
        if (zone := _dict.get('zone')) is not None:
            args['zone'] = 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, 'advertise') and self.advertise is not None:
            _dict['advertise'] = self.advertise
        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 RouteReference:
    """
    RouteReference.

    :param Deleted deleted: (optional) If present, this property indicates the
          referenced resource has been deleted, and provides
          some supplementary information.
    :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.
    """

    def __init__(
        self,
        href: str,
        id: str,
        name: str,
        *,
        deleted: Optional['Deleted'] = 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 Deleted 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 := _dict.get('deleted')) is not None:
            args['deleted'] = Deleted.from_dict(deleted)
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in RouteReference JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in RouteReference JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = 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 RoutingTable:
    """
    RoutingTable.

    :param List[ResourceFilter] accept_routes_from: The filters specifying the
          resources that may create routes in this routing table.
          The resources and types of filters supported by this property is expected to
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :param List[str] advertise_routes_to: The ingress sources to advertise routes
          to. Routes in the table with `advertise` enabled will be advertised to these
          sources.
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :param datetime created_at: The date and time that this routing table was
          created.
    :param str crn: The CRN for this VPC routing table.
    :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 ResourceGroupReference resource_group: The resource group for this
          routing table.
    :param str resource_type: The resource type.
    :param bool route_direct_link_ingress: Indicates whether this routing table is
          used to route traffic that originates from
          [Direct Link](https://cloud.ibm.com/docs/dl) to this VPC.
          Incoming traffic will be routed according to the routing table with one
          exception: routes with an `action` of `deliver` are treated as `drop` unless the
          `next_hop` is an IP address 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.
    """

    def __init__(
        self,
        accept_routes_from: List['ResourceFilter'],
        advertise_routes_to: List[str],
        created_at: datetime,
        crn: str,
        href: str,
        id: str,
        is_default: bool,
        lifecycle_state: str,
        name: str,
        resource_group: 'ResourceGroupReference',
        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.
               The resources and types of filters supported by this property is expected
               to
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :param List[str] advertise_routes_to: The ingress sources to advertise
               routes to. Routes in the table with `advertise` enabled will be advertised
               to these sources.
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :param datetime created_at: The date and time that this routing table was
               created.
        :param str crn: The CRN for this VPC routing table.
        :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 ResourceGroupReference resource_group: The resource group for this
               routing table.
        :param str resource_type: The resource type.
        :param bool route_direct_link_ingress: Indicates whether this routing table
               is used to route traffic that originates from
               [Direct Link](https://cloud.ibm.com/docs/dl) to this VPC.
               Incoming traffic will be routed according to the routing table with one
               exception: routes with an `action` of `deliver` are treated as `drop`
               unless the `next_hop` is an IP address 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.advertise_routes_to = advertise_routes_to
        self.created_at = created_at
        self.crn = crn
        self.href = href
        self.id = id
        self.is_default = is_default
        self.lifecycle_state = lifecycle_state
        self.name = name
        self.resource_group = resource_group
        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 := _dict.get('accept_routes_from')) is not None:
            args['accept_routes_from'] = [ResourceFilter.from_dict(v) for v in accept_routes_from]
        else:
            raise ValueError('Required property \'accept_routes_from\' not present in RoutingTable JSON')
        if (advertise_routes_to := _dict.get('advertise_routes_to')) is not None:
            args['advertise_routes_to'] = advertise_routes_to
        else:
            raise ValueError('Required property \'advertise_routes_to\' not present in RoutingTable JSON')
        if (created_at := _dict.get('created_at')) is not None:
            args['created_at'] = string_to_datetime(created_at)
        else:
            raise ValueError('Required property \'created_at\' not present in RoutingTable JSON')
        if (crn := _dict.get('crn')) is not None:
            args['crn'] = crn
        else:
            raise ValueError('Required property \'crn\' not present in RoutingTable JSON')
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in RoutingTable JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in RoutingTable JSON')
        if (is_default := _dict.get('is_default')) is not None:
            args['is_default'] = is_default
        else:
            raise ValueError('Required property \'is_default\' not present in RoutingTable JSON')
        if (lifecycle_state := _dict.get('lifecycle_state')) is not None:
            args['lifecycle_state'] = lifecycle_state
        else:
            raise ValueError('Required property \'lifecycle_state\' not present in RoutingTable JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in RoutingTable JSON')
        if (resource_group := _dict.get('resource_group')) is not None:
            args['resource_group'] = ResourceGroupReference.from_dict(resource_group)
        else:
            raise ValueError('Required property \'resource_group\' not present in RoutingTable JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = resource_type
        else:
            raise ValueError('Required property \'resource_type\' not present in RoutingTable JSON')
        if (route_direct_link_ingress := _dict.get('route_direct_link_ingress')) is not None:
            args['route_direct_link_ingress'] = route_direct_link_ingress
        else:
            raise ValueError('Required property \'route_direct_link_ingress\' not present in RoutingTable JSON')
        if (route_internet_ingress := _dict.get('route_internet_ingress')) is not None:
            args['route_internet_ingress'] = route_internet_ingress
        else:
            raise ValueError('Required property \'route_internet_ingress\' not present in RoutingTable JSON')
        if (route_transit_gateway_ingress := _dict.get('route_transit_gateway_ingress')) is not None:
            args['route_transit_gateway_ingress'] = route_transit_gateway_ingress
        else:
            raise ValueError('Required property \'route_transit_gateway_ingress\' not present in RoutingTable JSON')
        if (route_vpc_zone_ingress := _dict.get('route_vpc_zone_ingress')) is not None:
            args['route_vpc_zone_ingress'] = route_vpc_zone_ingress
        else:
            raise ValueError('Required property \'route_vpc_zone_ingress\' not present in RoutingTable JSON')
        if (routes := _dict.get('routes')) is not None:
            args['routes'] = [RouteReference.from_dict(v) for v in routes]
        else:
            raise ValueError('Required property \'routes\' not present in RoutingTable JSON')
        if (subnets := _dict.get('subnets')) is not None:
            args['subnets'] = [SubnetReference.from_dict(v) for v in 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, 'advertise_routes_to') and self.advertise_routes_to is not None:
            _dict['advertise_routes_to'] = self.advertise_routes_to
        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, '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_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_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 AdvertiseRoutesToEnum(str, Enum):
        """
        An ingress source that routes can be advertised to:
        - `direct_link` (requires `route_direct_link_ingress` be set to `true`)
        - `transit_gateway` (requires `route_transit_gateway_ingress` be set to `true`).
        """

        DIRECT_LINK = 'direct_link'
        TRANSIT_GATEWAY = 'transit_gateway'


    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.

    :param PageLink 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 PageLink next: (optional) A link to the next page of resources. This
          property is present for all pages
          except the last page.
    :param List[RoutingTable] routing_tables: A page of routing tables.
    :param int total_count: The total number of resources across all pages.
    """

    def __init__(
        self,
        first: 'PageLink',
        limit: int,
        routing_tables: List['RoutingTable'],
        total_count: int,
        *,
        next: Optional['PageLink'] = None,
    ) -> None:
        """
        Initialize a RoutingTableCollection object.

        :param PageLink 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: A page of routing tables.
        :param int total_count: The total number of resources across all pages.
        :param PageLink 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 := _dict.get('first')) is not None:
            args['first'] = PageLink.from_dict(first)
        else:
            raise ValueError('Required property \'first\' not present in RoutingTableCollection JSON')
        if (limit := _dict.get('limit')) is not None:
            args['limit'] = limit
        else:
            raise ValueError('Required property \'limit\' not present in RoutingTableCollection JSON')
        if (next := _dict.get('next')) is not None:
            args['next'] = PageLink.from_dict(next)
        if (routing_tables := _dict.get('routing_tables')) is not None:
            args['routing_tables'] = [RoutingTable.from_dict(v) for v in routing_tables]
        else:
            raise ValueError('Required property \'routing_tables\' not present in RoutingTableCollection JSON')
        if (total_count := _dict.get('total_count')) is not None:
            args['total_count'] = 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 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(['RoutingTableIdentityByCRN', 'RoutingTableIdentityById', 'RoutingTableIdentityByHref'])
        )
        raise Exception(msg)


class RoutingTablePatch:
    """
    RoutingTablePatch.

    :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.
          If specified, `resource_type` must be `vpn_gateway` or `vpn_server`.
    :param List[str] advertise_routes_to: (optional) The ingress sources to
          advertise routes to, replacing any existing sources to advertise to. Routes in
          the table with `advertise` enabled will be advertised to these sources.
    :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, provided `direct_link` is absent from
          `advertise_routes_to`.
          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, provided
          `transit_gateway` is absent from `advertise_routes_to`.
          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.
    """

    def __init__(
        self,
        *,
        accept_routes_from: Optional[List['ResourceFilter']] = None,
        advertise_routes_to: Optional[List[str]] = None,
        name: Optional[str] = None,
        route_direct_link_ingress: Optional[bool] = None,
        route_internet_ingress: Optional[bool] = None,
        route_transit_gateway_ingress: Optional[bool] = None,
        route_vpc_zone_ingress: Optional[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.
               If specified, `resource_type` must be `vpn_gateway` or `vpn_server`.
        :param List[str] advertise_routes_to: (optional) The ingress sources to
               advertise routes to, replacing any existing sources to advertise to. Routes
               in the table with `advertise` enabled will be advertised to these sources.
        :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, provided `direct_link` is absent from
               `advertise_routes_to`.
               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,
               provided `transit_gateway` is absent from `advertise_routes_to`.
               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.advertise_routes_to = advertise_routes_to
        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 := _dict.get('accept_routes_from')) is not None:
            args['accept_routes_from'] = [ResourceFilter.from_dict(v) for v in accept_routes_from]
        if (advertise_routes_to := _dict.get('advertise_routes_to')) is not None:
            args['advertise_routes_to'] = advertise_routes_to
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        if (route_direct_link_ingress := _dict.get('route_direct_link_ingress')) is not None:
            args['route_direct_link_ingress'] = route_direct_link_ingress
        if (route_internet_ingress := _dict.get('route_internet_ingress')) is not None:
            args['route_internet_ingress'] = route_internet_ingress
        if (route_transit_gateway_ingress := _dict.get('route_transit_gateway_ingress')) is not None:
            args['route_transit_gateway_ingress'] = route_transit_gateway_ingress
        if (route_vpc_zone_ingress := _dict.get('route_vpc_zone_ingress')) is not None:
            args['route_vpc_zone_ingress'] = 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, 'advertise_routes_to') and self.advertise_routes_to is not None:
            _dict['advertise_routes_to'] = self.advertise_routes_to
        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 AdvertiseRoutesToEnum(str, Enum):
        """
        An ingress source that routes can be advertised to:
        - `direct_link` (requires `route_direct_link_ingress` be set to `true`)
        - `transit_gateway` (requires `route_transit_gateway_ingress` be set to `true`).
        """

        DIRECT_LINK = 'direct_link'
        TRANSIT_GATEWAY = 'transit_gateway'



class RoutingTableReference:
    """
    RoutingTableReference.

    :param str crn: The CRN for this VPC routing table.
    :param Deleted deleted: (optional) If present, this property indicates the
          referenced resource has been deleted, and provides
          some supplementary information.
    :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.
    """

    def __init__(
        self,
        crn: str,
        href: str,
        id: str,
        name: str,
        resource_type: str,
        *,
        deleted: Optional['Deleted'] = None,
    ) -> None:
        """
        Initialize a RoutingTableReference object.

        :param str crn: The CRN for this VPC routing table.
        :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 Deleted 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) -> 'RoutingTableReference':
        """Initialize a RoutingTableReference object from a json dictionary."""
        args = {}
        if (crn := _dict.get('crn')) is not None:
            args['crn'] = crn
        else:
            raise ValueError('Required property \'crn\' not present in RoutingTableReference JSON')
        if (deleted := _dict.get('deleted')) is not None:
            args['deleted'] = Deleted.from_dict(deleted)
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in RoutingTableReference JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in RoutingTableReference JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in RoutingTableReference JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = 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, '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 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 SecurityGroup:
    """
    SecurityGroup.

    :param datetime created_at: The date and time that this security group was
          created.
    :param str crn: The CRN for this security group.
    :param str href: The URL for this security group.
    :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.
    """

    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 CRN for this security group.
        :param str href: The URL for this security group.
        :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 := _dict.get('created_at')) is not None:
            args['created_at'] = string_to_datetime(created_at)
        else:
            raise ValueError('Required property \'created_at\' not present in SecurityGroup JSON')
        if (crn := _dict.get('crn')) is not None:
            args['crn'] = crn
        else:
            raise ValueError('Required property \'crn\' not present in SecurityGroup JSON')
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in SecurityGroup JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in SecurityGroup JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in SecurityGroup JSON')
        if (resource_group := _dict.get('resource_group')) is not None:
            args['resource_group'] = ResourceGroupReference.from_dict(resource_group)
        else:
            raise ValueError('Required property \'resource_group\' not present in SecurityGroup JSON')
        if (rules := _dict.get('rules')) is not None:
            args['rules'] = [SecurityGroupRule.from_dict(v) for v in rules]
        else:
            raise ValueError('Required property \'rules\' not present in SecurityGroup JSON')
        if (targets := _dict.get('targets')) is not None:
            args['targets'] = targets
        else:
            raise ValueError('Required property \'targets\' not present in SecurityGroup JSON')
        if (vpc := _dict.get('vpc')) is not None:
            args['vpc'] = VPCReference.from_dict(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.

    :param PageLink 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 PageLink next: (optional) A link to the next page of resources. This
          property is present for all pages
          except the last page.
    :param List[SecurityGroup] security_groups: A page of security groups.
    :param int total_count: The total number of resources across all pages.
    """

    def __init__(
        self,
        first: 'PageLink',
        limit: int,
        security_groups: List['SecurityGroup'],
        total_count: int,
        *,
        next: Optional['PageLink'] = None,
    ) -> None:
        """
        Initialize a SecurityGroupCollection object.

        :param PageLink 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: A page of security groups.
        :param int total_count: The total number of resources across all pages.
        :param PageLink 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 := _dict.get('first')) is not None:
            args['first'] = PageLink.from_dict(first)
        else:
            raise ValueError('Required property \'first\' not present in SecurityGroupCollection JSON')
        if (limit := _dict.get('limit')) is not None:
            args['limit'] = limit
        else:
            raise ValueError('Required property \'limit\' not present in SecurityGroupCollection JSON')
        if (next := _dict.get('next')) is not None:
            args['next'] = PageLink.from_dict(next)
        if (security_groups := _dict.get('security_groups')) is not None:
            args['security_groups'] = [SecurityGroup.from_dict(v) for v in security_groups]
        else:
            raise ValueError('Required property \'security_groups\' not present in SecurityGroupCollection JSON')
        if (total_count := _dict.get('total_count')) is not None:
            args['total_count'] = 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 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.

    :param 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: Optional[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 := _dict.get('name')) is not None:
            args['name'] = 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.

    :param str crn: The CRN for this security group.
    :param Deleted deleted: (optional) If present, this property indicates the
          referenced resource has been deleted, and provides
          some supplementary information.
    :param str href: The URL for this security group.
    :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.
    """

    def __init__(
        self,
        crn: str,
        href: str,
        id: str,
        name: str,
        *,
        deleted: Optional['Deleted'] = None,
    ) -> None:
        """
        Initialize a SecurityGroupReference object.

        :param str crn: The CRN for this security group.
        :param str href: The URL for this security group.
        :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 Deleted 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 := _dict.get('crn')) is not None:
            args['crn'] = crn
        else:
            raise ValueError('Required property \'crn\' not present in SecurityGroupReference JSON')
        if (deleted := _dict.get('deleted')) is not None:
            args['deleted'] = Deleted.from_dict(deleted)
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in SecurityGroupReference JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in SecurityGroupReference JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = 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 SecurityGroupRule:
    """
    SecurityGroupRule.

    :param str direction: The direction of traffic to allow.
    :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 allow. The format of `local.address`,
          `remote.address`,
          `local.cidr_block` or `remote.cidr_block` must match this property, if they are
          used.
          If `remote` references a security group, then this rule only applies to IP
          addresses in that group matching this IP version.
    :param SecurityGroupRuleLocal local: The local IP address or range of local IP
          addresses to which this rule will allow inbound
          traffic (or from which, for outbound traffic). A CIDR block of `0.0.0.0/0`
          allows traffic
          to all local IP addresses (or from all local IP addresses, for outbound rules).
    :param str protocol: The protocol to allow.
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :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).
    """

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

        :param str direction: The direction of traffic to allow.
        :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 allow. The format of
               `local.address`, `remote.address`,
               `local.cidr_block` or `remote.cidr_block` must match this property, if they
               are used.
               If `remote` references a security group, then this rule only applies to IP
               addresses in that group matching this IP version.
        :param SecurityGroupRuleLocal local: The local IP address or range of local
               IP addresses to which this rule will allow inbound
               traffic (or from which, for outbound traffic). A CIDR block of `0.0.0.0/0`
               allows traffic
               to all local IP addresses (or from all local IP addresses, for outbound
               rules).
        :param str protocol: The protocol to allow.
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :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 allow.
        """

        INBOUND = 'inbound'
        OUTBOUND = 'outbound'


    class IpVersionEnum(str, Enum):
        """
        The IP version to allow. The format of `local.address`, `remote.address`,
        `local.cidr_block` or `remote.cidr_block` must match this property, if they are
        used.
        If `remote` references a security group, then this rule only applies to IP
        addresses in that group matching this IP version.
        """

        IPV4 = 'ipv4'


    class ProtocolEnum(str, Enum):
        """
        The protocol to allow.
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        ALL = 'all'
        ICMP = 'icmp'
        TCP = 'tcp'
        UDP = 'udp'



class SecurityGroupRuleCollection:
    """
    SecurityGroupRuleCollection.

    :param List[SecurityGroupRule] rules: The rules for the security group.
    """

    def __init__(
        self,
        rules: List['SecurityGroupRule'],
    ) -> None:
        """
        Initialize a SecurityGroupRuleCollection object.

        :param List[SecurityGroupRule] rules: The rules for the security group.
        """
        self.rules = rules

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'SecurityGroupRuleCollection':
        """Initialize a SecurityGroupRuleCollection object from a json dictionary."""
        args = {}
        if (rules := _dict.get('rules')) is not None:
            args['rules'] = [SecurityGroupRule.from_dict(v) for v in 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 SecurityGroupRuleLocal:
    """
    The local IP address or range of local IP addresses to which this rule will allow
    inbound traffic (or from which, for outbound traffic). A CIDR block of `0.0.0.0/0`
    allows traffic to all local IP addresses (or from all local IP addresses, for outbound
    rules).

    """

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

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


class SecurityGroupRuleLocalPatch:
    """
    The local IP address or range of local IP addresses to which this rule will allow
    inbound traffic (or from which, for outbound traffic). Can be specified as an IP
    address or a CIDR block.
    Specify a CIDR block of `0.0.0.0/0` to allow traffic to all local IP addresses (or
    from all local IP addresses, for outbound rules).

    """

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

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


class SecurityGroupRuleLocalPrototype:
    """
    The local IP address or range of local IP addresses to which this rule will allow
    inbound traffic (or from which, for outbound traffic)
    If unspecified, a CIDR block of `0.0.0.0/0` will be used to allow traffic to all local
    IP addresses (or from all local IP addresses, for outbound rules).

    """

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

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


class SecurityGroupRulePatch:
    """
    SecurityGroupRulePatch.

    :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 allow.
    :param str ip_version: (optional) The IP version to allow. The format of
          `local.address`, `remote.address`,
          `local.cidr_block` or `remote.cidr_block` must match this property, if they are
          used.
          If `remote` references a security group, then this rule only applies to IP
          addresses in that group matching this IP version.
    :param SecurityGroupRuleLocalPatch local: (optional) The local IP address or
          range of local IP addresses to which this rule will allow inbound
          traffic (or from which, for outbound traffic). Can be specified as an IP address
          or a CIDR
          block.
          Specify a CIDR block of `0.0.0.0/0` to allow traffic to all local IP addresses
          (or from all
          local IP addresses, for outbound rules).
    :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.
    """

    def __init__(
        self,
        *,
        code: Optional[int] = None,
        direction: Optional[str] = None,
        ip_version: Optional[str] = None,
        local: Optional['SecurityGroupRuleLocalPatch'] = None,
        port_max: Optional[int] = None,
        port_min: Optional[int] = None,
        remote: Optional['SecurityGroupRuleRemotePatch'] = None,
        type: Optional[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 allow.
        :param str ip_version: (optional) The IP version to allow. The format of
               `local.address`, `remote.address`,
               `local.cidr_block` or `remote.cidr_block` must match this property, if they
               are used.
               If `remote` references a security group, then this rule only applies to IP
               addresses in that group matching this IP version.
        :param SecurityGroupRuleLocalPatch local: (optional) The local IP address
               or range of local IP addresses to which this rule will allow inbound
               traffic (or from which, for outbound traffic). Can be specified as an IP
               address or a CIDR
               block.
               Specify a CIDR block of `0.0.0.0/0` to allow traffic to all local IP
               addresses (or from all
               local IP addresses, for outbound rules).
        :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.local = local
        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 := _dict.get('code')) is not None:
            args['code'] = code
        if (direction := _dict.get('direction')) is not None:
            args['direction'] = direction
        if (ip_version := _dict.get('ip_version')) is not None:
            args['ip_version'] = ip_version
        if (local := _dict.get('local')) is not None:
            args['local'] = local
        if (port_max := _dict.get('port_max')) is not None:
            args['port_max'] = port_max
        if (port_min := _dict.get('port_min')) is not None:
            args['port_min'] = port_min
        if (remote := _dict.get('remote')) is not None:
            args['remote'] = remote
        if (type := _dict.get('type')) is not None:
            args['type'] = 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, 'local') and self.local is not None:
            if isinstance(self.local, dict):
                _dict['local'] = self.local
            else:
                _dict['local'] = self.local.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, '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 allow.
        """

        INBOUND = 'inbound'
        OUTBOUND = 'outbound'


    class IpVersionEnum(str, Enum):
        """
        The IP version to allow. The format of `local.address`, `remote.address`,
        `local.cidr_block` or `remote.cidr_block` must match this property, if they are
        used.
        If `remote` references a security group, then this rule only applies to IP
        addresses in that group matching this IP version.
        """

        IPV4 = 'ipv4'



class SecurityGroupRulePrototype:
    """
    SecurityGroupRulePrototype.

    :param str direction: The direction of traffic to allow.
    :param str ip_version: (optional) The IP version to allow. The format of
          `local.address`, `remote.address`,
          `local.cidr_block` or `remote.cidr_block` must match this property, if they are
          used.
          If `remote` references a security group, then this rule only applies to IP
          addresses in that group matching this IP version.
    :param SecurityGroupRuleLocalPrototype local: (optional) The local IP address or
          range of local IP addresses to which this rule will allow inbound
          traffic (or from which, for outbound traffic)
          If unspecified, a CIDR block of `0.0.0.0/0` will be used to allow traffic to all
          local IP
          addresses (or from all local IP addresses, for outbound rules).
    :param str protocol: The protocol to allow.
    :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).
    """

    def __init__(
        self,
        direction: str,
        protocol: str,
        *,
        ip_version: Optional[str] = None,
        local: Optional['SecurityGroupRuleLocalPrototype'] = None,
        remote: Optional['SecurityGroupRuleRemotePrototype'] = None,
    ) -> None:
        """
        Initialize a SecurityGroupRulePrototype object.

        :param str direction: The direction of traffic to allow.
        :param str protocol: The protocol to allow.
        :param str ip_version: (optional) The IP version to allow. The format of
               `local.address`, `remote.address`,
               `local.cidr_block` or `remote.cidr_block` must match this property, if they
               are used.
               If `remote` references a security group, then this rule only applies to IP
               addresses in that group matching this IP version.
        :param SecurityGroupRuleLocalPrototype local: (optional) The local IP
               address or range of local IP addresses to which this rule will allow
               inbound
               traffic (or from which, for outbound traffic)
               If unspecified, a CIDR block of `0.0.0.0/0` will be used to allow traffic
               to all local IP
               addresses (or from all local IP addresses, for outbound rules).
        :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)

    class DirectionEnum(str, Enum):
        """
        The direction of traffic to allow.
        """

        INBOUND = 'inbound'
        OUTBOUND = 'outbound'


    class IpVersionEnum(str, Enum):
        """
        The IP version to allow. The format of `local.address`, `remote.address`,
        `local.cidr_block` or `remote.cidr_block` must match this property, if they are
        used.
        If `remote` references a security group, then this rule only applies to IP
        addresses in that group matching this IP version.
        """

        IPV4 = 'ipv4'


    class ProtocolEnum(str, Enum):
        """
        The protocol to allow.
        """

        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.

    :param PageLink 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 PageLink next: (optional) A link to the next page of resources. This
          property is present for all pages
          except the last page.
    :param List[SecurityGroupTargetReference] targets: A page of targets for the
          security group.
    :param int total_count: The total number of resources across all pages.
    """

    def __init__(
        self,
        first: 'PageLink',
        limit: int,
        targets: List['SecurityGroupTargetReference'],
        total_count: int,
        *,
        next: Optional['PageLink'] = None,
    ) -> None:
        """
        Initialize a SecurityGroupTargetCollection object.

        :param PageLink 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: A page of targets for
               the security group.
        :param int total_count: The total number of resources across all pages.
        :param PageLink 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 := _dict.get('first')) is not None:
            args['first'] = PageLink.from_dict(first)
        else:
            raise ValueError('Required property \'first\' not present in SecurityGroupTargetCollection JSON')
        if (limit := _dict.get('limit')) is not None:
            args['limit'] = limit
        else:
            raise ValueError('Required property \'limit\' not present in SecurityGroupTargetCollection JSON')
        if (next := _dict.get('next')) is not None:
            args['next'] = PageLink.from_dict(next)
        if (targets := _dict.get('targets')) is not None:
            args['targets'] = targets
        else:
            raise ValueError('Required property \'targets\' not present in SecurityGroupTargetCollection JSON')
        if (total_count := _dict.get('total_count')) is not None:
            args['total_count'] = 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 SecurityGroupTargetReference:
    """
    A target of this security group.
    The resources supported by this property may
    [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the future.

    """

    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.

    :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 values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :param str accessor_binding_role: The accessor binding role of this file share:
          - `none`: This file share is not participating in access with another file share
          - `origin`: This file share is the origin for one or more file shares
            (which may be in other accounts)
          - `accessor`: This file share is providing access to another file share
            (which may be in another account).
    :param List[ShareAccessorBindingReference] accessor_bindings: The accessor
          bindings for this file share. Each accessor binding identifies a resource
          (possibly in another account) with access to this file share's data.
    :param List[str] allowed_transit_encryption_modes: The transit encryption modes
          allowed for this share.
    :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 EncryptionKeyReference encryption_key: (optional) The key used to encrypt
          this file share.
          This property will be present if `encryption` is `user_managed`.
    :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 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 ShareLatestSync latest_sync: (optional) Information about the latest
          synchronization for this file share.
          This property will be present when the `replication_role` is `replica` and at
          least
          one replication sync has been completed.
    :param List[ShareLifecycleReason] lifecycle_reasons: The reasons for the current
          `lifecycle_state` (if any).
    :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 ShareReference origin_share: (optional) The origin share this accessor
          share is referring to.
          This property will be present when the `accessor_binding_role` is `accessor`.
    :param ShareProfileReference profile: The
          [profile](https://cloud.ibm.com/docs/vpc?topic=vpc-file-storage-profiles) 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 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.
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :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.
          - `degraded`: This is share is participating in replication, but the replica's
          data has fallen behind 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.
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :param List[ShareReplicationStatusReason] replication_status_reasons: The
          reasons for the current replication status (if any).
    :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 ShareReference source_share: (optional) The source file share for this
          replica file share.
          This property will be present when the `replication_role` is `replica`.
    :param List[str] user_tags: Tags for this resource.
    :param ZoneReference zone: The zone this file share will reside in.
    """

    def __init__(
        self,
        access_control_mode: str,
        accessor_binding_role: str,
        accessor_bindings: List['ShareAccessorBindingReference'],
        allowed_transit_encryption_modes: List[str],
        created_at: datetime,
        crn: str,
        encryption: str,
        href: str,
        id: str,
        iops: int,
        lifecycle_reasons: List['ShareLifecycleReason'],
        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: Optional['EncryptionKeyReference'] = None,
        latest_job: Optional['ShareJob'] = None,
        latest_sync: Optional['ShareLatestSync'] = None,
        origin_share: Optional['ShareReference'] = None,
        replica_share: Optional['ShareReference'] = None,
        replication_cron_spec: Optional[str] = None,
        source_share: Optional['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 values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :param str accessor_binding_role: The accessor binding role of this file
               share:
               - `none`: This file share is not participating in access with another file
               share
               - `origin`: This file share is the origin for one or more file shares
                 (which may be in other accounts)
               - `accessor`: This file share is providing access to another file share
                 (which may be in another account).
        :param List[ShareAccessorBindingReference] accessor_bindings: The accessor
               bindings for this file share. Each accessor binding identifies a resource
               (possibly in another account) with access to this file share's data.
        :param List[str] allowed_transit_encryption_modes: The transit encryption
               modes allowed for this share.
        :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 List[ShareLifecycleReason] lifecycle_reasons: The reasons for the
               current `lifecycle_state` (if any).
        :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.
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :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.
               - `degraded`: This is share is participating in replication, but the
               replica's data has fallen behind 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.
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :param List[ShareReplicationStatusReason] replication_status_reasons: The
               reasons for the current replication status (if any).
        :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` 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 ShareLatestSync latest_sync: (optional) Information about the latest
               synchronization for this file share.
               This property will be present when the `replication_role` is `replica` and
               at least
               one replication sync has been completed.
        :param ShareReference origin_share: (optional) The origin share this
               accessor share is referring to.
               This property will be present when the `accessor_binding_role` is
               `accessor`.
        :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.accessor_binding_role = accessor_binding_role
        self.accessor_bindings = accessor_bindings
        self.allowed_transit_encryption_modes = allowed_transit_encryption_modes
        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.latest_sync = latest_sync
        self.lifecycle_reasons = lifecycle_reasons
        self.lifecycle_state = lifecycle_state
        self.mount_targets = mount_targets
        self.name = name
        self.origin_share = origin_share
        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 := _dict.get('access_control_mode')) is not None:
            args['access_control_mode'] = access_control_mode
        else:
            raise ValueError('Required property \'access_control_mode\' not present in Share JSON')
        if (accessor_binding_role := _dict.get('accessor_binding_role')) is not None:
            args['accessor_binding_role'] = accessor_binding_role
        else:
            raise ValueError('Required property \'accessor_binding_role\' not present in Share JSON')
        if (accessor_bindings := _dict.get('accessor_bindings')) is not None:
            args['accessor_bindings'] = [ShareAccessorBindingReference.from_dict(v) for v in accessor_bindings]
        else:
            raise ValueError('Required property \'accessor_bindings\' not present in Share JSON')
        if (allowed_transit_encryption_modes := _dict.get('allowed_transit_encryption_modes')) is not None:
            args['allowed_transit_encryption_modes'] = allowed_transit_encryption_modes
        else:
            raise ValueError('Required property \'allowed_transit_encryption_modes\' not present in Share JSON')
        if (created_at := _dict.get('created_at')) is not None:
            args['created_at'] = string_to_datetime(created_at)
        else:
            raise ValueError('Required property \'created_at\' not present in Share JSON')
        if (crn := _dict.get('crn')) is not None:
            args['crn'] = crn
        else:
            raise ValueError('Required property \'crn\' not present in Share JSON')
        if (encryption := _dict.get('encryption')) is not None:
            args['encryption'] = encryption
        else:
            raise ValueError('Required property \'encryption\' not present in Share JSON')
        if (encryption_key := _dict.get('encryption_key')) is not None:
            args['encryption_key'] = EncryptionKeyReference.from_dict(encryption_key)
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in Share JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in Share JSON')
        if (iops := _dict.get('iops')) is not None:
            args['iops'] = iops
        else:
            raise ValueError('Required property \'iops\' not present in Share JSON')
        if (latest_job := _dict.get('latest_job')) is not None:
            args['latest_job'] = ShareJob.from_dict(latest_job)
        if (latest_sync := _dict.get('latest_sync')) is not None:
            args['latest_sync'] = ShareLatestSync.from_dict(latest_sync)
        if (lifecycle_reasons := _dict.get('lifecycle_reasons')) is not None:
            args['lifecycle_reasons'] = [ShareLifecycleReason.from_dict(v) for v in lifecycle_reasons]
        else:
            raise ValueError('Required property \'lifecycle_reasons\' not present in Share JSON')
        if (lifecycle_state := _dict.get('lifecycle_state')) is not None:
            args['lifecycle_state'] = lifecycle_state
        else:
            raise ValueError('Required property \'lifecycle_state\' not present in Share JSON')
        if (mount_targets := _dict.get('mount_targets')) is not None:
            args['mount_targets'] = [ShareMountTargetReference.from_dict(v) for v in mount_targets]
        else:
            raise ValueError('Required property \'mount_targets\' not present in Share JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in Share JSON')
        if (origin_share := _dict.get('origin_share')) is not None:
            args['origin_share'] = ShareReference.from_dict(origin_share)
        if (profile := _dict.get('profile')) is not None:
            args['profile'] = ShareProfileReference.from_dict(profile)
        else:
            raise ValueError('Required property \'profile\' not present in Share JSON')
        if (replica_share := _dict.get('replica_share')) is not None:
            args['replica_share'] = ShareReference.from_dict(replica_share)
        if (replication_cron_spec := _dict.get('replication_cron_spec')) is not None:
            args['replication_cron_spec'] = replication_cron_spec
        if (replication_role := _dict.get('replication_role')) is not None:
            args['replication_role'] = replication_role
        else:
            raise ValueError('Required property \'replication_role\' not present in Share JSON')
        if (replication_status := _dict.get('replication_status')) is not None:
            args['replication_status'] = replication_status
        else:
            raise ValueError('Required property \'replication_status\' not present in Share JSON')
        if (replication_status_reasons := _dict.get('replication_status_reasons')) is not None:
            args['replication_status_reasons'] = [ShareReplicationStatusReason.from_dict(v) for v in replication_status_reasons]
        else:
            raise ValueError('Required property \'replication_status_reasons\' not present in Share JSON')
        if (resource_group := _dict.get('resource_group')) is not None:
            args['resource_group'] = ResourceGroupReference.from_dict(resource_group)
        else:
            raise ValueError('Required property \'resource_group\' not present in Share JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = resource_type
        else:
            raise ValueError('Required property \'resource_type\' not present in Share JSON')
        if (size := _dict.get('size')) is not None:
            args['size'] = size
        else:
            raise ValueError('Required property \'size\' not present in Share JSON')
        if (source_share := _dict.get('source_share')) is not None:
            args['source_share'] = ShareReference.from_dict(source_share)
        if (user_tags := _dict.get('user_tags')) is not None:
            args['user_tags'] = user_tags
        else:
            raise ValueError('Required property \'user_tags\' not present in Share JSON')
        if (zone := _dict.get('zone')) is not None:
            args['zone'] = ZoneReference.from_dict(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, 'accessor_binding_role') and self.accessor_binding_role is not None:
            _dict['accessor_binding_role'] = self.accessor_binding_role
        if hasattr(self, 'accessor_bindings') and self.accessor_bindings is not None:
            accessor_bindings_list = []
            for v in self.accessor_bindings:
                if isinstance(v, dict):
                    accessor_bindings_list.append(v)
                else:
                    accessor_bindings_list.append(v.to_dict())
            _dict['accessor_bindings'] = accessor_bindings_list
        if hasattr(self, 'allowed_transit_encryption_modes') and self.allowed_transit_encryption_modes is not None:
            _dict['allowed_transit_encryption_modes'] = self.allowed_transit_encryption_modes
        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, 'latest_sync') and self.latest_sync is not None:
            if isinstance(self.latest_sync, dict):
                _dict['latest_sync'] = self.latest_sync
            else:
                _dict['latest_sync'] = self.latest_sync.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, '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, 'origin_share') and self.origin_share is not None:
            if isinstance(self.origin_share, dict):
                _dict['origin_share'] = self.origin_share
            else:
                _dict['origin_share'] = self.origin_share.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, '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 values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        SECURITY_GROUP = 'security_group'
        VPC = 'vpc'


    class AccessorBindingRoleEnum(str, Enum):
        """
        The accessor binding role of this file share:
        - `none`: This file share is not participating in access with another file share
        - `origin`: This file share is the origin for one or more file shares
          (which may be in other accounts)
        - `accessor`: This file share is providing access to another file share
          (which may be in another account).
        """

        ACCESSOR = 'accessor'
        NONE = 'none'
        ORIGIN = 'origin'


    class AllowedTransitEncryptionModesEnum(str, Enum):
        """
        An allowed transit encryption mode for this share.
        - `none`: Not encrypted in transit.
        - `user_managed`: Encrypted in transit using an instance identity certificate.
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        NONE = 'none'
        USER_MANAGED = 'user_managed'


    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.
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        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.
        - `degraded`: This is share is participating in replication, but the replica's
        data has fallen behind 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.
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        ACTIVE = 'active'
        DEGRADED = 'degraded'
        FAILOVER_PENDING = 'failover_pending'
        INITIALIZING = 'initializing'
        NONE = 'none'
        SPLIT_PENDING = 'split_pending'


    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        SHARE = 'share'



class ShareAccessorBinding:
    """
    ShareAccessorBinding.

    :param ShareAccessorBindingAccessor accessor: The accessor for this share
          accessor binding.
          The resources supported by this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :param datetime created_at: The date and time that the share accessor binding
          was created.
    :param str href: The URL for this share accessor binding.
    :param str id: The unique identifier for this share accessor binding.
    :param str lifecycle_state: The lifecycle state of the file share accessor
          binding.
    :param str resource_type: The resource type.
    """

    def __init__(
        self,
        accessor: 'ShareAccessorBindingAccessor',
        created_at: datetime,
        href: str,
        id: str,
        lifecycle_state: str,
        resource_type: str,
    ) -> None:
        """
        Initialize a ShareAccessorBinding object.

        :param ShareAccessorBindingAccessor accessor: The accessor for this share
               accessor binding.
               The resources supported by this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :param datetime created_at: The date and time that the share accessor
               binding was created.
        :param str href: The URL for this share accessor binding.
        :param str id: The unique identifier for this share accessor binding.
        :param str lifecycle_state: The lifecycle state of the file share accessor
               binding.
        :param str resource_type: The resource type.
        """
        self.accessor = accessor
        self.created_at = created_at
        self.href = href
        self.id = id
        self.lifecycle_state = lifecycle_state
        self.resource_type = resource_type

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

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

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

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

    def __ne__(self, other: 'ShareAccessorBinding') -> 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 file share accessor binding.
        """

        DELETING = 'deleting'
        FAILED = 'failed'
        PENDING = 'pending'
        STABLE = 'stable'
        SUSPENDED = 'suspended'
        UPDATING = 'updating'
        WAITING = 'waiting'


    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        SHARE_ACCESSOR_BINDING = 'share_accessor_binding'



class ShareAccessorBindingAccessor:
    """
    The accessor for this share accessor binding.
    The resources supported by this property may
    [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the future.

    """

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

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


class ShareAccessorBindingCollection:
    """
    ShareAccessorBindingCollection.

    :param List[ShareAccessorBinding] accessor_bindings: A page of accessor bindings
          for the share.
    :param PageLink 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 PageLink next: (optional) A link to the next page of resources. This
          property is present for all pages
          except the last page.
    :param int total_count: The total number of resources across all pages.
    """

    def __init__(
        self,
        accessor_bindings: List['ShareAccessorBinding'],
        first: 'PageLink',
        limit: int,
        total_count: int,
        *,
        next: Optional['PageLink'] = None,
    ) -> None:
        """
        Initialize a ShareAccessorBindingCollection object.

        :param List[ShareAccessorBinding] accessor_bindings: A page of accessor
               bindings for the share.
        :param PageLink 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 PageLink next: (optional) A link to the next page of resources. This
               property is present for all pages
               except the last page.
        """
        self.accessor_bindings = accessor_bindings
        self.first = first
        self.limit = limit
        self.next = next
        self.total_count = total_count

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ShareAccessorBindingCollection':
        """Initialize a ShareAccessorBindingCollection object from a json dictionary."""
        args = {}
        if (accessor_bindings := _dict.get('accessor_bindings')) is not None:
            args['accessor_bindings'] = [ShareAccessorBinding.from_dict(v) for v in accessor_bindings]
        else:
            raise ValueError('Required property \'accessor_bindings\' not present in ShareAccessorBindingCollection JSON')
        if (first := _dict.get('first')) is not None:
            args['first'] = PageLink.from_dict(first)
        else:
            raise ValueError('Required property \'first\' not present in ShareAccessorBindingCollection JSON')
        if (limit := _dict.get('limit')) is not None:
            args['limit'] = limit
        else:
            raise ValueError('Required property \'limit\' not present in ShareAccessorBindingCollection JSON')
        if (next := _dict.get('next')) is not None:
            args['next'] = PageLink.from_dict(next)
        if (total_count := _dict.get('total_count')) is not None:
            args['total_count'] = total_count
        else:
            raise ValueError('Required property \'total_count\' not present in ShareAccessorBindingCollection JSON')
        return cls(**args)

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

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'accessor_bindings') and self.accessor_bindings is not None:
            accessor_bindings_list = []
            for v in self.accessor_bindings:
                if isinstance(v, dict):
                    accessor_bindings_list.append(v)
                else:
                    accessor_bindings_list.append(v.to_dict())
            _dict['accessor_bindings'] = accessor_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 ShareAccessorBindingCollection object."""
        return json.dumps(self.to_dict(), indent=2)

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

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


class ShareAccessorBindingReference:
    """
    ShareAccessorBindingReference.

    :param str href: The URL for this share accessor binding.
    :param str id: The unique identifier for this share accessor binding.
    :param str resource_type: The resource type.
    """

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

        :param str href: The URL for this share accessor binding.
        :param str id: The unique identifier for this share accessor binding.
        :param str resource_type: The resource type.
        """
        self.href = href
        self.id = id
        self.resource_type = resource_type

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

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

    def to_dict(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, '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 ShareAccessorBindingReference object."""
        return json.dumps(self.to_dict(), indent=2)

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

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

    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        SHARE_ACCESSOR_BINDING = 'share_accessor_binding'



class ShareCollection:
    """
    ShareCollection.

    :param PageLink 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 PageLink next: (optional) A link to the next page of resources. This
          property is present for all pages
          except the last page.
    :param List[Share] shares: A page of file shares.
    :param int total_count: The total number of resources across all pages.
    """

    def __init__(
        self,
        first: 'PageLink',
        limit: int,
        shares: List['Share'],
        total_count: int,
        *,
        next: Optional['PageLink'] = None,
    ) -> None:
        """
        Initialize a ShareCollection object.

        :param PageLink 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: A page of file shares.
        :param int total_count: The total number of resources across all pages.
        :param PageLink 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 := _dict.get('first')) is not None:
            args['first'] = PageLink.from_dict(first)
        else:
            raise ValueError('Required property \'first\' not present in ShareCollection JSON')
        if (limit := _dict.get('limit')) is not None:
            args['limit'] = limit
        else:
            raise ValueError('Required property \'limit\' not present in ShareCollection JSON')
        if (next := _dict.get('next')) is not None:
            args['next'] = PageLink.from_dict(next)
        if (shares := _dict.get('shares')) is not None:
            args['shares'] = [Share.from_dict(v) for v in shares]
        else:
            raise ValueError('Required property \'shares\' not present in ShareCollection JSON')
        if (total_count := _dict.get('total_count')) is not None:
            args['total_count'] = 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 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.

    :param int gid: (optional) The initial group identifier for the file share.
    :param int uid: (optional) The initial user identifier for the file share.
    """

    def __init__(
        self,
        *,
        gid: Optional[int] = None,
        uid: Optional[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 := _dict.get('gid')) is not None:
            args['gid'] = gid
        if (uid := _dict.get('uid')) is not None:
            args['uid'] = 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.

    :param str status: The status of the file share job:
          - `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.
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :param List[ShareJobStatusReason] status_reasons: The reasons for the file share
          job status (if any).
    :param str type: The type of the file share job:
          - `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.
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    """

    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:
               - `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.
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :param List[ShareJobStatusReason] status_reasons: The reasons for the file
               share job status (if any).
        :param str type: The type of the file share job:
               - `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.
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        """
        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 := _dict.get('status')) is not None:
            args['status'] = status
        else:
            raise ValueError('Required property \'status\' not present in ShareJob JSON')
        if (status_reasons := _dict.get('status_reasons')) is not None:
            args['status_reasons'] = [ShareJobStatusReason.from_dict(v) for v in status_reasons]
        else:
            raise ValueError('Required property \'status_reasons\' not present in ShareJob JSON')
        if (type := _dict.get('type')) is not None:
            args['type'] = 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:
        - `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.
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        CANCELLED = 'cancelled'
        FAILED = 'failed'
        QUEUED = 'queued'
        RUNNING = 'running'
        SUCCEEDED = 'succeeded'


    class TypeEnum(str, Enum):
        """
        The type of the file share job:
        - `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.
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        REPLICATION_FAILOVER = 'replication_failover'
        REPLICATION_INIT = 'replication_init'
        REPLICATION_SPLIT = 'replication_split'



class ShareJobStatusReason:
    """
    ShareJobStatusReason.

    :param str code: A snake case string succinctly identifying the status reason.
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :param str message: An explanation of the status reason.
    :param str more_info: (optional) Link to documentation about this status reason.
    """

    def __init__(
        self,
        code: str,
        message: str,
        *,
        more_info: Optional[str] = None,
    ) -> None:
        """
        Initialize a ShareJobStatusReason object.

        :param str code: A snake case string succinctly identifying the status
               reason.
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :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 := _dict.get('code')) is not None:
            args['code'] = code
        else:
            raise ValueError('Required property \'code\' not present in ShareJobStatusReason JSON')
        if (message := _dict.get('message')) is not None:
            args['message'] = message
        else:
            raise ValueError('Required property \'message\' not present in ShareJobStatusReason JSON')
        if (more_info := _dict.get('more_info')) is not None:
            args['more_info'] = 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.
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        CANNOT_INITIALIZE_REPLICATION = 'cannot_initialize_replication'
        CANNOT_REACH_REPLICA_SHARE = 'cannot_reach_replica_share'
        CANNOT_REACH_SOURCE_SHARE = 'cannot_reach_source_share'



class ShareLatestSync:
    """
    Information about the latest synchronization for this file share.
    This property will be present when the `replication_role` is `replica` and at least
    one replication sync has been completed.

    :param datetime completed_at: The completed date and time of last
          synchronization between the replica share and its source.
    :param int data_transferred: The data transferred (in bytes) in the last
          synchronization between the replica and its source.
    :param datetime started_at: The start date and time of last synchronization
          between the replica share and its source.
    """

    def __init__(
        self,
        completed_at: datetime,
        data_transferred: int,
        started_at: datetime,
    ) -> None:
        """
        Initialize a ShareLatestSync object.

        :param datetime completed_at: The completed date and time of last
               synchronization between the replica share and its source.
        :param int data_transferred: The data transferred (in bytes) in the last
               synchronization between the replica and its source.
        :param datetime started_at: The start date and time of last synchronization
               between the replica share and its source.
        """
        self.completed_at = completed_at
        self.data_transferred = data_transferred
        self.started_at = started_at

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

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

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

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


class ShareLifecycleReason:
    """
    ShareLifecycleReason.

    :param str code: A reason code for this lifecycle state:
          - `origin_share_access_revoked`: The resource has been revoked by the share
          owner
          - `internal_error`: internal error (contact IBM support)
          - `resource_suspended_by_provider`: The resource has been suspended (contact IBM
            support)
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :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.
    """

    def __init__(
        self,
        code: str,
        message: str,
        *,
        more_info: Optional[str] = None,
    ) -> None:
        """
        Initialize a ShareLifecycleReason object.

        :param str code: A reason code for this lifecycle state:
               - `origin_share_access_revoked`: The resource has been revoked by the share
               owner
               - `internal_error`: internal error (contact IBM support)
               - `resource_suspended_by_provider`: The resource has been suspended
               (contact IBM
                 support)
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :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) -> 'ShareLifecycleReason':
        """Initialize a ShareLifecycleReason object from a json dictionary."""
        args = {}
        if (code := _dict.get('code')) is not None:
            args['code'] = code
        else:
            raise ValueError('Required property \'code\' not present in ShareLifecycleReason JSON')
        if (message := _dict.get('message')) is not None:
            args['message'] = message
        else:
            raise ValueError('Required property \'message\' not present in ShareLifecycleReason JSON')
        if (more_info := _dict.get('more_info')) is not None:
            args['more_info'] = more_info
        return cls(**args)

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

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

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

    class CodeEnum(str, Enum):
        """
        A reason code for this lifecycle state:
        - `origin_share_access_revoked`: The resource has been revoked by the share owner
        - `internal_error`: internal error (contact IBM support)
        - `resource_suspended_by_provider`: The resource has been suspended (contact IBM
          support)
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        INTERNAL_ERROR = 'internal_error'
        ORIGIN_SHARE_ACCESS_REVOKED = 'origin_share_access_revoked'
        RESOURCE_SUSPENDED_BY_PROVIDER = 'resource_suspended_by_provider'



class ShareMountTarget:
    """
    ShareMountTarget.

    :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 values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :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 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 str name: The name for this share mount target. The name is unique across
          all mount targets for the file share.
    :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 str resource_type: The resource type.
    :param SubnetReference subnet: (optional) The subnet of the virtual network
          interface for the share mount target.
          Absent if `access_control_mode` is `vpc`.
    :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 may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :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`.
    :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.
    """

    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: Optional[str] = None,
        primary_ip: Optional['ReservedIPReference'] = None,
        subnet: Optional['SubnetReference'] = None,
        virtual_network_interface: Optional['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 values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :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 may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :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 := _dict.get('access_control_mode')) is not None:
            args['access_control_mode'] = access_control_mode
        else:
            raise ValueError('Required property \'access_control_mode\' not present in ShareMountTarget JSON')
        if (created_at := _dict.get('created_at')) is not None:
            args['created_at'] = string_to_datetime(created_at)
        else:
            raise ValueError('Required property \'created_at\' not present in ShareMountTarget JSON')
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in ShareMountTarget JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in ShareMountTarget JSON')
        if (lifecycle_state := _dict.get('lifecycle_state')) is not None:
            args['lifecycle_state'] = lifecycle_state
        else:
            raise ValueError('Required property \'lifecycle_state\' not present in ShareMountTarget JSON')
        if (mount_path := _dict.get('mount_path')) is not None:
            args['mount_path'] = mount_path
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in ShareMountTarget JSON')
        if (primary_ip := _dict.get('primary_ip')) is not None:
            args['primary_ip'] = ReservedIPReference.from_dict(primary_ip)
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = resource_type
        else:
            raise ValueError('Required property \'resource_type\' not present in ShareMountTarget JSON')
        if (subnet := _dict.get('subnet')) is not None:
            args['subnet'] = SubnetReference.from_dict(subnet)
        if (transit_encryption := _dict.get('transit_encryption')) is not None:
            args['transit_encryption'] = transit_encryption
        else:
            raise ValueError('Required property \'transit_encryption\' not present in ShareMountTarget JSON')
        if (virtual_network_interface := _dict.get('virtual_network_interface')) is not None:
            args['virtual_network_interface'] = VirtualNetworkInterfaceReferenceAttachmentContext.from_dict(virtual_network_interface)
        if (vpc := _dict.get('vpc')) is not None:
            args['vpc'] = VPCReference.from_dict(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 values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        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 may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        NONE = 'none'
        USER_MANAGED = 'user_managed'



class ShareMountTargetCollection:
    """
    ShareMountTargetCollection.

    :param PageLink 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: A page of mount targets for the
          share.
    :param PageLink next: (optional) A link to the next page of resources. This
          property is present for all pages
          except the last page.
    :param int total_count: The total number of resources across all pages.
    """

    def __init__(
        self,
        first: 'PageLink',
        limit: int,
        mount_targets: List['ShareMountTarget'],
        total_count: int,
        *,
        next: Optional['PageLink'] = None,
    ) -> None:
        """
        Initialize a ShareMountTargetCollection object.

        :param PageLink 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: A page of mount targets for
               the share.
        :param int total_count: The total number of resources across all pages.
        :param PageLink 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 := _dict.get('first')) is not None:
            args['first'] = PageLink.from_dict(first)
        else:
            raise ValueError('Required property \'first\' not present in ShareMountTargetCollection JSON')
        if (limit := _dict.get('limit')) is not None:
            args['limit'] = limit
        else:
            raise ValueError('Required property \'limit\' not present in ShareMountTargetCollection JSON')
        if (mount_targets := _dict.get('mount_targets')) is not None:
            args['mount_targets'] = [ShareMountTarget.from_dict(v) for v in mount_targets]
        else:
            raise ValueError('Required property \'mount_targets\' not present in ShareMountTargetCollection JSON')
        if (next := _dict.get('next')) is not None:
            args['next'] = PageLink.from_dict(next)
        if (total_count := _dict.get('total_count')) is not None:
            args['total_count'] = 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 ShareMountTargetPatch:
    """
    ShareMountTargetPatch.

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

    def __init__(
        self,
        *,
        name: Optional[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 := _dict.get('name')) is not None:
            args['name'] = 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.

    :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`.
          The specified value must be listed in the share's
          `allowed_transit_encryption_modes`.
    """

    def __init__(
        self,
        *,
        name: Optional[str] = None,
        transit_encryption: Optional[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`.
               The specified value must be listed in the share's
               `allowed_transit_encryption_modes`.
        """
        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`.
        The specified value must be listed in the share's
        `allowed_transit_encryption_modes`.
        """

        NONE = 'none'
        USER_MANAGED = 'user_managed'



class ShareMountTargetReference:
    """
    ShareMountTargetReference.

    :param Deleted deleted: (optional) If present, this property indicates the
          referenced resource has been deleted, and provides
          some supplementary information.
    :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.
    """

    def __init__(
        self,
        href: str,
        id: str,
        name: str,
        resource_type: str,
        *,
        deleted: Optional['Deleted'] = 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 Deleted 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 := _dict.get('deleted')) is not None:
            args['deleted'] = Deleted.from_dict(deleted)
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in ShareMountTargetReference JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in ShareMountTargetReference JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in ShareMountTargetReference JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = 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 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', 'ShareMountTargetVirtualNetworkInterfacePrototypeVirtualNetworkInterfaceIdentity'])
        )
        raise Exception(msg)


class SharePatch:
    """
    SharePatch.

    :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,
          `replication_role` must be `none` and `accessor_binding_role` must not be
          `accessor`.
    :param List[str] allowed_transit_encryption_modes: (optional) The transit
          encryption modes to allow for this share.
          For this property to be updated, the `accessor_binding_role` must be `none`.
    :param int iops: (optional) 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. For this property to be
          changed, the share `accessor_binding_role` must not be `accessor`.
    :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 every 15 minutes.
          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`
          - The share `replication_role` must not be `replica`
          - The share `accessor_binding_role` must not be `accessor`.
    :param List[str] user_tags: (optional) Tags for this resource.
    """

    def __init__(
        self,
        *,
        access_control_mode: Optional[str] = None,
        allowed_transit_encryption_modes: Optional[List[str]] = None,
        iops: Optional[int] = None,
        name: Optional[str] = None,
        profile: Optional['ShareProfileIdentity'] = None,
        replication_cron_spec: Optional[str] = None,
        size: Optional[int] = None,
        user_tags: Optional[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,
               `replication_role` must be `none` and `accessor_binding_role` must not be
               `accessor`.
        :param List[str] allowed_transit_encryption_modes: (optional) The transit
               encryption modes to allow for this share.
               For this property to be updated, the `accessor_binding_role` must be
               `none`.
        :param int iops: (optional) 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. For this property
               to be changed, the share `accessor_binding_role` must not be `accessor`.
        :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 every 15
               minutes.
               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`
               - The share `replication_role` must not be `replica`
               - The share `accessor_binding_role` must not be `accessor`.
        :param List[str] user_tags: (optional) Tags for this resource.
        """
        self.access_control_mode = access_control_mode
        self.allowed_transit_encryption_modes = allowed_transit_encryption_modes
        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 := _dict.get('access_control_mode')) is not None:
            args['access_control_mode'] = access_control_mode
        if (allowed_transit_encryption_modes := _dict.get('allowed_transit_encryption_modes')) is not None:
            args['allowed_transit_encryption_modes'] = allowed_transit_encryption_modes
        if (iops := _dict.get('iops')) is not None:
            args['iops'] = iops
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        if (profile := _dict.get('profile')) is not None:
            args['profile'] = profile
        if (replication_cron_spec := _dict.get('replication_cron_spec')) is not None:
            args['replication_cron_spec'] = replication_cron_spec
        if (size := _dict.get('size')) is not None:
            args['size'] = size
        if (user_tags := _dict.get('user_tags')) is not None:
            args['user_tags'] = 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, 'allowed_transit_encryption_modes') and self.allowed_transit_encryption_modes is not None:
            _dict['allowed_transit_encryption_modes'] = self.allowed_transit_encryption_modes
        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,
        `replication_role` must be `none` and `accessor_binding_role` must not be
        `accessor`.
        """

        SECURITY_GROUP = 'security_group'
        VPC = 'vpc'


    class AllowedTransitEncryptionModesEnum(str, Enum):
        """
        An allowed transit encryption mode for this share.
        - `none`: Not encrypted in transit.
        - `user_managed`: Encrypted in transit using an instance identity certificate.
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        NONE = 'none'
        USER_MANAGED = 'user_managed'



class ShareProfile:
    """
    ShareProfile.

    :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.
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :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.
    """

    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.
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :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 := _dict.get('capacity')) is not None:
            args['capacity'] = capacity
        else:
            raise ValueError('Required property \'capacity\' not present in ShareProfile JSON')
        if (family := _dict.get('family')) is not None:
            args['family'] = family
        else:
            raise ValueError('Required property \'family\' not present in ShareProfile JSON')
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in ShareProfile JSON')
        if (iops := _dict.get('iops')) is not None:
            args['iops'] = iops
        else:
            raise ValueError('Required property \'iops\' not present in ShareProfile JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in ShareProfile JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = 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.
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        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', 'ShareProfileCapacityEnum', 'ShareProfileCapacityRange', 'ShareProfileCapacityDependentRange'])
        )
        raise Exception(msg)


class ShareProfileCollection:
    """
    ShareProfileCollection.

    :param PageLink 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 PageLink next: (optional) A link to the next page of resources. This
          property is present for all pages
          except the last page.
    :param List[ShareProfile] profiles: A page of share profiles.
    :param int total_count: The total number of resources across all pages.
    """

    def __init__(
        self,
        first: 'PageLink',
        limit: int,
        profiles: List['ShareProfile'],
        total_count: int,
        *,
        next: Optional['PageLink'] = None,
    ) -> None:
        """
        Initialize a ShareProfileCollection object.

        :param PageLink 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: A page of share profiles.
        :param int total_count: The total number of resources across all pages.
        :param PageLink 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 := _dict.get('first')) is not None:
            args['first'] = PageLink.from_dict(first)
        else:
            raise ValueError('Required property \'first\' not present in ShareProfileCollection JSON')
        if (limit := _dict.get('limit')) is not None:
            args['limit'] = limit
        else:
            raise ValueError('Required property \'limit\' not present in ShareProfileCollection JSON')
        if (next := _dict.get('next')) is not None:
            args['next'] = PageLink.from_dict(next)
        if (profiles := _dict.get('profiles')) is not None:
            args['profiles'] = [ShareProfile.from_dict(v) for v in profiles]
        else:
            raise ValueError('Required property \'profiles\' not present in ShareProfileCollection JSON')
        if (total_count := _dict.get('total_count')) is not None:
            args['total_count'] = 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 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.

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

    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 := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in ShareProfileReference JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in ShareProfileReference JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = 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.

    :param List[str] allowed_transit_encryption_modes: (optional) The transit
          encryption modes to allow for this share. If unspecified:
          - If share mount targets are specified, and those share mount targets all
          specify a
            `transit_encryption` of `user_managed`, then only `user_managed` will be
          allowed.
          - Otherwise, all `transit_encryption` modes will be allowed.
    :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.
    """

    def __init__(
        self,
        *,
        allowed_transit_encryption_modes: Optional[List[str]] = None,
        mount_targets: Optional[List['ShareMountTargetPrototype']] = None,
        name: Optional[str] = None,
        replica_share: Optional['SharePrototypeShareContext'] = None,
        user_tags: Optional[List[str]] = None,
    ) -> None:
        """
        Initialize a SharePrototype object.

        :param List[str] allowed_transit_encryption_modes: (optional) The transit
               encryption modes to allow for this share. If unspecified:
               - If share mount targets are specified, and those share mount targets all
               specify a
                 `transit_encryption` of `user_managed`, then only `user_managed` will be
               allowed.
               - Otherwise, all `transit_encryption` modes will be allowed.
        :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', 'SharePrototypeShareByOriginShare'])
        )
        raise Exception(msg)

    class AllowedTransitEncryptionModesEnum(str, Enum):
        """
        An allowed transit encryption mode for this share.
        - `none`: Not encrypted in transit.
        - `user_managed`: Encrypted in transit using an instance identity certificate.
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        NONE = 'none'
        USER_MANAGED = 'user_managed'



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.

    :param List[str] allowed_transit_encryption_modes: (optional) The transit
          encryption modes to allow for this share. If unspecified:
          - If share mount targets are specified, and those share mount targets all
          specify a
            `transit_encryption` of `user_managed`, then only `user_managed` will be
          allowed.
          - Otherwise, all `transit_encryption` modes will be allowed.
    :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 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 every 15 minutes.
    :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.
    :param ZoneIdentity zone: The zone this replica file share will reside in. For a
          replica share in the same
          region as the source share, this must be a different zone from the source share.
    """

    def __init__(
        self,
        profile: 'ShareProfileIdentity',
        replication_cron_spec: str,
        zone: 'ZoneIdentity',
        *,
        allowed_transit_encryption_modes: Optional[List[str]] = None,
        iops: Optional[int] = None,
        mount_targets: Optional[List['ShareMountTargetPrototype']] = None,
        name: Optional[str] = None,
        resource_group: Optional['ResourceGroupIdentity'] = None,
        user_tags: Optional[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 every 15
               minutes.
        :param ZoneIdentity zone: The zone this replica file share will reside in.
               For a replica share in the same
               region as the source share, this must be a different zone from the source
               share.
        :param List[str] allowed_transit_encryption_modes: (optional) The transit
               encryption modes to allow for this share. If unspecified:
               - If share mount targets are specified, and those share mount targets all
               specify a
                 `transit_encryption` of `user_managed`, then only `user_managed` will be
               allowed.
               - Otherwise, all `transit_encryption` modes will be allowed.
        :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.allowed_transit_encryption_modes = allowed_transit_encryption_modes
        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 (allowed_transit_encryption_modes := _dict.get('allowed_transit_encryption_modes')) is not None:
            args['allowed_transit_encryption_modes'] = allowed_transit_encryption_modes
        if (iops := _dict.get('iops')) is not None:
            args['iops'] = iops
        if (mount_targets := _dict.get('mount_targets')) is not None:
            args['mount_targets'] = mount_targets
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        if (profile := _dict.get('profile')) is not None:
            args['profile'] = profile
        else:
            raise ValueError('Required property \'profile\' not present in SharePrototypeShareContext JSON')
        if (replication_cron_spec := _dict.get('replication_cron_spec')) is not None:
            args['replication_cron_spec'] = replication_cron_spec
        else:
            raise ValueError('Required property \'replication_cron_spec\' not present in SharePrototypeShareContext JSON')
        if (resource_group := _dict.get('resource_group')) is not None:
            args['resource_group'] = resource_group
        if (user_tags := _dict.get('user_tags')) is not None:
            args['user_tags'] = user_tags
        if (zone := _dict.get('zone')) is not None:
            args['zone'] = 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, 'allowed_transit_encryption_modes') and self.allowed_transit_encryption_modes is not None:
            _dict['allowed_transit_encryption_modes'] = self.allowed_transit_encryption_modes
        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 AllowedTransitEncryptionModesEnum(str, Enum):
        """
        An allowed transit encryption mode for this share.
        - `none`: Not encrypted in transit.
        - `user_managed`: Encrypted in transit using an instance identity certificate.
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        NONE = 'none'
        USER_MANAGED = 'user_managed'



class ShareReference:
    """
    ShareReference.

    :param str crn: The CRN for this file share.
    :param Deleted deleted: (optional) If present, this property indicates the
          referenced resource has been deleted, and provides
          some supplementary information.
    :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 ShareRemote remote: (optional) If present, this property indicates that
          the resource associated with this reference
          is remote and therefore may not be directly retrievable.
    :param str resource_type: The resource type.
    """

    def __init__(
        self,
        crn: str,
        href: str,
        id: str,
        name: str,
        resource_type: str,
        *,
        deleted: Optional['Deleted'] = None,
        remote: Optional['ShareRemote'] = 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 Deleted deleted: (optional) If present, this property indicates the
               referenced resource has been deleted, and provides
               some supplementary information.
        :param ShareRemote 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) -> 'ShareReference':
        """Initialize a ShareReference object from a json dictionary."""
        args = {}
        if (crn := _dict.get('crn')) is not None:
            args['crn'] = crn
        else:
            raise ValueError('Required property \'crn\' not present in ShareReference JSON')
        if (deleted := _dict.get('deleted')) is not None:
            args['deleted'] = Deleted.from_dict(deleted)
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in ShareReference JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in ShareReference JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in ShareReference JSON')
        if (remote := _dict.get('remote')) is not None:
            args['remote'] = ShareRemote.from_dict(remote)
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = 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, '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 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 ShareRemote:
    """
    If present, this property indicates that the resource associated with this reference
    is remote and therefore may not be directly retrievable.

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

    def __init__(
        self,
        *,
        account: Optional['AccountReference'] = None,
        region: Optional['RegionReference'] = None,
    ) -> None:
        """
        Initialize a ShareRemote 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) -> 'ShareRemote':
        """Initialize a ShareRemote object from a json dictionary."""
        args = {}
        if (account := _dict.get('account')) is not None:
            args['account'] = AccountReference.from_dict(account)
        if (region := _dict.get('region')) is not None:
            args['region'] = RegionReference.from_dict(region)
        return cls(**args)

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

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

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


class ShareReplicationStatusReason:
    """
    ShareReplicationStatusReason.

    :param str code: A snake case string succinctly identifying the status reason.
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :param str message: An explanation of the status reason.
    :param str more_info: (optional) Link to documentation about this status reason.
    """

    def __init__(
        self,
        code: str,
        message: str,
        *,
        more_info: Optional[str] = None,
    ) -> None:
        """
        Initialize a ShareReplicationStatusReason object.

        :param str code: A snake case string succinctly identifying the status
               reason.
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :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 := _dict.get('code')) is not None:
            args['code'] = code
        else:
            raise ValueError('Required property \'code\' not present in ShareReplicationStatusReason JSON')
        if (message := _dict.get('message')) is not None:
            args['message'] = message
        else:
            raise ValueError('Required property \'message\' not present in ShareReplicationStatusReason JSON')
        if (more_info := _dict.get('more_info')) is not None:
            args['more_info'] = 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.
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        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.

    :param BackupPolicyPlanReference backup_policy_plan: (optional) If present, the
          backup policy plan which created this snapshot.
    :param bool bootable: Indicates if a boot volume attachment can be created with
          a volume created from 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 SnapshotCatalogOffering catalog_offering: (optional) The
          [catalog](https://cloud.ibm.com/docs/account?topic=account-restrict-by-user)
          offering inherited from the snapshot's source. If a virtual server instance is
          provisioned with a `source_snapshot` specifying this snapshot, the virtual
          server
          instance will use this snapshot's catalog offering, including its pricing plan.
          If absent, this snapshot is not associated with a catalog offering.
    :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 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 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 OperatingSystem operating_system: (optional) The operating system
          included in this snapshot.
    :param int progress: Indicates the progress (as a percentage) of storing this
          snapshot. Only stored snapshots can be used for restoration.
    :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 SnapshotConsistencyGroupReference snapshot_consistency_group: (optional)
          If present, the snapshot consistency group which created 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.
    :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.
    """

    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,
        progress: int,
        resource_group: 'ResourceGroupReference',
        resource_type: str,
        service_tags: List[str],
        size: int,
        source_volume: 'VolumeReference',
        user_tags: List[str],
        *,
        backup_policy_plan: Optional['BackupPolicyPlanReference'] = None,
        captured_at: Optional[datetime] = None,
        catalog_offering: Optional['SnapshotCatalogOffering'] = None,
        encryption_key: Optional['EncryptionKeyReference'] = None,
        operating_system: Optional['OperatingSystem'] = None,
        snapshot_consistency_group: Optional['SnapshotConsistencyGroupReference'] = None,
        source_image: Optional['ImageReference'] = None,
        source_snapshot: Optional['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 int progress: Indicates the progress (as a percentage) of storing
               this snapshot. Only stored snapshots can be used for restoration.
        :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 SnapshotCatalogOffering catalog_offering: (optional) The
               [catalog](https://cloud.ibm.com/docs/account?topic=account-restrict-by-user)
               offering inherited from the snapshot's source. If a virtual server instance
               is
               provisioned with a `source_snapshot` specifying this snapshot, the virtual
               server
               instance will use this snapshot's catalog offering, including its pricing
               plan.
               If absent, this snapshot is not associated with a catalog offering.
        :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 SnapshotConsistencyGroupReference snapshot_consistency_group:
               (optional) If present, the snapshot consistency group which created 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.catalog_offering = catalog_offering
        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.progress = progress
        self.resource_group = resource_group
        self.resource_type = resource_type
        self.service_tags = service_tags
        self.size = size
        self.snapshot_consistency_group = snapshot_consistency_group
        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 := _dict.get('backup_policy_plan')) is not None:
            args['backup_policy_plan'] = BackupPolicyPlanReference.from_dict(backup_policy_plan)
        if (bootable := _dict.get('bootable')) is not None:
            args['bootable'] = bootable
        else:
            raise ValueError('Required property \'bootable\' not present in Snapshot JSON')
        if (captured_at := _dict.get('captured_at')) is not None:
            args['captured_at'] = string_to_datetime(captured_at)
        if (catalog_offering := _dict.get('catalog_offering')) is not None:
            args['catalog_offering'] = SnapshotCatalogOffering.from_dict(catalog_offering)
        if (clones := _dict.get('clones')) is not None:
            args['clones'] = [SnapshotClone.from_dict(v) for v in clones]
        else:
            raise ValueError('Required property \'clones\' not present in Snapshot JSON')
        if (copies := _dict.get('copies')) is not None:
            args['copies'] = [SnapshotCopiesItem.from_dict(v) for v in copies]
        else:
            raise ValueError('Required property \'copies\' not present in Snapshot JSON')
        if (created_at := _dict.get('created_at')) is not None:
            args['created_at'] = string_to_datetime(created_at)
        else:
            raise ValueError('Required property \'created_at\' not present in Snapshot JSON')
        if (crn := _dict.get('crn')) is not None:
            args['crn'] = crn
        else:
            raise ValueError('Required property \'crn\' not present in Snapshot JSON')
        if (deletable := _dict.get('deletable')) is not None:
            args['deletable'] = deletable
        else:
            raise ValueError('Required property \'deletable\' not present in Snapshot JSON')
        if (encryption := _dict.get('encryption')) is not None:
            args['encryption'] = encryption
        else:
            raise ValueError('Required property \'encryption\' not present in Snapshot JSON')
        if (encryption_key := _dict.get('encryption_key')) is not None:
            args['encryption_key'] = EncryptionKeyReference.from_dict(encryption_key)
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in Snapshot JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in Snapshot JSON')
        if (lifecycle_state := _dict.get('lifecycle_state')) is not None:
            args['lifecycle_state'] = lifecycle_state
        else:
            raise ValueError('Required property \'lifecycle_state\' not present in Snapshot JSON')
        if (minimum_capacity := _dict.get('minimum_capacity')) is not None:
            args['minimum_capacity'] = minimum_capacity
        else:
            raise ValueError('Required property \'minimum_capacity\' not present in Snapshot JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in Snapshot JSON')
        if (operating_system := _dict.get('operating_system')) is not None:
            args['operating_system'] = OperatingSystem.from_dict(operating_system)
        if (progress := _dict.get('progress')) is not None:
            args['progress'] = progress
        else:
            raise ValueError('Required property \'progress\' not present in Snapshot JSON')
        if (resource_group := _dict.get('resource_group')) is not None:
            args['resource_group'] = ResourceGroupReference.from_dict(resource_group)
        else:
            raise ValueError('Required property \'resource_group\' not present in Snapshot JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = resource_type
        else:
            raise ValueError('Required property \'resource_type\' not present in Snapshot JSON')
        if (service_tags := _dict.get('service_tags')) is not None:
            args['service_tags'] = service_tags
        else:
            raise ValueError('Required property \'service_tags\' not present in Snapshot JSON')
        if (size := _dict.get('size')) is not None:
            args['size'] = size
        else:
            raise ValueError('Required property \'size\' not present in Snapshot JSON')
        if (snapshot_consistency_group := _dict.get('snapshot_consistency_group')) is not None:
            args['snapshot_consistency_group'] = SnapshotConsistencyGroupReference.from_dict(snapshot_consistency_group)
        if (source_image := _dict.get('source_image')) is not None:
            args['source_image'] = ImageReference.from_dict(source_image)
        if (source_snapshot := _dict.get('source_snapshot')) is not None:
            args['source_snapshot'] = SnapshotSourceSnapshot.from_dict(source_snapshot)
        if (source_volume := _dict.get('source_volume')) is not None:
            args['source_volume'] = VolumeReference.from_dict(source_volume)
        else:
            raise ValueError('Required property \'source_volume\' not present in Snapshot JSON')
        if (user_tags := _dict.get('user_tags')) is not None:
            args['user_tags'] = 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, '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, '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, 'progress') and self.progress is not None:
            _dict['progress'] = self.progress
        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, 'snapshot_consistency_group') and self.snapshot_consistency_group is not None:
            if isinstance(self.snapshot_consistency_group, dict):
                _dict['snapshot_consistency_group'] = self.snapshot_consistency_group
            else:
                _dict['snapshot_consistency_group'] = self.snapshot_consistency_group.to_dict()
        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 SnapshotCatalogOffering:
    """
    SnapshotCatalogOffering.

    :param CatalogOfferingVersionPlanReference plan: (optional) The billing plan
          associated with the catalog offering version.
          If absent, no billing plan is associated with the catalog offering version
          (free).
    :param CatalogOfferingVersionReference version: The
          [catalog](https://cloud.ibm.com/docs/account?topic=account-restrict-by-user)
          offering version contained in this snapshot.
    """

    def __init__(
        self,
        version: 'CatalogOfferingVersionReference',
        *,
        plan: Optional['CatalogOfferingVersionPlanReference'] = None,
    ) -> None:
        """
        Initialize a SnapshotCatalogOffering object.

        :param CatalogOfferingVersionReference version: The
               [catalog](https://cloud.ibm.com/docs/account?topic=account-restrict-by-user)
               offering version contained in this snapshot.
        :param CatalogOfferingVersionPlanReference plan: (optional) The billing
               plan associated with the catalog offering version.
               If absent, no billing plan is associated with the catalog offering version
               (free).
        """
        self.plan = plan
        self.version = version

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

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

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

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

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


class SnapshotClone:
    """
    SnapshotClone.

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

    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 := _dict.get('available')) is not None:
            args['available'] = available
        else:
            raise ValueError('Required property \'available\' not present in SnapshotClone JSON')
        if (created_at := _dict.get('created_at')) is not None:
            args['created_at'] = string_to_datetime(created_at)
        else:
            raise ValueError('Required property \'created_at\' not present in SnapshotClone JSON')
        if (zone := _dict.get('zone')) is not None:
            args['zone'] = ZoneReference.from_dict(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.

    :param List[SnapshotClone] clones: The clones for the snapshot.
    """

    def __init__(
        self,
        clones: List['SnapshotClone'],
    ) -> None:
        """
        Initialize a SnapshotCloneCollection object.

        :param List[SnapshotClone] clones: The clones for the snapshot.
        """
        self.clones = clones

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'SnapshotCloneCollection':
        """Initialize a SnapshotCloneCollection object from a json dictionary."""
        args = {}
        if (clones := _dict.get('clones')) is not None:
            args['clones'] = [SnapshotClone.from_dict(v) for v in 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.

    :param 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 := _dict.get('zone')) is not None:
            args['zone'] = 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.

    :param PageLink 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 PageLink next: (optional) A link to the next page of resources. This
          property is present for all pages
          except the last page.
    :param List[Snapshot] snapshots: A page of snapshots.
    :param int total_count: The total number of resources across all pages.
    """

    def __init__(
        self,
        first: 'PageLink',
        limit: int,
        snapshots: List['Snapshot'],
        total_count: int,
        *,
        next: Optional['PageLink'] = None,
    ) -> None:
        """
        Initialize a SnapshotCollection object.

        :param PageLink 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: A page of snapshots.
        :param int total_count: The total number of resources across all pages.
        :param PageLink 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 := _dict.get('first')) is not None:
            args['first'] = PageLink.from_dict(first)
        else:
            raise ValueError('Required property \'first\' not present in SnapshotCollection JSON')
        if (limit := _dict.get('limit')) is not None:
            args['limit'] = limit
        else:
            raise ValueError('Required property \'limit\' not present in SnapshotCollection JSON')
        if (next := _dict.get('next')) is not None:
            args['next'] = PageLink.from_dict(next)
        if (snapshots := _dict.get('snapshots')) is not None:
            args['snapshots'] = [Snapshot.from_dict(v) for v in snapshots]
        else:
            raise ValueError('Required property \'snapshots\' not present in SnapshotCollection JSON')
        if (total_count := _dict.get('total_count')) is not None:
            args['total_count'] = 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 SnapshotConsistencyGroup:
    """
    SnapshotConsistencyGroup.

    :param BackupPolicyPlanReference backup_policy_plan: (optional) If present, the
          backup policy plan which created this snapshot consistency group.
    :param datetime created_at: The date and time that this snapshot consistency
          group was created.
    :param str crn: The CRN of this snapshot consistency group.
    :param bool delete_snapshots_on_delete: Indicates whether deleting the snapshot
          consistency group will also delete the snapshots in the group.
    :param str href: The URL for this snapshot consistency group.
    :param str id: The unique identifier for this snapshot consistency group.
    :param str lifecycle_state: The lifecycle state of this snapshot consistency
          group.
    :param str name: The name for this snapshot consistency group. The name is
          unique across all snapshot consistency groups in the region.
    :param ResourceGroupReference resource_group: The resource group for this
          snapshot consistency group.
    :param str resource_type: The resource type.
    :param List[str] service_tags: The [service
          tags](https://cloud.ibm.com/apidocs/tagging#types-of-tags) associated with this
          snapshot consistency group. Each tag is prefixed with
          [is.instance:](https://cloud.ibm.com/docs/vpc?topic=vpc-snapshots-vpc-faqs).
    :param List[SnapshotReference] snapshots: The member snapshots that are
          data-consistent with respect to captured time. (may be
          [deleted](https://cloud.ibm.com/apidocs/vpc#deleted-resources)).
    """

    def __init__(
        self,
        created_at: datetime,
        crn: str,
        delete_snapshots_on_delete: bool,
        href: str,
        id: str,
        lifecycle_state: str,
        name: str,
        resource_group: 'ResourceGroupReference',
        resource_type: str,
        service_tags: List[str],
        snapshots: List['SnapshotReference'],
        *,
        backup_policy_plan: Optional['BackupPolicyPlanReference'] = None,
    ) -> None:
        """
        Initialize a SnapshotConsistencyGroup object.

        :param datetime created_at: The date and time that this snapshot
               consistency group was created.
        :param str crn: The CRN of this snapshot consistency group.
        :param bool delete_snapshots_on_delete: Indicates whether deleting the
               snapshot consistency group will also delete the snapshots in the group.
        :param str href: The URL for this snapshot consistency group.
        :param str id: The unique identifier for this snapshot consistency group.
        :param str lifecycle_state: The lifecycle state of this snapshot
               consistency group.
        :param str name: The name for this snapshot consistency group. The name is
               unique across all snapshot consistency groups in the region.
        :param ResourceGroupReference resource_group: The resource group for this
               snapshot consistency group.
        :param str resource_type: The resource type.
        :param List[str] service_tags: The [service
               tags](https://cloud.ibm.com/apidocs/tagging#types-of-tags) associated with
               this snapshot consistency group. Each tag is prefixed with
               [is.instance:](https://cloud.ibm.com/docs/vpc?topic=vpc-snapshots-vpc-faqs).
        :param List[SnapshotReference] snapshots: The member snapshots that are
               data-consistent with respect to captured time. (may be
               [deleted](https://cloud.ibm.com/apidocs/vpc#deleted-resources)).
        :param BackupPolicyPlanReference backup_policy_plan: (optional) If present,
               the backup policy plan which created this snapshot consistency group.
        """
        self.backup_policy_plan = backup_policy_plan
        self.created_at = created_at
        self.crn = crn
        self.delete_snapshots_on_delete = delete_snapshots_on_delete
        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.service_tags = service_tags
        self.snapshots = snapshots

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'SnapshotConsistencyGroup':
        """Initialize a SnapshotConsistencyGroup object from a json dictionary."""
        args = {}
        if (backup_policy_plan := _dict.get('backup_policy_plan')) is not None:
            args['backup_policy_plan'] = BackupPolicyPlanReference.from_dict(backup_policy_plan)
        if (created_at := _dict.get('created_at')) is not None:
            args['created_at'] = string_to_datetime(created_at)
        else:
            raise ValueError('Required property \'created_at\' not present in SnapshotConsistencyGroup JSON')
        if (crn := _dict.get('crn')) is not None:
            args['crn'] = crn
        else:
            raise ValueError('Required property \'crn\' not present in SnapshotConsistencyGroup JSON')
        if (delete_snapshots_on_delete := _dict.get('delete_snapshots_on_delete')) is not None:
            args['delete_snapshots_on_delete'] = delete_snapshots_on_delete
        else:
            raise ValueError('Required property \'delete_snapshots_on_delete\' not present in SnapshotConsistencyGroup JSON')
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in SnapshotConsistencyGroup JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in SnapshotConsistencyGroup JSON')
        if (lifecycle_state := _dict.get('lifecycle_state')) is not None:
            args['lifecycle_state'] = lifecycle_state
        else:
            raise ValueError('Required property \'lifecycle_state\' not present in SnapshotConsistencyGroup JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in SnapshotConsistencyGroup JSON')
        if (resource_group := _dict.get('resource_group')) is not None:
            args['resource_group'] = ResourceGroupReference.from_dict(resource_group)
        else:
            raise ValueError('Required property \'resource_group\' not present in SnapshotConsistencyGroup JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = resource_type
        else:
            raise ValueError('Required property \'resource_type\' not present in SnapshotConsistencyGroup JSON')
        if (service_tags := _dict.get('service_tags')) is not None:
            args['service_tags'] = service_tags
        else:
            raise ValueError('Required property \'service_tags\' not present in SnapshotConsistencyGroup JSON')
        if (snapshots := _dict.get('snapshots')) is not None:
            args['snapshots'] = [SnapshotReference.from_dict(v) for v in snapshots]
        else:
            raise ValueError('Required property \'snapshots\' not present in SnapshotConsistencyGroup JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SnapshotConsistencyGroup object from 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, '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, 'delete_snapshots_on_delete') and self.delete_snapshots_on_delete is not None:
            _dict['delete_snapshots_on_delete'] = self.delete_snapshots_on_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, '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, 'service_tags') and self.service_tags is not None:
            _dict['service_tags'] = self.service_tags
        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
        return _dict

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

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

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

    def __ne__(self, other: 'SnapshotConsistencyGroup') -> 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 snapshot consistency group.
        """

        DELETING = 'deleting'
        FAILED = 'failed'
        PENDING = 'pending'
        STABLE = 'stable'
        SUSPENDED = 'suspended'
        UPDATING = 'updating'
        WAITING = 'waiting'


    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        SNAPSHOT_CONSISTENCY_GROUP = 'snapshot_consistency_group'



class SnapshotConsistencyGroupCollection:
    """
    SnapshotConsistencyGroupCollection.

    :param PageLink 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 PageLink next: (optional) A link to the next page of resources. This
          property is present for all pages
          except the last page.
    :param List[SnapshotConsistencyGroup] snapshot_consistency_groups: A page of
          snapshot consistency groups.
    :param int total_count: The total number of resources across all pages.
    """

    def __init__(
        self,
        first: 'PageLink',
        limit: int,
        snapshot_consistency_groups: List['SnapshotConsistencyGroup'],
        total_count: int,
        *,
        next: Optional['PageLink'] = None,
    ) -> None:
        """
        Initialize a SnapshotConsistencyGroupCollection object.

        :param PageLink 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[SnapshotConsistencyGroup] snapshot_consistency_groups: A page
               of snapshot consistency groups.
        :param int total_count: The total number of resources across all pages.
        :param PageLink 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.snapshot_consistency_groups = snapshot_consistency_groups
        self.total_count = total_count

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'SnapshotConsistencyGroupCollection':
        """Initialize a SnapshotConsistencyGroupCollection object from a json dictionary."""
        args = {}
        if (first := _dict.get('first')) is not None:
            args['first'] = PageLink.from_dict(first)
        else:
            raise ValueError('Required property \'first\' not present in SnapshotConsistencyGroupCollection JSON')
        if (limit := _dict.get('limit')) is not None:
            args['limit'] = limit
        else:
            raise ValueError('Required property \'limit\' not present in SnapshotConsistencyGroupCollection JSON')
        if (next := _dict.get('next')) is not None:
            args['next'] = PageLink.from_dict(next)
        if (snapshot_consistency_groups := _dict.get('snapshot_consistency_groups')) is not None:
            args['snapshot_consistency_groups'] = [SnapshotConsistencyGroup.from_dict(v) for v in snapshot_consistency_groups]
        else:
            raise ValueError('Required property \'snapshot_consistency_groups\' not present in SnapshotConsistencyGroupCollection JSON')
        if (total_count := _dict.get('total_count')) is not None:
            args['total_count'] = total_count
        else:
            raise ValueError('Required property \'total_count\' not present in SnapshotConsistencyGroupCollection JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SnapshotConsistencyGroupCollection object from 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, 'snapshot_consistency_groups') and self.snapshot_consistency_groups is not None:
            snapshot_consistency_groups_list = []
            for v in self.snapshot_consistency_groups:
                if isinstance(v, dict):
                    snapshot_consistency_groups_list.append(v)
                else:
                    snapshot_consistency_groups_list.append(v.to_dict())
            _dict['snapshot_consistency_groups'] = snapshot_consistency_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 SnapshotConsistencyGroupCollection object."""
        return json.dumps(self.to_dict(), indent=2)

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

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


class SnapshotConsistencyGroupPatch:
    """
    SnapshotConsistencyGroupPatch.

    :param bool delete_snapshots_on_delete: (optional) Indicates whether deleting
          the snapshot consistency group will also delete the snapshots in the group.
    :param str name: (optional) The name for this snapshot consistency group. The
          name must not be used by another snapshot consistency groups in the region.
    """

    def __init__(
        self,
        *,
        delete_snapshots_on_delete: Optional[bool] = None,
        name: Optional[str] = None,
    ) -> None:
        """
        Initialize a SnapshotConsistencyGroupPatch object.

        :param bool delete_snapshots_on_delete: (optional) Indicates whether
               deleting the snapshot consistency group will also delete the snapshots in
               the group.
        :param str name: (optional) The name for this snapshot consistency group.
               The name must not be used by another snapshot consistency groups in the
               region.
        """
        self.delete_snapshots_on_delete = delete_snapshots_on_delete
        self.name = name

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

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

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

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


class SnapshotConsistencyGroupPrototype:
    """
    SnapshotConsistencyGroupPrototype.

    :param bool delete_snapshots_on_delete: (optional) Indicates whether deleting
          the snapshot consistency group will also delete the snapshots in the group.
    :param str name: (optional) The name for this snapshot consistency group. The
          name must be unique across all snapshot consistency groups 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.
    """

    def __init__(
        self,
        *,
        delete_snapshots_on_delete: Optional[bool] = None,
        name: Optional[str] = None,
        resource_group: Optional['ResourceGroupIdentity'] = None,
    ) -> None:
        """
        Initialize a SnapshotConsistencyGroupPrototype object.

        :param bool delete_snapshots_on_delete: (optional) Indicates whether
               deleting the snapshot consistency group will also delete the snapshots in
               the group.
        :param str name: (optional) The name for this snapshot consistency group.
               The name must be unique across all snapshot consistency groups 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(['SnapshotConsistencyGroupPrototypeSnapshotConsistencyGroupBySnapshots'])
        )
        raise Exception(msg)


class SnapshotConsistencyGroupReference:
    """
    SnapshotConsistencyGroupReference.

    :param str crn: The CRN of this snapshot consistency group.
    :param Deleted deleted: (optional) If present, this property indicates the
          referenced resource has been deleted, and provides
          some supplementary information.
    :param str href: The URL for this snapshot consistency group.
    :param str id: The unique identifier for this snapshot consistency group.
    :param str name: The name for this snapshot consistency group. The name is
          unique across all snapshot consistency groups in the region.
    :param str resource_type: The resource type.
    """

    def __init__(
        self,
        crn: str,
        href: str,
        id: str,
        name: str,
        resource_type: str,
        *,
        deleted: Optional['Deleted'] = None,
    ) -> None:
        """
        Initialize a SnapshotConsistencyGroupReference object.

        :param str crn: The CRN of this snapshot consistency group.
        :param str href: The URL for this snapshot consistency group.
        :param str id: The unique identifier for this snapshot consistency group.
        :param str name: The name for this snapshot consistency group. The name is
               unique across all snapshot consistency groups in the region.
        :param str resource_type: The resource type.
        :param Deleted 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) -> 'SnapshotConsistencyGroupReference':
        """Initialize a SnapshotConsistencyGroupReference object from a json dictionary."""
        args = {}
        if (crn := _dict.get('crn')) is not None:
            args['crn'] = crn
        else:
            raise ValueError('Required property \'crn\' not present in SnapshotConsistencyGroupReference JSON')
        if (deleted := _dict.get('deleted')) is not None:
            args['deleted'] = Deleted.from_dict(deleted)
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in SnapshotConsistencyGroupReference JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in SnapshotConsistencyGroupReference JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in SnapshotConsistencyGroupReference JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = resource_type
        else:
            raise ValueError('Required property \'resource_type\' not present in SnapshotConsistencyGroupReference JSON')
        return cls(**args)

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

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

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

    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        SNAPSHOT_CONSISTENCY_GROUP = 'snapshot_consistency_group'



class SnapshotCopiesItem:
    """
    SnapshotCopiesItem.

    :param str crn: The CRN for the copied snapshot.
    :param Deleted deleted: (optional) If present, this property indicates the
          referenced resource has been deleted, and provides
          some supplementary information.
    :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 SnapshotRemote remote: (optional) If present, this property indicates
          that the resource associated with this reference
          is remote and therefore may not be directly retrievable.
    :param str resource_type: The resource type.
    """

    def __init__(
        self,
        crn: str,
        href: str,
        id: str,
        name: str,
        resource_type: str,
        *,
        deleted: Optional['Deleted'] = None,
        remote: Optional['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 Deleted 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 := _dict.get('crn')) is not None:
            args['crn'] = crn
        else:
            raise ValueError('Required property \'crn\' not present in SnapshotCopiesItem JSON')
        if (deleted := _dict.get('deleted')) is not None:
            args['deleted'] = Deleted.from_dict(deleted)
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in SnapshotCopiesItem JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in SnapshotCopiesItem JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in SnapshotCopiesItem JSON')
        if (remote := _dict.get('remote')) is not None:
            args['remote'] = SnapshotRemote.from_dict(remote)
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = 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.

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

    def __init__(
        self,
        *,
        name: Optional[str] = None,
        user_tags: Optional[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 := _dict.get('name')) is not None:
            args['name'] = name
        if (user_tags := _dict.get('user_tags')) is not None:
            args['user_tags'] = 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.

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

    def __init__(
        self,
        *,
        clones: Optional[List['SnapshotClonePrototype']] = None,
        name: Optional[str] = None,
        resource_group: Optional['ResourceGroupIdentity'] = None,
        user_tags: Optional[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 SnapshotPrototypeSnapshotConsistencyGroupContext:
    """
    SnapshotPrototypeSnapshotConsistencyGroupContext.

    :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 VolumeIdentity source_volume: The volume to create this snapshot from.
    :param List[str] user_tags: (optional) The [user
          tags](https://cloud.ibm.com/apidocs/tagging#types-of-tags) associated with this
          snapshot.
    """

    def __init__(
        self,
        source_volume: 'VolumeIdentity',
        *,
        name: Optional[str] = None,
        user_tags: Optional[List[str]] = None,
    ) -> None:
        """
        Initialize a SnapshotPrototypeSnapshotConsistencyGroupContext object.

        :param VolumeIdentity source_volume: The volume to create this snapshot
               from.
        :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 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.source_volume = source_volume
        self.user_tags = user_tags

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

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

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

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

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


class SnapshotReference:
    """
    SnapshotReference.

    :param str crn: The CRN of this snapshot.
    :param Deleted deleted: (optional) If present, this property indicates the
          referenced resource has been deleted, and provides
          some supplementary information.
    :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 SnapshotRemote remote: (optional) If present, this property indicates
          that the resource associated with this reference
          is remote and therefore may not be directly retrievable.
    :param str resource_type: The resource type.
    """

    def __init__(
        self,
        crn: str,
        href: str,
        id: str,
        name: str,
        resource_type: str,
        *,
        deleted: Optional['Deleted'] = None,
        remote: Optional['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 Deleted 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 := _dict.get('crn')) is not None:
            args['crn'] = crn
        else:
            raise ValueError('Required property \'crn\' not present in SnapshotReference JSON')
        if (deleted := _dict.get('deleted')) is not None:
            args['deleted'] = Deleted.from_dict(deleted)
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in SnapshotReference JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in SnapshotReference JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in SnapshotReference JSON')
        if (remote := _dict.get('remote')) is not None:
            args['remote'] = SnapshotRemote.from_dict(remote)
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = 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 SnapshotRemote:
    """
    If present, this property indicates that the resource associated with this reference
    is remote and therefore may not be directly retrievable.

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

    def __init__(
        self,
        *,
        account: Optional['AccountReference'] = None,
        region: Optional['RegionReference'] = None,
    ) -> None:
        """
        Initialize a SnapshotRemote 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) -> 'SnapshotRemote':
        """Initialize a SnapshotRemote object from a json dictionary."""
        args = {}
        if (account := _dict.get('account')) is not None:
            args['account'] = AccountReference.from_dict(account)
        if (region := _dict.get('region')) is not None:
            args['region'] = RegionReference.from_dict(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, '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 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.

    :param str crn: The CRN of the source snapshot.
    :param Deleted deleted: (optional) If present, this property indicates the
          referenced resource has been deleted, and provides
          some supplementary information.
    :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 SnapshotRemote remote: (optional) If present, this property indicates
          that the resource associated with this reference
          is remote and therefore may not be directly retrievable.
    :param str resource_type: The resource type.
    """

    def __init__(
        self,
        crn: str,
        href: str,
        id: str,
        name: str,
        resource_type: str,
        *,
        deleted: Optional['Deleted'] = None,
        remote: Optional['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 Deleted 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 := _dict.get('crn')) is not None:
            args['crn'] = crn
        else:
            raise ValueError('Required property \'crn\' not present in SnapshotSourceSnapshot JSON')
        if (deleted := _dict.get('deleted')) is not None:
            args['deleted'] = Deleted.from_dict(deleted)
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in SnapshotSourceSnapshot JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in SnapshotSourceSnapshot JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in SnapshotSourceSnapshot JSON')
        if (remote := _dict.get('remote')) is not None:
            args['remote'] = SnapshotRemote.from_dict(remote)
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = 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.

    :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 PublicGatewayReference public_gateway: (optional) The public gateway to
          use for internet-bound traffic 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.
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :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.
    """

    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: Optional['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.
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :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 := _dict.get('available_ipv4_address_count')) is not None:
            args['available_ipv4_address_count'] = available_ipv4_address_count
        else:
            raise ValueError('Required property \'available_ipv4_address_count\' not present in Subnet JSON')
        if (created_at := _dict.get('created_at')) is not None:
            args['created_at'] = string_to_datetime(created_at)
        else:
            raise ValueError('Required property \'created_at\' not present in Subnet JSON')
        if (crn := _dict.get('crn')) is not None:
            args['crn'] = crn
        else:
            raise ValueError('Required property \'crn\' not present in Subnet JSON')
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in Subnet JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in Subnet JSON')
        if (ip_version := _dict.get('ip_version')) is not None:
            args['ip_version'] = ip_version
        else:
            raise ValueError('Required property \'ip_version\' not present in Subnet JSON')
        if (ipv4_cidr_block := _dict.get('ipv4_cidr_block')) is not None:
            args['ipv4_cidr_block'] = ipv4_cidr_block
        else:
            raise ValueError('Required property \'ipv4_cidr_block\' not present in Subnet JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in Subnet JSON')
        if (network_acl := _dict.get('network_acl')) is not None:
            args['network_acl'] = NetworkACLReference.from_dict(network_acl)
        else:
            raise ValueError('Required property \'network_acl\' not present in Subnet JSON')
        if (public_gateway := _dict.get('public_gateway')) is not None:
            args['public_gateway'] = PublicGatewayReference.from_dict(public_gateway)
        if (resource_group := _dict.get('resource_group')) is not None:
            args['resource_group'] = ResourceGroupReference.from_dict(resource_group)
        else:
            raise ValueError('Required property \'resource_group\' not present in Subnet JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = resource_type
        else:
            raise ValueError('Required property \'resource_type\' not present in Subnet JSON')
        if (routing_table := _dict.get('routing_table')) is not None:
            args['routing_table'] = RoutingTableReference.from_dict(routing_table)
        else:
            raise ValueError('Required property \'routing_table\' not present in Subnet JSON')
        if (status := _dict.get('status')) is not None:
            args['status'] = status
        else:
            raise ValueError('Required property \'status\' not present in Subnet JSON')
        if (total_ipv4_address_count := _dict.get('total_ipv4_address_count')) is not None:
            args['total_ipv4_address_count'] = total_ipv4_address_count
        else:
            raise ValueError('Required property \'total_ipv4_address_count\' not present in Subnet JSON')
        if (vpc := _dict.get('vpc')) is not None:
            args['vpc'] = VPCReference.from_dict(vpc)
        else:
            raise ValueError('Required property \'vpc\' not present in Subnet JSON')
        if (zone := _dict.get('zone')) is not None:
            args['zone'] = ZoneReference.from_dict(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.
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        AVAILABLE = 'available'
        DELETING = 'deleting'
        FAILED = 'failed'
        PENDING = 'pending'



class SubnetCollection:
    """
    SubnetCollection.

    :param PageLink 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 PageLink next: (optional) A link to the next page of resources. This
          property is present for all pages
          except the last page.
    :param List[Subnet] subnets: A page of subnets.
    :param int total_count: The total number of resources across all pages.
    """

    def __init__(
        self,
        first: 'PageLink',
        limit: int,
        subnets: List['Subnet'],
        total_count: int,
        *,
        next: Optional['PageLink'] = None,
    ) -> None:
        """
        Initialize a SubnetCollection object.

        :param PageLink 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: A page of subnets.
        :param int total_count: The total number of resources across all pages.
        :param PageLink 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 := _dict.get('first')) is not None:
            args['first'] = PageLink.from_dict(first)
        else:
            raise ValueError('Required property \'first\' not present in SubnetCollection JSON')
        if (limit := _dict.get('limit')) is not None:
            args['limit'] = limit
        else:
            raise ValueError('Required property \'limit\' not present in SubnetCollection JSON')
        if (next := _dict.get('next')) is not None:
            args['next'] = PageLink.from_dict(next)
        if (subnets := _dict.get('subnets')) is not None:
            args['subnets'] = [Subnet.from_dict(v) for v in subnets]
        else:
            raise ValueError('Required property \'subnets\' not present in SubnetCollection JSON')
        if (total_count := _dict.get('total_count')) is not None:
            args['total_count'] = 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 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.

    :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`.
    """

    def __init__(
        self,
        *,
        name: Optional[str] = None,
        network_acl: Optional['NetworkACLIdentity'] = None,
        public_gateway: Optional['SubnetPublicGatewayPatch'] = None,
        routing_table: Optional['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 := _dict.get('name')) is not None:
            args['name'] = name
        if (network_acl := _dict.get('network_acl')) is not None:
            args['network_acl'] = network_acl
        if (public_gateway := _dict.get('public_gateway')) is not None:
            args['public_gateway'] = public_gateway
        if (routing_table := _dict.get('routing_table')) is not None:
            args['routing_table'] = 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.

    :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`.
    :param VPCIdentity vpc: The VPC the subnet will reside in.
    """

    def __init__(
        self,
        vpc: 'VPCIdentity',
        *,
        ip_version: Optional[str] = None,
        name: Optional[str] = None,
        network_acl: Optional['NetworkACLIdentity'] = None,
        public_gateway: Optional['PublicGatewayIdentity'] = None,
        resource_group: Optional['ResourceGroupIdentity'] = None,
        routing_table: Optional['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.

    :param str crn: The CRN for this subnet.
    :param Deleted deleted: (optional) If present, this property indicates the
          referenced resource has been deleted, and provides
          some supplementary information.
    :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.
    """

    def __init__(
        self,
        crn: str,
        href: str,
        id: str,
        name: str,
        resource_type: str,
        *,
        deleted: Optional['Deleted'] = 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 Deleted 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 := _dict.get('crn')) is not None:
            args['crn'] = crn
        else:
            raise ValueError('Required property \'crn\' not present in SubnetReference JSON')
        if (deleted := _dict.get('deleted')) is not None:
            args['deleted'] = Deleted.from_dict(deleted)
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in SubnetReference JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in SubnetReference JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in SubnetReference JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = 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 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(['TrustedProfileIdentityById', 'TrustedProfileIdentityByCRN'])
        )
        raise Exception(msg)


class TrustedProfileReference:
    """
    TrustedProfileReference.

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

    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 := _dict.get('crn')) is not None:
            args['crn'] = crn
        else:
            raise ValueError('Required property \'crn\' not present in TrustedProfileReference JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in TrustedProfileReference JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = 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.

    :param str architecture: The VCPU architecture.
    :param int count: The number of VCPUs assigned.
    :param 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 := _dict.get('architecture')) is not None:
            args['architecture'] = architecture
        else:
            raise ValueError('Required property \'architecture\' not present in VCPU JSON')
        if (count := _dict.get('count')) is not None:
            args['count'] = count
        else:
            raise ValueError('Required property \'count\' not present in VCPU JSON')
        if (manufacturer := _dict.get('manufacturer')) is not None:
            args['manufacturer'] = 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.

    :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 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.
    :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).
    :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.
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    """

    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: Optional[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).
        :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.
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :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 := _dict.get('classic_access')) is not None:
            args['classic_access'] = classic_access
        else:
            raise ValueError('Required property \'classic_access\' not present in VPC JSON')
        if (created_at := _dict.get('created_at')) is not None:
            args['created_at'] = string_to_datetime(created_at)
        else:
            raise ValueError('Required property \'created_at\' not present in VPC JSON')
        if (crn := _dict.get('crn')) is not None:
            args['crn'] = crn
        else:
            raise ValueError('Required property \'crn\' not present in VPC JSON')
        if (cse_source_ips := _dict.get('cse_source_ips')) is not None:
            args['cse_source_ips'] = [VPCCSESourceIP.from_dict(v) for v in cse_source_ips]
        if (default_network_acl := _dict.get('default_network_acl')) is not None:
            args['default_network_acl'] = NetworkACLReference.from_dict(default_network_acl)
        else:
            raise ValueError('Required property \'default_network_acl\' not present in VPC JSON')
        if (default_routing_table := _dict.get('default_routing_table')) is not None:
            args['default_routing_table'] = RoutingTableReference.from_dict(default_routing_table)
        else:
            raise ValueError('Required property \'default_routing_table\' not present in VPC JSON')
        if (default_security_group := _dict.get('default_security_group')) is not None:
            args['default_security_group'] = SecurityGroupReference.from_dict(default_security_group)
        else:
            raise ValueError('Required property \'default_security_group\' not present in VPC JSON')
        if (dns := _dict.get('dns')) is not None:
            args['dns'] = VPCDNS.from_dict(dns)
        else:
            raise ValueError('Required property \'dns\' not present in VPC JSON')
        if (health_reasons := _dict.get('health_reasons')) is not None:
            args['health_reasons'] = [VPCHealthReason.from_dict(v) for v in health_reasons]
        else:
            args['health_reasons'] = []
        if (health_state := _dict.get('health_state')) is not None:
            args['health_state'] = health_state
        else:
            raise ValueError('Required property \'health_state\' not present in VPC JSON')
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in VPC JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in VPC JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in VPC JSON')
        if (resource_group := _dict.get('resource_group')) is not None:
            args['resource_group'] = ResourceGroupReference.from_dict(resource_group)
        else:
            raise ValueError('Required property \'resource_group\' not present in VPC JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = resource_type
        else:
            raise ValueError('Required property \'resource_type\' not present in VPC JSON')
        if (status := _dict.get('status')) is not None:
            args['status'] = 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.
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        AVAILABLE = 'available'
        DELETING = 'deleting'
        FAILED = 'failed'
        PENDING = 'pending'



class VPCCSESourceIP:
    """
    VPCCSESourceIP.

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

    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 := _dict.get('ip')) is not None:
            args['ip'] = IP.from_dict(ip)
        else:
            raise ValueError('Required property \'ip\' not present in VPCCSESourceIP JSON')
        if (zone := _dict.get('zone')) is not None:
            args['zone'] = ZoneReference.from_dict(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.

    :param PageLink 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 PageLink next: (optional) A link to the next page of resources. This
          property is present for all pages
          except the last page.
    :param int total_count: The total number of resources across all pages.
    :param List[VPC] vpcs: A page of VPCs.
    """

    def __init__(
        self,
        first: 'PageLink',
        limit: int,
        total_count: int,
        vpcs: List['VPC'],
        *,
        next: Optional['PageLink'] = None,
    ) -> None:
        """
        Initialize a VPCCollection object.

        :param PageLink 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: A page of VPCs.
        :param PageLink 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 := _dict.get('first')) is not None:
            args['first'] = PageLink.from_dict(first)
        else:
            raise ValueError('Required property \'first\' not present in VPCCollection JSON')
        if (limit := _dict.get('limit')) is not None:
            args['limit'] = limit
        else:
            raise ValueError('Required property \'limit\' not present in VPCCollection JSON')
        if (next := _dict.get('next')) is not None:
            args['next'] = PageLink.from_dict(next)
        if (total_count := _dict.get('total_count')) is not None:
            args['total_count'] = total_count
        else:
            raise ValueError('Required property \'total_count\' not present in VPCCollection JSON')
        if (vpcs := _dict.get('vpcs')) is not None:
            args['vpcs'] = [VPC.from_dict(v) for v in 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 VPCDNS:
    """
    The DNS configuration for this VPC.

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

    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 := _dict.get('enable_hub')) is not None:
            args['enable_hub'] = enable_hub
        else:
            raise ValueError('Required property \'enable_hub\' not present in VPCDNS JSON')
        if (resolution_binding_count := _dict.get('resolution_binding_count')) is not None:
            args['resolution_binding_count'] = resolution_binding_count
        else:
            raise ValueError('Required property \'resolution_binding_count\' not present in VPCDNS JSON')
        if (resolver := _dict.get('resolver')) is not None:
            args['resolver'] = 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.

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

    def __init__(
        self,
        *,
        enable_hub: Optional[bool] = None,
        resolver: Optional['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 := _dict.get('enable_hub')) is not None:
            args['enable_hub'] = enable_hub
        if (resolver := _dict.get('resolver')) is not None:
            args['resolver'] = VPCDNSResolverPatch.from_dict(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.

    :param bool enable_hub: (optional) Indicates whether this VPC is enabled as a
          DNS name resolution hub.
    :param VPCDNSResolverPrototype resolver: (optional)
    """

    def __init__(
        self,
        *,
        enable_hub: Optional[bool] = None,
        resolver: Optional['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 := _dict.get('enable_hub')) is not None:
            args['enable_hub'] = enable_hub
        if (resolver := _dict.get('resolver')) is not None:
            args['resolver'] = 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.

    :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 List[VPCDNSResolutionBindingHealthReason] health_reasons: The reasons for
          the current `health_state` (if any).
    :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 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.
    """

    def __init__(
        self,
        created_at: datetime,
        endpoint_gateways: List['EndpointGatewayReferenceRemote'],
        health_reasons: List['VPCDNSResolutionBindingHealthReason'],
        health_state: str,
        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 List[VPCDNSResolutionBindingHealthReason] health_reasons: The
               reasons for the current `health_state` (if any).
        :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 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.health_reasons = health_reasons
        self.health_state = health_state
        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 := _dict.get('created_at')) is not None:
            args['created_at'] = string_to_datetime(created_at)
        else:
            raise ValueError('Required property \'created_at\' not present in VPCDNSResolutionBinding JSON')
        if (endpoint_gateways := _dict.get('endpoint_gateways')) is not None:
            args['endpoint_gateways'] = [EndpointGatewayReferenceRemote.from_dict(v) for v in endpoint_gateways]
        else:
            raise ValueError('Required property \'endpoint_gateways\' not present in VPCDNSResolutionBinding JSON')
        if (health_reasons := _dict.get('health_reasons')) is not None:
            args['health_reasons'] = [VPCDNSResolutionBindingHealthReason.from_dict(v) for v in health_reasons]
        else:
            raise ValueError('Required property \'health_reasons\' not present in VPCDNSResolutionBinding JSON')
        if (health_state := _dict.get('health_state')) is not None:
            args['health_state'] = health_state
        else:
            raise ValueError('Required property \'health_state\' not present in VPCDNSResolutionBinding JSON')
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in VPCDNSResolutionBinding JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in VPCDNSResolutionBinding JSON')
        if (lifecycle_state := _dict.get('lifecycle_state')) is not None:
            args['lifecycle_state'] = lifecycle_state
        else:
            raise ValueError('Required property \'lifecycle_state\' not present in VPCDNSResolutionBinding JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in VPCDNSResolutionBinding JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = resource_type
        else:
            raise ValueError('Required property \'resource_type\' not present in VPCDNSResolutionBinding JSON')
        if (vpc := _dict.get('vpc')) is not None:
            args['vpc'] = VPCReferenceRemote.from_dict(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, '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_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 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 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.

    :param List[VPCDNSResolutionBinding] dns_resolution_bindings: A page of DNS
          resolution bindings for the VPC.
    :param PageLink 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 PageLink next: (optional) A link to the next page of resources. This
          property is present for all pages
          except the last page.
    :param int total_count: The total number of resources across all pages.
    """

    def __init__(
        self,
        dns_resolution_bindings: List['VPCDNSResolutionBinding'],
        first: 'PageLink',
        limit: int,
        total_count: int,
        *,
        next: Optional['PageLink'] = None,
    ) -> None:
        """
        Initialize a VPCDNSResolutionBindingCollection object.

        :param List[VPCDNSResolutionBinding] dns_resolution_bindings: A page of DNS
               resolution bindings for the VPC.
        :param PageLink 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 PageLink 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 := _dict.get('dns_resolution_bindings')) is not None:
            args['dns_resolution_bindings'] = [VPCDNSResolutionBinding.from_dict(v) for v in dns_resolution_bindings]
        else:
            raise ValueError('Required property \'dns_resolution_bindings\' not present in VPCDNSResolutionBindingCollection JSON')
        if (first := _dict.get('first')) is not None:
            args['first'] = PageLink.from_dict(first)
        else:
            raise ValueError('Required property \'first\' not present in VPCDNSResolutionBindingCollection JSON')
        if (limit := _dict.get('limit')) is not None:
            args['limit'] = limit
        else:
            raise ValueError('Required property \'limit\' not present in VPCDNSResolutionBindingCollection JSON')
        if (next := _dict.get('next')) is not None:
            args['next'] = PageLink.from_dict(next)
        if (total_count := _dict.get('total_count')) is not None:
            args['total_count'] = 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 VPCDNSResolutionBindingHealthReason:
    """
    VPCDNSResolutionBindingHealthReason.

    :param str code: A reason code 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.
    """

    def __init__(
        self,
        code: str,
        message: str,
        *,
        more_info: Optional[str] = None,
    ) -> None:
        """
        Initialize a VPCDNSResolutionBindingHealthReason object.

        :param str code: A reason code 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) -> 'VPCDNSResolutionBindingHealthReason':
        """Initialize a VPCDNSResolutionBindingHealthReason object from a json dictionary."""
        args = {}
        if (code := _dict.get('code')) is not None:
            args['code'] = code
        else:
            raise ValueError('Required property \'code\' not present in VPCDNSResolutionBindingHealthReason JSON')
        if (message := _dict.get('message')) is not None:
            args['message'] = message
        else:
            raise ValueError('Required property \'message\' not present in VPCDNSResolutionBindingHealthReason JSON')
        if (more_info := _dict.get('more_info')) is not None:
            args['more_info'] = more_info
        return cls(**args)

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

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

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

    class CodeEnum(str, Enum):
        """
        A reason code for this health state.
        """

        DISCONNECTED_FROM_BOUND_VPC = 'disconnected_from_bound_vpc'
        INTERNAL_ERROR = 'internal_error'



class VPCDNSResolutionBindingPatch:
    """
    VPCDNSResolutionBindingPatch.

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

    def __init__(
        self,
        *,
        name: Optional[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 := _dict.get('name')) is not None:
            args['name'] = 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.

    :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`
          The maximum number of DNS servers is expected to
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :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.
          The maximum number of DNS servers is expected to
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    """

    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`
               The maximum number of DNS servers is expected to
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :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.
               The maximum number of DNS servers is expected to
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        """
        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.
        The maximum number of DNS servers is expected to
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        DELEGATED = 'delegated'
        MANUAL = 'manual'
        SYSTEM = 'system'



class VPCDNSResolverPatch:
    """
    VPCDNSResolverPatch.

    :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`.
          If `zone_affinity` is specified, exactly one DNS server must be specified for
          each zone in the region. The DHCP [Domain Name Server
          Option](https://datatracker.ietf.org/doc/html/rfc2132#section-3.8) for a zone
          will list this DNS server first, followed by unique DNS servers from other zones
          if available.
          If `zone_affinity` is not specified, the DHCP [Domain Name Server
          Option](https://datatracker.ietf.org/doc/html/rfc2132#section-3.8) for each zone
          will list all the manual DNS servers in the order specified.
          `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`.
    """

    def __init__(
        self,
        *,
        manual_servers: Optional[List['DNSServerPrototype']] = None,
        type: Optional[str] = None,
        vpc: Optional['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`.
               If `zone_affinity` is specified, exactly one DNS server must be specified
               for each zone in the region. The DHCP [Domain Name Server
               Option](https://datatracker.ietf.org/doc/html/rfc2132#section-3.8) for a
               zone will list this DNS server first, followed by unique DNS servers from
               other zones if available.
               If `zone_affinity` is not specified, the DHCP [Domain Name Server
               Option](https://datatracker.ietf.org/doc/html/rfc2132#section-3.8) for each
               zone will list all the manual DNS servers in the order specified.
               `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 := _dict.get('manual_servers')) is not None:
            args['manual_servers'] = [DNSServerPrototype.from_dict(v) for v in manual_servers]
        if (type := _dict.get('type')) is not None:
            args['type'] = type
        if (vpc := _dict.get('vpc')) is not None:
            args['vpc'] = 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.

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

    def __init__(
        self,
        *,
        type: Optional[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.

    :param str code: A reason code 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.
    """

    def __init__(
        self,
        code: str,
        message: str,
        *,
        more_info: Optional[str] = None,
    ) -> None:
        """
        Initialize a VPCHealthReason object.

        :param str code: A reason code 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 := _dict.get('code')) is not None:
            args['code'] = code
        else:
            raise ValueError('Required property \'code\' not present in VPCHealthReason JSON')
        if (message := _dict.get('message')) is not None:
            args['message'] = message
        else:
            raise ValueError('Required property \'message\' not present in VPCHealthReason JSON')
        if (more_info := _dict.get('more_info')) is not None:
            args['more_info'] = 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 reason code for this health state.
        """

        DNS_RESOLUTION_BINDING_FAILED = 'dns_resolution_binding_failed'
        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.

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

    def __init__(
        self,
        *,
        dns: Optional['VPCDNSPatch'] = None,
        name: Optional[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 := _dict.get('dns')) is not None:
            args['dns'] = VPCDNSPatch.from_dict(dns)
        if (name := _dict.get('name')) is not None:
            args['name'] = 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.

    :param str crn: The CRN for this VPC.
    :param Deleted deleted: (optional) If present, this property indicates the
          referenced resource has been deleted, and provides
          some supplementary information.
    :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.
    """

    def __init__(
        self,
        crn: str,
        href: str,
        id: str,
        name: str,
        resource_type: str,
        *,
        deleted: Optional['Deleted'] = 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 Deleted 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 := _dict.get('crn')) is not None:
            args['crn'] = crn
        else:
            raise ValueError('Required property \'crn\' not present in VPCReference JSON')
        if (deleted := _dict.get('deleted')) is not None:
            args['deleted'] = Deleted.from_dict(deleted)
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in VPCReference JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in VPCReference JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in VPCReference JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = 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.

    :param str crn: The CRN for this VPC.
    :param Deleted deleted: (optional) If present, this property indicates the
          referenced resource has been deleted, and provides
          some supplementary information.
    :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 VPCRemote remote: (optional) If present, this property indicates that the
          resource associated with this reference
          is remote and therefore may not be directly retrievable.
    :param str resource_type: The resource type.
    """

    def __init__(
        self,
        crn: str,
        href: str,
        id: str,
        name: str,
        resource_type: str,
        *,
        deleted: Optional['Deleted'] = None,
        remote: Optional['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 Deleted 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 := _dict.get('crn')) is not None:
            args['crn'] = crn
        else:
            raise ValueError('Required property \'crn\' not present in VPCReferenceDNSResolverContext JSON')
        if (deleted := _dict.get('deleted')) is not None:
            args['deleted'] = Deleted.from_dict(deleted)
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in VPCReferenceDNSResolverContext JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in VPCReferenceDNSResolverContext JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in VPCReferenceDNSResolverContext JSON')
        if (remote := _dict.get('remote')) is not None:
            args['remote'] = VPCRemote.from_dict(remote)
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = 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 VPCReferenceRemote:
    """
    VPCReferenceRemote.

    :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 VPCRemote remote: (optional) If present, this property indicates that the
          resource associated with this reference
          is remote and therefore may not be directly retrievable.
    :param str resource_type: The resource type.
    """

    def __init__(
        self,
        crn: str,
        href: str,
        id: str,
        name: str,
        resource_type: str,
        *,
        remote: Optional['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 := _dict.get('crn')) is not None:
            args['crn'] = crn
        else:
            raise ValueError('Required property \'crn\' not present in VPCReferenceRemote JSON')
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in VPCReferenceRemote JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in VPCReferenceRemote JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in VPCReferenceRemote JSON')
        if (remote := _dict.get('remote')) is not None:
            args['remote'] = VPCRemote.from_dict(remote)
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = 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.

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

    def __init__(
        self,
        *,
        account: Optional['AccountReference'] = None,
        region: Optional['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 := _dict.get('account')) is not None:
            args['account'] = AccountReference.from_dict(account)
        if (region := _dict.get('region')) is not None:
            args['region'] = RegionReference.from_dict(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.

    :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 CRN for this VPN gateway.
    :param List[VPNGatewayHealthReason] health_reasons: The reasons for the current
          `health_state` (if any).
    :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 gateway.
    :param str id: The unique identifier for this VPN gateway.
    :param List[VPNGatewayLifecycleReason] lifecycle_reasons: The reasons for the
          current `lifecycle_state` (if any).
    :param str lifecycle_state: The lifecycle state of the VPN gateway.
    :param List[VPNGatewayMember] members: The members for the VPN gateway.
    :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.
    """

    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 CRN for this VPN gateway.
        :param List[VPNGatewayHealthReason] health_reasons: The reasons for the
               current `health_state` (if any).
        :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 gateway.
        :param str id: The unique identifier for this VPN gateway.
        :param List[VPNGatewayLifecycleReason] lifecycle_reasons: The reasons for
               the current `lifecycle_state` (if any).
        :param str lifecycle_state: The lifecycle state of the VPN gateway.
        :param List[VPNGatewayMember] members: The members for the VPN gateway.
        :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.

    :param PageLink 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 PageLink next: (optional) A link to the next page of resources. This
          property is present for all pages
          except the last page.
    :param int total_count: The total number of resources across all pages.
    :param List[VPNGateway] vpn_gateways: A page of VPN gateways.
    """

    def __init__(
        self,
        first: 'PageLink',
        limit: int,
        total_count: int,
        vpn_gateways: List['VPNGateway'],
        *,
        next: Optional['PageLink'] = None,
    ) -> None:
        """
        Initialize a VPNGatewayCollection object.

        :param PageLink 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: A page of VPN gateways.
        :param PageLink 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 := _dict.get('first')) is not None:
            args['first'] = PageLink.from_dict(first)
        else:
            raise ValueError('Required property \'first\' not present in VPNGatewayCollection JSON')
        if (limit := _dict.get('limit')) is not None:
            args['limit'] = limit
        else:
            raise ValueError('Required property \'limit\' not present in VPNGatewayCollection JSON')
        if (next := _dict.get('next')) is not None:
            args['next'] = PageLink.from_dict(next)
        if (total_count := _dict.get('total_count')) is not None:
            args['total_count'] = total_count
        else:
            raise ValueError('Required property \'total_count\' not present in VPNGatewayCollection JSON')
        if (vpn_gateways := _dict.get('vpn_gateways')) is not None:
            args['vpn_gateways'] = 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 VPNGatewayConnection:
    """
    VPNGatewayConnection.

    :param bool admin_state_up: If set to false, the VPN gateway connection is shut
          down.
    :param str authentication_mode: The authentication mode.
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :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 establish_mode: The establish mode of the VPN gateway connection:
          - `bidirectional`: Either side of the VPN gateway can initiate IKE protocol
             negotiations or rekeying processes.
          - `peer_only`: Only the peer can initiate IKE protocol negotiations for this VPN
          gateway
             connection. Additionally, the peer is responsible for initiating the rekeying
          process
             after the connection is established. If rekeying does not occur, the VPN
          gateway
             connection will be brought down after its lifetime expires.
    :param str href: The URL for this VPN gateway connection.
    :param str id: The unique identifier for this VPN gateway connection.
    :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).
    :param str mode: The mode of the VPN gateway.
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :param str name: The name for this VPN gateway connection. The name is unique
          across all connections for the 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).
    """

    def __init__(
        self,
        admin_state_up: bool,
        authentication_mode: str,
        created_at: datetime,
        dead_peer_detection: 'VPNGatewayConnectionDPD',
        establish_mode: str,
        href: str,
        id: str,
        mode: str,
        name: str,
        psk: str,
        resource_type: str,
        status: str,
        status_reasons: List['VPNGatewayConnectionStatusReason'],
        *,
        ike_policy: Optional['IKEPolicyReference'] = None,
        ipsec_policy: Optional['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.
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :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 establish_mode: The establish mode of the VPN gateway
               connection:
               - `bidirectional`: Either side of the VPN gateway can initiate IKE protocol
                  negotiations or rekeying processes.
               - `peer_only`: Only the peer can initiate IKE protocol negotiations for
               this VPN gateway
                  connection. Additionally, the peer is responsible for initiating the
               rekeying process
                  after the connection is established. If rekeying does not occur, the VPN
               gateway
                  connection will be brought down after its lifetime expires.
        :param str href: The URL for this VPN gateway connection.
        :param str id: The unique identifier for this VPN gateway connection.
        :param str mode: The mode of the VPN gateway.
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :param str name: The name for this VPN gateway connection. The name is
               unique across all connections for the 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).
        :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(['VPNGatewayConnectionRouteMode', 'VPNGatewayConnectionPolicyMode'])
        )
        raise Exception(msg)

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

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

    @classmethod
    def _get_class_by_discriminator(cls, _dict: Dict) -> object:
        mapping = {}
        mapping['policy'] = 'VPNGatewayConnectionPolicyMode'
        mapping['route'] = 'VPNGatewayConnectionRouteMode'
        disc_value = _dict.get('mode')
        if disc_value is None:
            raise ValueError('Discriminator property \'mode\' not found in VPNGatewayConnection 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 AuthenticationModeEnum(str, Enum):
        """
        The authentication mode.
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        PSK = 'psk'


    class EstablishModeEnum(str, Enum):
        """
        The establish mode of the VPN gateway connection:
        - `bidirectional`: Either side of the VPN gateway can initiate IKE protocol
           negotiations or rekeying processes.
        - `peer_only`: Only the peer can initiate IKE protocol negotiations for this VPN
        gateway
           connection. Additionally, the peer is responsible for initiating the rekeying
        process
           after the connection is established. If rekeying does not occur, the VPN
        gateway
           connection will be brought down after its lifetime expires.
        """

        BIDIRECTIONAL = 'bidirectional'
        PEER_ONLY = 'peer_only'


    class ModeEnum(str, Enum):
        """
        The mode of the VPN gateway.
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        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 VPNGatewayConnectionCIDRs:
    """
    VPNGatewayConnectionCIDRs.

    :param List[str] cidrs: The CIDRs for this resource.
    """

    def __init__(
        self,
        cidrs: List[str],
    ) -> None:
        """
        Initialize a VPNGatewayConnectionCIDRs object.

        :param List[str] cidrs: The CIDRs for this resource.
        """
        self.cidrs = cidrs

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

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

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

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

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


class VPNGatewayConnectionCollection:
    """
    VPNGatewayConnectionCollection.

    :param List[VPNGatewayConnection] connections: A page of connections for the VPN
          gateway.
    :param PageLink 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 PageLink next: (optional) A link to the next page of resources. This
          property is present for all pages
          except the last page.
    :param int total_count: The total number of resources across all pages.
    """

    def __init__(
        self,
        connections: List['VPNGatewayConnection'],
        first: 'PageLink',
        limit: int,
        total_count: int,
        *,
        next: Optional['PageLink'] = None,
    ) -> None:
        """
        Initialize a VPNGatewayConnectionCollection object.

        :param List[VPNGatewayConnection] connections: A page of connections for
               the VPN gateway.
        :param PageLink 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 PageLink next: (optional) A link to the next page of resources. This
               property is present for all pages
               except the last page.
        """
        self.connections = connections
        self.first = first
        self.limit = limit
        self.next = next
        self.total_count = total_count

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPNGatewayConnectionCollection':
        """Initialize a VPNGatewayConnectionCollection object from a json dictionary."""
        args = {}
        if (connections := _dict.get('connections')) is not None:
            args['connections'] = [VPNGatewayConnection.from_dict(v) for v in connections]
        else:
            raise ValueError('Required property \'connections\' not present in VPNGatewayConnectionCollection JSON')
        if (first := _dict.get('first')) is not None:
            args['first'] = PageLink.from_dict(first)
        else:
            raise ValueError('Required property \'first\' not present in VPNGatewayConnectionCollection JSON')
        if (limit := _dict.get('limit')) is not None:
            args['limit'] = limit
        else:
            raise ValueError('Required property \'limit\' not present in VPNGatewayConnectionCollection JSON')
        if (next := _dict.get('next')) is not None:
            args['next'] = PageLink.from_dict(next)
        if (total_count := _dict.get('total_count')) is not None:
            args['total_count'] = total_count
        else:
            raise ValueError('Required property \'total_count\' 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
        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 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.

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

    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 := _dict.get('action')) is not None:
            args['action'] = action
        else:
            raise ValueError('Required property \'action\' not present in VPNGatewayConnectionDPD JSON')
        if (interval := _dict.get('interval')) is not None:
            args['interval'] = interval
        else:
            raise ValueError('Required property \'interval\' not present in VPNGatewayConnectionDPD JSON')
        if (timeout := _dict.get('timeout')) is not None:
            args['timeout'] = 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.

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

    def __init__(
        self,
        *,
        action: Optional[str] = None,
        interval: Optional[int] = None,
        timeout: Optional[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 := _dict.get('action')) is not None:
            args['action'] = action
        if (interval := _dict.get('interval')) is not None:
            args['interval'] = interval
        if (timeout := _dict.get('timeout')) is not None:
            args['timeout'] = 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.

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

    def __init__(
        self,
        *,
        action: Optional[str] = None,
        interval: Optional[int] = None,
        timeout: Optional[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 := _dict.get('action')) is not None:
            args['action'] = action
        if (interval := _dict.get('interval')) is not None:
            args['interval'] = interval
        if (timeout := _dict.get('timeout')) is not None:
            args['timeout'] = 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 VPNGatewayConnectionIKEIdentity:
    """
    VPNGatewayConnectionIKEIdentity.

    :param str type: The IKE identity type.
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    """

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

        :param str type: The IKE identity type.
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['VPNGatewayConnectionIKEIdentityVPNGatewayConnectionIKEIdentityFQDN', 'VPNGatewayConnectionIKEIdentityVPNGatewayConnectionIKEIdentityHostname', 'VPNGatewayConnectionIKEIdentityVPNGatewayConnectionIKEIdentityIPv4', 'VPNGatewayConnectionIKEIdentityVPNGatewayConnectionIKEIdentityKeyID'])
        )
        raise Exception(msg)

    class TypeEnum(str, Enum):
        """
        The IKE identity type.
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        FQDN = 'fqdn'
        HOSTNAME = 'hostname'
        IPV4_ADDRESS = 'ipv4_address'
        KEY_ID = 'key_id'



class VPNGatewayConnectionIKEIdentityPrototype:
    """
    VPNGatewayConnectionIKEIdentityPrototype.

    :param str type: The IKE identity type.
    """

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

        :param str type: The IKE identity type.
        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['VPNGatewayConnectionIKEIdentityPrototypeVPNGatewayConnectionIKEIdentityFQDN', 'VPNGatewayConnectionIKEIdentityPrototypeVPNGatewayConnectionIKEIdentityHostname', 'VPNGatewayConnectionIKEIdentityPrototypeVPNGatewayConnectionIKEIdentityIPv4', 'VPNGatewayConnectionIKEIdentityPrototypeVPNGatewayConnectionIKEIdentityKeyID'])
        )
        raise Exception(msg)

    class TypeEnum(str, Enum):
        """
        The IKE identity type.
        """

        FQDN = 'fqdn'
        HOSTNAME = 'hostname'
        IPV4_ADDRESS = 'ipv4_address'
        KEY_ID = 'key_id'



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 VPNGatewayConnectionPatch:
    """
    VPNGatewayConnectionPatch.

    :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 bool distribute_traffic: (optional) Indicates whether the traffic is
          distributed between the `up` tunnels of the VPN gateway connection when the VPC
          route's next hop is a VPN connection. If `false`, the traffic is only routed
          through the `up` tunnel with the lower `public_ip` address. Before enabling it
          on VPN connections to on-prem private networks, review
          [distributing traffic
          restrictions](https://cloud.ibm.com/docs/vpc?topic=vpc-vpn-limitations#distributing-traffic-restrictions).
          If specified, `mode` must be `route`.
    :param str establish_mode: (optional) The establish mode of the VPN gateway
          connection:
          - `bidirectional`: Either side of the VPN gateway can initiate IKE protocol
             negotiations or rekeying processes.
          - `peer_only`: Only the peer can initiate IKE protocol negotiations for this VPN
          gateway
             connection. Additionally, the peer is responsible for initiating the rekeying
          process
             after the connection is established. If rekeying does not occur, the VPN
          gateway
             connection will be brought down after its lifetime expires.
    :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 VPNGatewayConnectionPeerPatch peer: (optional)
    :param str psk: (optional) The pre-shared key.
    """

    def __init__(
        self,
        *,
        admin_state_up: Optional[bool] = None,
        dead_peer_detection: Optional['VPNGatewayConnectionDPDPatch'] = None,
        distribute_traffic: Optional[bool] = None,
        establish_mode: Optional[str] = None,
        ike_policy: Optional['VPNGatewayConnectionIKEPolicyPatch'] = None,
        ipsec_policy: Optional['VPNGatewayConnectionIPsecPolicyPatch'] = None,
        name: Optional[str] = None,
        peer: Optional['VPNGatewayConnectionPeerPatch'] = None,
        psk: Optional[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 bool distribute_traffic: (optional) Indicates whether the traffic is
               distributed between the `up` tunnels of the VPN gateway connection when the
               VPC route's next hop is a VPN connection. If `false`, the traffic is only
               routed through the `up` tunnel with the lower `public_ip` address. Before
               enabling it on VPN connections to on-prem private networks, review
               [distributing traffic
               restrictions](https://cloud.ibm.com/docs/vpc?topic=vpc-vpn-limitations#distributing-traffic-restrictions).
               If specified, `mode` must be `route`.
        :param str establish_mode: (optional) The establish mode of the VPN gateway
               connection:
               - `bidirectional`: Either side of the VPN gateway can initiate IKE protocol
                  negotiations or rekeying processes.
               - `peer_only`: Only the peer can initiate IKE protocol negotiations for
               this VPN gateway
                  connection. Additionally, the peer is responsible for initiating the
               rekeying process
                  after the connection is established. If rekeying does not occur, the VPN
               gateway
                  connection will be brought down after its lifetime expires.
        :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 VPNGatewayConnectionPeerPatch peer: (optional)
        :param str psk: (optional) The pre-shared key.
        """
        self.admin_state_up = admin_state_up
        self.dead_peer_detection = dead_peer_detection
        self.distribute_traffic = distribute_traffic
        self.establish_mode = establish_mode
        self.ike_policy = ike_policy
        self.ipsec_policy = ipsec_policy
        self.name = name
        self.peer = peer
        self.psk = psk

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPNGatewayConnectionPatch':
        """Initialize a VPNGatewayConnectionPatch object from a json dictionary."""
        args = {}
        if (admin_state_up := _dict.get('admin_state_up')) is not None:
            args['admin_state_up'] = admin_state_up
        if (dead_peer_detection := _dict.get('dead_peer_detection')) is not None:
            args['dead_peer_detection'] = VPNGatewayConnectionDPDPatch.from_dict(dead_peer_detection)
        if (distribute_traffic := _dict.get('distribute_traffic')) is not None:
            args['distribute_traffic'] = distribute_traffic
        if (establish_mode := _dict.get('establish_mode')) is not None:
            args['establish_mode'] = establish_mode
        if (ike_policy := _dict.get('ike_policy')) is not None:
            args['ike_policy'] = ike_policy
        if (ipsec_policy := _dict.get('ipsec_policy')) is not None:
            args['ipsec_policy'] = ipsec_policy
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        if (peer := _dict.get('peer')) is not None:
            args['peer'] = peer
        if (psk := _dict.get('psk')) is not None:
            args['psk'] = psk
        return cls(**args)

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

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'admin_state_up') and self.admin_state_up is not None:
            _dict['admin_state_up'] = self.admin_state_up
        if hasattr(self, 'dead_peer_detection') and self.dead_peer_detection is not None:
            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, 'distribute_traffic') and self.distribute_traffic is not None:
            _dict['distribute_traffic'] = self.distribute_traffic
        if hasattr(self, 'establish_mode') and self.establish_mode is not None:
            _dict['establish_mode'] = self.establish_mode
        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') and self.peer is not None:
            if isinstance(self.peer, dict):
                _dict['peer'] = self.peer
            else:
                _dict['peer'] = self.peer.to_dict()
        if hasattr(self, 'psk') and self.psk is not None:
            _dict['psk'] = self.psk
        return _dict

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

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

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

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

    class EstablishModeEnum(str, Enum):
        """
        The establish mode of the VPN gateway connection:
        - `bidirectional`: Either side of the VPN gateway can initiate IKE protocol
           negotiations or rekeying processes.
        - `peer_only`: Only the peer can initiate IKE protocol negotiations for this VPN
        gateway
           connection. Additionally, the peer is responsible for initiating the rekeying
        process
           after the connection is established. If rekeying does not occur, the VPN
        gateway
           connection will be brought down after its lifetime expires.
        """

        BIDIRECTIONAL = 'bidirectional'
        PEER_ONLY = 'peer_only'



class VPNGatewayConnectionPeerPatch:
    """
    VPNGatewayConnectionPeerPatch.

    """

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

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


class VPNGatewayConnectionPolicyModeLocal:
    """
    VPNGatewayConnectionPolicyModeLocal.

    :param List[str] cidrs: The local CIDRs for this VPN gateway connection.
    :param List[VPNGatewayConnectionIKEIdentity] ike_identities: The local IKE
          identities.
          A VPN gateway in policy mode consists of two members in active-standby mode. The
          local IKE identity applies to the active member.
    """

    def __init__(
        self,
        cidrs: List[str],
        ike_identities: List['VPNGatewayConnectionIKEIdentity'],
    ) -> None:
        """
        Initialize a VPNGatewayConnectionPolicyModeLocal object.

        :param List[str] cidrs: The local CIDRs for this VPN gateway connection.
        :param List[VPNGatewayConnectionIKEIdentity] ike_identities: The local IKE
               identities.
               A VPN gateway in policy mode consists of two members in active-standby
               mode. The local IKE identity applies to the active member.
        """
        self.cidrs = cidrs
        self.ike_identities = ike_identities

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

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

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'cidrs') and self.cidrs is not None:
            _dict['cidrs'] = self.cidrs
        if hasattr(self, 'ike_identities') and self.ike_identities is not None:
            ike_identities_list = []
            for v in self.ike_identities:
                if isinstance(v, dict):
                    ike_identities_list.append(v)
                else:
                    ike_identities_list.append(v.to_dict())
            _dict['ike_identities'] = ike_identities_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 VPNGatewayConnectionPolicyModeLocal object."""
        return json.dumps(self.to_dict(), indent=2)

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

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


class VPNGatewayConnectionPolicyModeLocalPrototype:
    """
    VPNGatewayConnectionPolicyModeLocalPrototype.

    :param List[str] cidrs: The local CIDRs for this VPN gateway connection.
    :param List[VPNGatewayConnectionIKEIdentityPrototype] ike_identities: (optional)
          The local IKE identities to use.
          A VPN gateway in policy mode consists of two members in active-standby mode. The
          specified identity will be applied to the active member.
          If unspecified, then `type` will be `ipv4_address` and `value` will be the
          public IP address of the VPN gateway.
    """

    def __init__(
        self,
        cidrs: List[str],
        *,
        ike_identities: Optional[List['VPNGatewayConnectionIKEIdentityPrototype']] = None,
    ) -> None:
        """
        Initialize a VPNGatewayConnectionPolicyModeLocalPrototype object.

        :param List[str] cidrs: The local CIDRs for this VPN gateway connection.
        :param List[VPNGatewayConnectionIKEIdentityPrototype] ike_identities:
               (optional) The local IKE identities to use.
               A VPN gateway in policy mode consists of two members in active-standby
               mode. The specified identity will be applied to the active member.
               If unspecified, then `type` will be `ipv4_address` and `value` will be the
               public IP address of the VPN gateway.
        """
        self.cidrs = cidrs
        self.ike_identities = ike_identities

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

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

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'cidrs') and self.cidrs is not None:
            _dict['cidrs'] = self.cidrs
        if hasattr(self, 'ike_identities') and self.ike_identities is not None:
            ike_identities_list = []
            for v in self.ike_identities:
                if isinstance(v, dict):
                    ike_identities_list.append(v)
                else:
                    ike_identities_list.append(v.to_dict())
            _dict['ike_identities'] = ike_identities_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 VPNGatewayConnectionPolicyModeLocalPrototype object."""
        return json.dumps(self.to_dict(), indent=2)

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

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


class VPNGatewayConnectionPolicyModePeer:
    """
    VPNGatewayConnectionPolicyModePeer.

    :param List[str] cidrs: The peer CIDRs for this VPN gateway connection.
    :param VPNGatewayConnectionIKEIdentity ike_identity: The peer IKE identity.
    :param str type: Indicates whether `peer.address` or `peer.fqdn` is used.
    """

    def __init__(
        self,
        cidrs: List[str],
        ike_identity: 'VPNGatewayConnectionIKEIdentity',
        type: str,
    ) -> None:
        """
        Initialize a VPNGatewayConnectionPolicyModePeer object.

        :param List[str] cidrs: The peer CIDRs for this VPN gateway connection.
        :param VPNGatewayConnectionIKEIdentity ike_identity: The peer IKE identity.
        :param str type: Indicates whether `peer.address` or `peer.fqdn` is used.
        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['VPNGatewayConnectionPolicyModePeerVPNGatewayConnectionPeerByAddress', 'VPNGatewayConnectionPolicyModePeerVPNGatewayConnectionPeerByFQDN'])
        )
        raise Exception(msg)

    class TypeEnum(str, Enum):
        """
        Indicates whether `peer.address` or `peer.fqdn` is used.
        """

        ADDRESS = 'address'
        FQDN = 'fqdn'



class VPNGatewayConnectionPolicyModePeerPrototype:
    """
    VPNGatewayConnectionPolicyModePeerPrototype.

    :param List[str] cidrs: The peer CIDRs for this VPN gateway connection.
    :param VPNGatewayConnectionIKEIdentityPrototype ike_identity: (optional) The
          peer IKE identity to use.
          If unspecified:
          - If `peer.address` is specified, the `type` will be `ipv4_address`, and
          the `value` will be `peer.address`.
          - If `peer.fqdn` is specified, the `type` will be `fqdn`, and the `value`
          will be `peer.fqdn`.
    """

    def __init__(
        self,
        cidrs: List[str],
        *,
        ike_identity: Optional['VPNGatewayConnectionIKEIdentityPrototype'] = None,
    ) -> None:
        """
        Initialize a VPNGatewayConnectionPolicyModePeerPrototype object.

        :param List[str] cidrs: The peer CIDRs for this VPN gateway connection.
        :param VPNGatewayConnectionIKEIdentityPrototype ike_identity: (optional)
               The peer IKE identity to use.
               If unspecified:
               - If `peer.address` is specified, the `type` will be `ipv4_address`, and
               the `value` will be `peer.address`.
               - If `peer.fqdn` is specified, the `type` will be `fqdn`, and the `value`
               will be `peer.fqdn`.
        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['VPNGatewayConnectionPolicyModePeerPrototypeVPNGatewayConnectionPeerByAddress', 'VPNGatewayConnectionPolicyModePeerPrototypeVPNGatewayConnectionPeerByFQDN'])
        )
        raise Exception(msg)


class VPNGatewayConnectionPrototype:
    """
    VPNGatewayConnectionPrototype.

    :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 str establish_mode: (optional) The establish mode of the VPN gateway
          connection:
          - `bidirectional`: Either side of the VPN gateway can initiate IKE protocol
             negotiations or rekeying processes.
          - `peer_only`: Only the peer can initiate IKE protocol negotiations for this VPN
          gateway
             connection. Additionally, the peer is responsible for initiating the rekeying
          process
             after the connection is established. If rekeying does not occur, the VPN
          gateway
             connection will be brought down after its lifetime expires.
    :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.
    :param str psk: The pre-shared key.
    """

    def __init__(
        self,
        psk: str,
        *,
        admin_state_up: Optional[bool] = None,
        dead_peer_detection: Optional['VPNGatewayConnectionDPDPrototype'] = None,
        establish_mode: Optional[str] = None,
        ike_policy: Optional['VPNGatewayConnectionIKEPolicyPrototype'] = None,
        ipsec_policy: Optional['VPNGatewayConnectionIPsecPolicyPrototype'] = None,
        name: Optional[str] = None,
    ) -> None:
        """
        Initialize a VPNGatewayConnectionPrototype object.

        :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 str establish_mode: (optional) The establish mode of the VPN gateway
               connection:
               - `bidirectional`: Either side of the VPN gateway can initiate IKE protocol
                  negotiations or rekeying processes.
               - `peer_only`: Only the peer can initiate IKE protocol negotiations for
               this VPN gateway
                  connection. Additionally, the peer is responsible for initiating the
               rekeying process
                  after the connection is established. If rekeying does not occur, the VPN
               gateway
                  connection will be brought down after its lifetime expires.
        :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 EstablishModeEnum(str, Enum):
        """
        The establish mode of the VPN gateway connection:
        - `bidirectional`: Either side of the VPN gateway can initiate IKE protocol
           negotiations or rekeying processes.
        - `peer_only`: Only the peer can initiate IKE protocol negotiations for this VPN
        gateway
           connection. Additionally, the peer is responsible for initiating the rekeying
        process
           after the connection is established. If rekeying does not occur, the VPN
        gateway
           connection will be brought down after its lifetime expires.
        """

        BIDIRECTIONAL = 'bidirectional'
        PEER_ONLY = 'peer_only'



class VPNGatewayConnectionReference:
    """
    VPNGatewayConnectionReference.

    :param Deleted deleted: (optional) If present, this property indicates the
          referenced resource has been deleted, and provides
          some supplementary information.
    :param str href: The URL for this VPN gateway connection.
    :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.
    """

    def __init__(
        self,
        href: str,
        id: str,
        name: str,
        resource_type: str,
        *,
        deleted: Optional['Deleted'] = None,
    ) -> None:
        """
        Initialize a VPNGatewayConnectionReference object.

        :param str href: The URL for this VPN gateway connection.
        :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 Deleted 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 := _dict.get('deleted')) is not None:
            args['deleted'] = Deleted.from_dict(deleted)
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in VPNGatewayConnectionReference JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in VPNGatewayConnectionReference JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in VPNGatewayConnectionReference JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = 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 VPNGatewayConnectionStaticRouteModeLocal:
    """
    VPNGatewayConnectionStaticRouteModeLocal.

    :param List[VPNGatewayConnectionIKEIdentity] ike_identities: The local IKE
          identities.
          A VPN gateway in static route mode consists of two members in active-active
          mode. The first identity applies to the first member, and the second identity
          applies to the second member.
    """

    def __init__(
        self,
        ike_identities: List['VPNGatewayConnectionIKEIdentity'],
    ) -> None:
        """
        Initialize a VPNGatewayConnectionStaticRouteModeLocal object.

        :param List[VPNGatewayConnectionIKEIdentity] ike_identities: The local IKE
               identities.
               A VPN gateway in static route mode consists of two members in active-active
               mode. The first identity applies to the first member, and the second
               identity applies to the second member.
        """
        self.ike_identities = ike_identities

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

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

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'ike_identities') and self.ike_identities is not None:
            ike_identities_list = []
            for v in self.ike_identities:
                if isinstance(v, dict):
                    ike_identities_list.append(v)
                else:
                    ike_identities_list.append(v.to_dict())
            _dict['ike_identities'] = ike_identities_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 VPNGatewayConnectionStaticRouteModeLocal object."""
        return json.dumps(self.to_dict(), indent=2)

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

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


class VPNGatewayConnectionStaticRouteModeLocalPrototype:
    """
    VPNGatewayConnectionStaticRouteModeLocalPrototype.

    :param List[VPNGatewayConnectionIKEIdentityPrototype] ike_identities: (optional)
          The local IKE identities to use.
          A VPN gateway in static route mode consists of two members in active-active
          mode. The first specified identity will be applied to the first member, and the
          second specified identity will be applied to the second member.
          If unspecified, then `type` will be `ipv4_address` and `value` will be the
          public IP address of the member's VPN connection tunnel.
    """

    def __init__(
        self,
        *,
        ike_identities: Optional[List['VPNGatewayConnectionIKEIdentityPrototype']] = None,
    ) -> None:
        """
        Initialize a VPNGatewayConnectionStaticRouteModeLocalPrototype object.

        :param List[VPNGatewayConnectionIKEIdentityPrototype] ike_identities:
               (optional) The local IKE identities to use.
               A VPN gateway in static route mode consists of two members in active-active
               mode. The first specified identity will be applied to the first member, and
               the second specified identity will be applied to the second member.
               If unspecified, then `type` will be `ipv4_address` and `value` will be the
               public IP address of the member's VPN connection tunnel.
        """
        self.ike_identities = ike_identities

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

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

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'ike_identities') and self.ike_identities is not None:
            ike_identities_list = []
            for v in self.ike_identities:
                if isinstance(v, dict):
                    ike_identities_list.append(v)
                else:
                    ike_identities_list.append(v.to_dict())
            _dict['ike_identities'] = ike_identities_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 VPNGatewayConnectionStaticRouteModeLocalPrototype object."""
        return json.dumps(self.to_dict(), indent=2)

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

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


class VPNGatewayConnectionStaticRouteModePeer:
    """
    VPNGatewayConnectionStaticRouteModePeer.

    :param VPNGatewayConnectionIKEIdentity ike_identity: The peer IKE identity.
    :param str type: Indicates whether `peer.address` or `peer.fqdn` is used.
    """

    def __init__(
        self,
        ike_identity: 'VPNGatewayConnectionIKEIdentity',
        type: str,
    ) -> None:
        """
        Initialize a VPNGatewayConnectionStaticRouteModePeer object.

        :param VPNGatewayConnectionIKEIdentity ike_identity: The peer IKE identity.
        :param str type: Indicates whether `peer.address` or `peer.fqdn` is used.
        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['VPNGatewayConnectionStaticRouteModePeerVPNGatewayConnectionPeerByAddress', 'VPNGatewayConnectionStaticRouteModePeerVPNGatewayConnectionPeerByFQDN'])
        )
        raise Exception(msg)

    class TypeEnum(str, Enum):
        """
        Indicates whether `peer.address` or `peer.fqdn` is used.
        """

        ADDRESS = 'address'
        FQDN = 'fqdn'



class VPNGatewayConnectionStaticRouteModePeerPrototype:
    """
    VPNGatewayConnectionStaticRouteModePeerPrototype.

    :param VPNGatewayConnectionIKEIdentityPrototype ike_identity: (optional) The
          peer IKE identity to use.
          If unspecified:
          - If `peer.address` is specified, the `type` will be `ipv4_address`, and
          the `value` will be `peer.address`.
          - If `peer.fqdn` is specified, the `type` will be `fqdn`, and the `value`
          will be `peer.fqdn`.
    """

    def __init__(
        self,
        *,
        ike_identity: Optional['VPNGatewayConnectionIKEIdentityPrototype'] = None,
    ) -> None:
        """
        Initialize a VPNGatewayConnectionStaticRouteModePeerPrototype object.

        :param VPNGatewayConnectionIKEIdentityPrototype ike_identity: (optional)
               The peer IKE identity to use.
               If unspecified:
               - If `peer.address` is specified, the `type` will be `ipv4_address`, and
               the `value` will be `peer.address`.
               - If `peer.fqdn` is specified, the `type` will be `fqdn`, and the `value`
               will be `peer.fqdn`.
        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['VPNGatewayConnectionStaticRouteModePeerPrototypeVPNGatewayConnectionPeerByAddress', 'VPNGatewayConnectionStaticRouteModePeerPrototypeVPNGatewayConnectionPeerByFQDN'])
        )
        raise Exception(msg)


class VPNGatewayConnectionStaticRouteModeTunnel:
    """
    VPNGatewayConnectionStaticRouteModeTunnel.

    :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.
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :param List[VPNGatewayConnectionTunnelStatusReason] status_reasons: The reasons
          for the current status (if any).
    """

    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.
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :param List[VPNGatewayConnectionTunnelStatusReason] status_reasons: The
               reasons for the current status (if any).
        """
        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 := _dict.get('public_ip')) is not None:
            args['public_ip'] = IP.from_dict(public_ip)
        else:
            raise ValueError('Required property \'public_ip\' not present in VPNGatewayConnectionStaticRouteModeTunnel JSON')
        if (status := _dict.get('status')) is not None:
            args['status'] = status
        else:
            raise ValueError('Required property \'status\' not present in VPNGatewayConnectionStaticRouteModeTunnel JSON')
        if (status_reasons := _dict.get('status_reasons')) is not None:
            args['status_reasons'] = [VPNGatewayConnectionTunnelStatusReason.from_dict(v) for v in 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.
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        DOWN = 'down'
        UP = 'up'



class VPNGatewayConnectionStatusReason:
    """
    VPNGatewayConnectionStatusReason.

    :param str code: A snake case string succinctly identifying the status reason.
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :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.
    """

    def __init__(
        self,
        code: str,
        message: str,
        *,
        more_info: Optional[str] = None,
    ) -> None:
        """
        Initialize a VPNGatewayConnectionStatusReason object.

        :param str code: A snake case string succinctly identifying the status
               reason.
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :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 := _dict.get('code')) is not None:
            args['code'] = code
        else:
            raise ValueError('Required property \'code\' not present in VPNGatewayConnectionStatusReason JSON')
        if (message := _dict.get('message')) is not None:
            args['message'] = message
        else:
            raise ValueError('Required property \'message\' not present in VPNGatewayConnectionStatusReason JSON')
        if (more_info := _dict.get('more_info')) is not None:
            args['more_info'] = 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.
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        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.

    :param str code: A reason code for this status:
          - `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 values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :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.
    """

    def __init__(
        self,
        code: str,
        message: str,
        *,
        more_info: Optional[str] = None,
    ) -> None:
        """
        Initialize a VPNGatewayConnectionTunnelStatusReason object.

        :param str code: A reason code for this status:
               - `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 values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :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 := _dict.get('code')) is not None:
            args['code'] = code
        else:
            raise ValueError('Required property \'code\' not present in VPNGatewayConnectionTunnelStatusReason JSON')
        if (message := _dict.get('message')) is not None:
            args['message'] = message
        else:
            raise ValueError('Required property \'message\' not present in VPNGatewayConnectionTunnelStatusReason JSON')
        if (more_info := _dict.get('more_info')) is not None:
            args['more_info'] = 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 reason code for this status:
        - `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 values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        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.

    :param str code: A reason code for this health state:
          - `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 values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :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.
    """

    def __init__(
        self,
        code: str,
        message: str,
        *,
        more_info: Optional[str] = None,
    ) -> None:
        """
        Initialize a VPNGatewayHealthReason object.

        :param str code: A reason code for this health state:
               - `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 values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :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 := _dict.get('code')) is not None:
            args['code'] = code
        else:
            raise ValueError('Required property \'code\' not present in VPNGatewayHealthReason JSON')
        if (message := _dict.get('message')) is not None:
            args['message'] = message
        else:
            raise ValueError('Required property \'message\' not present in VPNGatewayHealthReason JSON')
        if (more_info := _dict.get('more_info')) is not None:
            args['more_info'] = 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 reason code for this health state:
        - `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 values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        CANNOT_CREATE_VPC_ROUTE = 'cannot_create_vpc_route'
        CANNOT_RESERVE_IP_ADDRESS = 'cannot_reserve_ip_address'
        INTERNAL_ERROR = 'internal_error'



class VPNGatewayLifecycleReason:
    """
    VPNGatewayLifecycleReason.

    :param str code: A reason code for this lifecycle state:
          - `internal_error`: internal error (contact IBM support)
          - `resource_suspended_by_provider`: The resource has been suspended (contact IBM
            support)
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :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.
    """

    def __init__(
        self,
        code: str,
        message: str,
        *,
        more_info: Optional[str] = None,
    ) -> None:
        """
        Initialize a VPNGatewayLifecycleReason object.

        :param str code: A reason code for this lifecycle state:
               - `internal_error`: internal error (contact IBM support)
               - `resource_suspended_by_provider`: The resource has been suspended
               (contact IBM
                 support)
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :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 := _dict.get('code')) is not None:
            args['code'] = code
        else:
            raise ValueError('Required property \'code\' not present in VPNGatewayLifecycleReason JSON')
        if (message := _dict.get('message')) is not None:
            args['message'] = message
        else:
            raise ValueError('Required property \'message\' not present in VPNGatewayLifecycleReason JSON')
        if (more_info := _dict.get('more_info')) is not None:
            args['more_info'] = 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 reason code for this lifecycle state:
        - `internal_error`: internal error (contact IBM support)
        - `resource_suspended_by_provider`: The resource has been suspended (contact IBM
          support)
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        INTERNAL_ERROR = 'internal_error'
        RESOURCE_SUSPENDED_BY_PROVIDER = 'resource_suspended_by_provider'



class VPNGatewayMember:
    """
    VPNGatewayMember.

    :param List[VPNGatewayMemberHealthReason] health_reasons: The reasons for the
          current `health_state` (if any).
    :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 `lifecycle_state` (if any).
    :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.
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    """

    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 `health_state` (if any).
        :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 `lifecycle_state` (if any).
        :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.
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        """
        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 := _dict.get('health_reasons')) is not None:
            args['health_reasons'] = [VPNGatewayMemberHealthReason.from_dict(v) for v in health_reasons]
        else:
            raise ValueError('Required property \'health_reasons\' not present in VPNGatewayMember JSON')
        if (health_state := _dict.get('health_state')) is not None:
            args['health_state'] = health_state
        else:
            raise ValueError('Required property \'health_state\' not present in VPNGatewayMember JSON')
        if (lifecycle_reasons := _dict.get('lifecycle_reasons')) is not None:
            args['lifecycle_reasons'] = [VPNGatewayMemberLifecycleReason.from_dict(v) for v in lifecycle_reasons]
        else:
            raise ValueError('Required property \'lifecycle_reasons\' not present in VPNGatewayMember JSON')
        if (lifecycle_state := _dict.get('lifecycle_state')) is not None:
            args['lifecycle_state'] = lifecycle_state
        else:
            raise ValueError('Required property \'lifecycle_state\' not present in VPNGatewayMember JSON')
        if (private_ip := _dict.get('private_ip')) is not None:
            args['private_ip'] = ReservedIPReference.from_dict(private_ip)
        else:
            raise ValueError('Required property \'private_ip\' not present in VPNGatewayMember JSON')
        if (public_ip := _dict.get('public_ip')) is not None:
            args['public_ip'] = IP.from_dict(public_ip)
        else:
            raise ValueError('Required property \'public_ip\' not present in VPNGatewayMember JSON')
        if (role := _dict.get('role')) is not None:
            args['role'] = 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.
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        ACTIVE = 'active'
        STANDBY = 'standby'



class VPNGatewayMemberHealthReason:
    """
    VPNGatewayMemberHealthReason.

    :param str code: A reason code for this health state:
          - `cannot_reserve_ip_address`: IP address exhaustion (release addresses on the
          VPN's
            subnet)
          - `internal_error`: Internal error (contact IBM support)
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :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.
    """

    def __init__(
        self,
        code: str,
        message: str,
        *,
        more_info: Optional[str] = None,
    ) -> None:
        """
        Initialize a VPNGatewayMemberHealthReason object.

        :param str code: A reason code for this health state:
               - `cannot_reserve_ip_address`: IP address exhaustion (release addresses on
               the VPN's
                 subnet)
               - `internal_error`: Internal error (contact IBM support)
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :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 := _dict.get('code')) is not None:
            args['code'] = code
        else:
            raise ValueError('Required property \'code\' not present in VPNGatewayMemberHealthReason JSON')
        if (message := _dict.get('message')) is not None:
            args['message'] = message
        else:
            raise ValueError('Required property \'message\' not present in VPNGatewayMemberHealthReason JSON')
        if (more_info := _dict.get('more_info')) is not None:
            args['more_info'] = 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 reason code for this health state:
        - `cannot_reserve_ip_address`: IP address exhaustion (release addresses on the
        VPN's
          subnet)
        - `internal_error`: Internal error (contact IBM support)
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        CANNOT_RESERVE_IP_ADDRESS = 'cannot_reserve_ip_address'
        INTERNAL_ERROR = 'internal_error'



class VPNGatewayMemberLifecycleReason:
    """
    VPNGatewayMemberLifecycleReason.

    :param str code: A reason code for this lifecycle state:
          - `internal_error`: internal error (contact IBM support)
          - `resource_suspended_by_provider`: The resource has been suspended (contact IBM
            support)
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :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.
    """

    def __init__(
        self,
        code: str,
        message: str,
        *,
        more_info: Optional[str] = None,
    ) -> None:
        """
        Initialize a VPNGatewayMemberLifecycleReason object.

        :param str code: A reason code for this lifecycle state:
               - `internal_error`: internal error (contact IBM support)
               - `resource_suspended_by_provider`: The resource has been suspended
               (contact IBM
                 support)
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :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 := _dict.get('code')) is not None:
            args['code'] = code
        else:
            raise ValueError('Required property \'code\' not present in VPNGatewayMemberLifecycleReason JSON')
        if (message := _dict.get('message')) is not None:
            args['message'] = message
        else:
            raise ValueError('Required property \'message\' not present in VPNGatewayMemberLifecycleReason JSON')
        if (more_info := _dict.get('more_info')) is not None:
            args['more_info'] = 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 reason code for this lifecycle state:
        - `internal_error`: internal error (contact IBM support)
        - `resource_suspended_by_provider`: The resource has been suspended (contact IBM
          support)
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        INTERNAL_ERROR = 'internal_error'
        RESOURCE_SUSPENDED_BY_PROVIDER = 'resource_suspended_by_provider'



class VPNGatewayPatch:
    """
    VPNGatewayPatch.

    :param 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: Optional[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 := _dict.get('name')) is not None:
            args['name'] = 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.

    :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.
    :param SubnetIdentity subnet: Identifies a subnet by a unique property.
    """

    def __init__(
        self,
        subnet: 'SubnetIdentity',
        *,
        name: Optional[str] = None,
        resource_group: Optional['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 VPNServer:
    """
    VPNServer.

    :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
          `health_state` (if any).
    :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 `lifecycle_state` (if any).
    :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 to use for this VPN server.
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :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.
    """

    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 `health_state` (if any).
        :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 `lifecycle_state` (if any).
        :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 to use for this VPN server.
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :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 := _dict.get('certificate')) is not None:
            args['certificate'] = CertificateInstanceReference.from_dict(certificate)
        else:
            raise ValueError('Required property \'certificate\' not present in VPNServer JSON')
        if (client_authentication := _dict.get('client_authentication')) is not None:
            args['client_authentication'] = client_authentication
        else:
            raise ValueError('Required property \'client_authentication\' not present in VPNServer JSON')
        if (client_auto_delete := _dict.get('client_auto_delete')) is not None:
            args['client_auto_delete'] = client_auto_delete
        else:
            raise ValueError('Required property \'client_auto_delete\' not present in VPNServer JSON')
        if (client_auto_delete_timeout := _dict.get('client_auto_delete_timeout')) is not None:
            args['client_auto_delete_timeout'] = client_auto_delete_timeout
        else:
            raise ValueError('Required property \'client_auto_delete_timeout\' not present in VPNServer JSON')
        if (client_dns_server_ips := _dict.get('client_dns_server_ips')) is not None:
            args['client_dns_server_ips'] = [IP.from_dict(v) for v in client_dns_server_ips]
        else:
            raise ValueError('Required property \'client_dns_server_ips\' not present in VPNServer JSON')
        if (client_idle_timeout := _dict.get('client_idle_timeout')) is not None:
            args['client_idle_timeout'] = client_idle_timeout
        else:
            raise ValueError('Required property \'client_idle_timeout\' not present in VPNServer JSON')
        if (client_ip_pool := _dict.get('client_ip_pool')) is not None:
            args['client_ip_pool'] = client_ip_pool
        else:
            raise ValueError('Required property \'client_ip_pool\' not present in VPNServer JSON')
        if (created_at := _dict.get('created_at')) is not None:
            args['created_at'] = string_to_datetime(created_at)
        else:
            raise ValueError('Required property \'created_at\' not present in VPNServer JSON')
        if (crn := _dict.get('crn')) is not None:
            args['crn'] = crn
        else:
            raise ValueError('Required property \'crn\' not present in VPNServer JSON')
        if (enable_split_tunneling := _dict.get('enable_split_tunneling')) is not None:
            args['enable_split_tunneling'] = enable_split_tunneling
        else:
            raise ValueError('Required property \'enable_split_tunneling\' not present in VPNServer JSON')
        if (health_reasons := _dict.get('health_reasons')) is not None:
            args['health_reasons'] = [VPNServerHealthReason.from_dict(v) for v in health_reasons]
        else:
            raise ValueError('Required property \'health_reasons\' not present in VPNServer JSON')
        if (health_state := _dict.get('health_state')) is not None:
            args['health_state'] = health_state
        else:
            raise ValueError('Required property \'health_state\' not present in VPNServer JSON')
        if (hostname := _dict.get('hostname')) is not None:
            args['hostname'] = hostname
        else:
            raise ValueError('Required property \'hostname\' not present in VPNServer JSON')
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in VPNServer JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in VPNServer JSON')
        if (lifecycle_reasons := _dict.get('lifecycle_reasons')) is not None:
            args['lifecycle_reasons'] = [VPNServerLifecycleReason.from_dict(v) for v in lifecycle_reasons]
        else:
            raise ValueError('Required property \'lifecycle_reasons\' not present in VPNServer JSON')
        if (lifecycle_state := _dict.get('lifecycle_state')) is not None:
            args['lifecycle_state'] = lifecycle_state
        else:
            raise ValueError('Required property \'lifecycle_state\' not present in VPNServer JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in VPNServer JSON')
        if (port := _dict.get('port')) is not None:
            args['port'] = port
        else:
            raise ValueError('Required property \'port\' not present in VPNServer JSON')
        if (private_ips := _dict.get('private_ips')) is not None:
            args['private_ips'] = [ReservedIPReference.from_dict(v) for v in private_ips]
        else:
            raise ValueError('Required property \'private_ips\' not present in VPNServer JSON')
        if (protocol := _dict.get('protocol')) is not None:
            args['protocol'] = protocol
        else:
            raise ValueError('Required property \'protocol\' not present in VPNServer JSON')
        if (resource_group := _dict.get('resource_group')) is not None:
            args['resource_group'] = ResourceGroupReference.from_dict(resource_group)
        else:
            raise ValueError('Required property \'resource_group\' not present in VPNServer JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = resource_type
        else:
            raise ValueError('Required property \'resource_type\' not present in VPNServer JSON')
        if (security_groups := _dict.get('security_groups')) is not None:
            args['security_groups'] = [SecurityGroupReference.from_dict(v) for v in security_groups]
        else:
            raise ValueError('Required property \'security_groups\' not present in VPNServer JSON')
        if (subnets := _dict.get('subnets')) is not None:
            args['subnets'] = [SubnetReference.from_dict(v) for v in subnets]
        else:
            raise ValueError('Required property \'subnets\' not present in VPNServer JSON')
        if (vpc := _dict.get('vpc')) is not None:
            args['vpc'] = VPCReference.from_dict(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 to use for this VPN server.
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        TCP = 'tcp'
        UDP = 'udp'


    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        VPN_SERVER = 'vpn_server'



class VPNServerAuthentication:
    """
    An authentication method for this VPN server.

    :param str method: The type of authentication.
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    """

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

        :param str method: The type of authentication.
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        """
        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.
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        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.

    :param 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.

    :param IP client_ip: The IP address assigned to this VPN client from
          `client_ip_pool`.
    :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 created_at: The date and time that the VPN client was created.
    :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 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 may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :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.
    """

    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: Optional[str] = None,
        disconnected_at: Optional[datetime] = None,
        username: Optional[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 may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :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 := _dict.get('client_ip')) is not None:
            args['client_ip'] = IP.from_dict(client_ip)
        else:
            raise ValueError('Required property \'client_ip\' not present in VPNServerClient JSON')
        if (common_name := _dict.get('common_name')) is not None:
            args['common_name'] = common_name
        if (created_at := _dict.get('created_at')) is not None:
            args['created_at'] = string_to_datetime(created_at)
        else:
            raise ValueError('Required property \'created_at\' not present in VPNServerClient JSON')
        if (disconnected_at := _dict.get('disconnected_at')) is not None:
            args['disconnected_at'] = string_to_datetime(disconnected_at)
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in VPNServerClient JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in VPNServerClient JSON')
        if (remote_ip := _dict.get('remote_ip')) is not None:
            args['remote_ip'] = IP.from_dict(remote_ip)
        else:
            raise ValueError('Required property \'remote_ip\' not present in VPNServerClient JSON')
        if (remote_port := _dict.get('remote_port')) is not None:
            args['remote_port'] = remote_port
        else:
            raise ValueError('Required property \'remote_port\' not present in VPNServerClient JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = resource_type
        else:
            raise ValueError('Required property \'resource_type\' not present in VPNServerClient JSON')
        if (status := _dict.get('status')) is not None:
            args['status'] = status
        else:
            raise ValueError('Required property \'status\' not present in VPNServerClient JSON')
        if (username := _dict.get('username')) is not None:
            args['username'] = 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 may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        CONNECTED = 'connected'
        DISCONNECTED = 'disconnected'



class VPNServerClientCollection:
    """
    VPNServerClientCollection.

    :param List[VPNServerClient] clients: A page of clients of the VPN server.
    :param PageLink 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 PageLink next: (optional) A link to the next page of resources. This
          property is present for all pages
          except the last page.
    :param int total_count: The total number of resources across all pages.
    """

    def __init__(
        self,
        clients: List['VPNServerClient'],
        first: 'PageLink',
        limit: int,
        total_count: int,
        *,
        next: Optional['PageLink'] = None,
    ) -> None:
        """
        Initialize a VPNServerClientCollection object.

        :param List[VPNServerClient] clients: A page of clients of the VPN server.
        :param PageLink 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 PageLink 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 := _dict.get('clients')) is not None:
            args['clients'] = [VPNServerClient.from_dict(v) for v in clients]
        else:
            raise ValueError('Required property \'clients\' not present in VPNServerClientCollection JSON')
        if (first := _dict.get('first')) is not None:
            args['first'] = PageLink.from_dict(first)
        else:
            raise ValueError('Required property \'first\' not present in VPNServerClientCollection JSON')
        if (limit := _dict.get('limit')) is not None:
            args['limit'] = limit
        else:
            raise ValueError('Required property \'limit\' not present in VPNServerClientCollection JSON')
        if (next := _dict.get('next')) is not None:
            args['next'] = PageLink.from_dict(next)
        if (total_count := _dict.get('total_count')) is not None:
            args['total_count'] = 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 VPNServerCollection:
    """
    VPNServerCollection.

    :param PageLink 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 PageLink next: (optional) A link to the next page of resources. This
          property is present for all pages
          except the last page.
    :param int total_count: The total number of resources across all pages.
    :param List[VPNServer] vpn_servers: A page of VPN servers.
    """

    def __init__(
        self,
        first: 'PageLink',
        limit: int,
        total_count: int,
        vpn_servers: List['VPNServer'],
        *,
        next: Optional['PageLink'] = None,
    ) -> None:
        """
        Initialize a VPNServerCollection object.

        :param PageLink 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: A page of VPN servers.
        :param PageLink 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 := _dict.get('first')) is not None:
            args['first'] = PageLink.from_dict(first)
        else:
            raise ValueError('Required property \'first\' not present in VPNServerCollection JSON')
        if (limit := _dict.get('limit')) is not None:
            args['limit'] = limit
        else:
            raise ValueError('Required property \'limit\' not present in VPNServerCollection JSON')
        if (next := _dict.get('next')) is not None:
            args['next'] = PageLink.from_dict(next)
        if (total_count := _dict.get('total_count')) is not None:
            args['total_count'] = total_count
        else:
            raise ValueError('Required property \'total_count\' not present in VPNServerCollection JSON')
        if (vpn_servers := _dict.get('vpn_servers')) is not None:
            args['vpn_servers'] = [VPNServer.from_dict(v) for v in 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 VPNServerHealthReason:
    """
    VPNServerHealthReason.

    :param str code: A reason code for this health state:
          - `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 values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :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.
    """

    def __init__(
        self,
        code: str,
        message: str,
        *,
        more_info: Optional[str] = None,
    ) -> None:
        """
        Initialize a VPNServerHealthReason object.

        :param str code: A reason code for this health state:
               - `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 values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :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 := _dict.get('code')) is not None:
            args['code'] = code
        else:
            raise ValueError('Required property \'code\' not present in VPNServerHealthReason JSON')
        if (message := _dict.get('message')) is not None:
            args['message'] = message
        else:
            raise ValueError('Required property \'message\' not present in VPNServerHealthReason JSON')
        if (more_info := _dict.get('more_info')) is not None:
            args['more_info'] = 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 reason code for this health state:
        - `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 values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        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.

    :param str code: A reason code for this lifecycle state:
          - `internal_error`: internal error (contact IBM support)
          - `resource_suspended_by_provider`: The resource has been suspended (contact IBM
            support)
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :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.
    """

    def __init__(
        self,
        code: str,
        message: str,
        *,
        more_info: Optional[str] = None,
    ) -> None:
        """
        Initialize a VPNServerLifecycleReason object.

        :param str code: A reason code for this lifecycle state:
               - `internal_error`: internal error (contact IBM support)
               - `resource_suspended_by_provider`: The resource has been suspended
               (contact IBM
                 support)
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :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 := _dict.get('code')) is not None:
            args['code'] = code
        else:
            raise ValueError('Required property \'code\' not present in VPNServerLifecycleReason JSON')
        if (message := _dict.get('message')) is not None:
            args['message'] = message
        else:
            raise ValueError('Required property \'message\' not present in VPNServerLifecycleReason JSON')
        if (more_info := _dict.get('more_info')) is not None:
            args['more_info'] = 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 reason code for this lifecycle state:
        - `internal_error`: internal error (contact IBM support)
        - `resource_suspended_by_provider`: The resource has been suspended (contact IBM
          support)
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        INTERNAL_ERROR = 'internal_error'
        RESOURCE_SUSPENDED_BY_PROVIDER = 'resource_suspended_by_provider'



class VPNServerPatch:
    """
    VPNServerPatch.

    :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 to use for this VPN
          server.
    :param List[SubnetIdentity] subnets: (optional) The subnets to provision this
          VPN server in (replacing the existing subnets).
    """

    def __init__(
        self,
        *,
        certificate: Optional['CertificateInstanceIdentity'] = None,
        client_authentication: Optional[List['VPNServerAuthenticationPrototype']] = None,
        client_dns_server_ips: Optional[List['IP']] = None,
        client_idle_timeout: Optional[int] = None,
        client_ip_pool: Optional[str] = None,
        enable_split_tunneling: Optional[bool] = None,
        name: Optional[str] = None,
        port: Optional[int] = None,
        protocol: Optional[str] = None,
        subnets: Optional[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 to use for 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 := _dict.get('certificate')) is not None:
            args['certificate'] = certificate
        if (client_authentication := _dict.get('client_authentication')) is not None:
            args['client_authentication'] = [VPNServerAuthenticationPrototype.from_dict(v) for v in client_authentication]
        if (client_dns_server_ips := _dict.get('client_dns_server_ips')) is not None:
            args['client_dns_server_ips'] = [IP.from_dict(v) for v in client_dns_server_ips]
        if (client_idle_timeout := _dict.get('client_idle_timeout')) is not None:
            args['client_idle_timeout'] = client_idle_timeout
        if (client_ip_pool := _dict.get('client_ip_pool')) is not None:
            args['client_ip_pool'] = client_ip_pool
        if (enable_split_tunneling := _dict.get('enable_split_tunneling')) is not None:
            args['enable_split_tunneling'] = enable_split_tunneling
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        if (port := _dict.get('port')) is not None:
            args['port'] = port
        if (protocol := _dict.get('protocol')) is not None:
            args['protocol'] = protocol
        if (subnets := _dict.get('subnets')) is not None:
            args['subnets'] = 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 to use for this VPN server.
        """

        TCP = 'tcp'
        UDP = 'udp'



class VPNServerRoute:
    """
    VPNServerRoute.

    :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, then deliver the packet to target.
          - `deliver`: deliver the packet into the VPC.
          - `drop`: drop the packet
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :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 `health_state` (if any).
    :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 `lifecycle_state` (if any).
    :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.
    """

    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, then deliver the packet to target.
               - `deliver`: deliver the packet into the VPC.
               - `drop`: drop the packet
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :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 `health_state` (if any).
        :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 `lifecycle_state` (if any).
        :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 := _dict.get('action')) is not None:
            args['action'] = action
        else:
            raise ValueError('Required property \'action\' not present in VPNServerRoute JSON')
        if (created_at := _dict.get('created_at')) is not None:
            args['created_at'] = string_to_datetime(created_at)
        else:
            raise ValueError('Required property \'created_at\' not present in VPNServerRoute JSON')
        if (destination := _dict.get('destination')) is not None:
            args['destination'] = destination
        else:
            raise ValueError('Required property \'destination\' not present in VPNServerRoute JSON')
        if (health_reasons := _dict.get('health_reasons')) is not None:
            args['health_reasons'] = [VPNServerRouteHealthReason.from_dict(v) for v in health_reasons]
        else:
            raise ValueError('Required property \'health_reasons\' not present in VPNServerRoute JSON')
        if (health_state := _dict.get('health_state')) is not None:
            args['health_state'] = health_state
        else:
            raise ValueError('Required property \'health_state\' not present in VPNServerRoute JSON')
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in VPNServerRoute JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in VPNServerRoute JSON')
        if (lifecycle_reasons := _dict.get('lifecycle_reasons')) is not None:
            args['lifecycle_reasons'] = [VPNServerRouteLifecycleReason.from_dict(v) for v in lifecycle_reasons]
        else:
            raise ValueError('Required property \'lifecycle_reasons\' not present in VPNServerRoute JSON')
        if (lifecycle_state := _dict.get('lifecycle_state')) is not None:
            args['lifecycle_state'] = lifecycle_state
        else:
            raise ValueError('Required property \'lifecycle_state\' not present in VPNServerRoute JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in VPNServerRoute JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = 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, then deliver the packet to target.
        - `deliver`: deliver the packet into the VPC.
        - `drop`: drop the packet
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        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.

    :param PageLink 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 PageLink next: (optional) A link to the next page of resources. This
          property is present for all pages
          except the last page.
    :param List[VPNServerRoute] routes: A page of routes for the VPN server.
    :param int total_count: The total number of resources across all pages.
    """

    def __init__(
        self,
        first: 'PageLink',
        limit: int,
        routes: List['VPNServerRoute'],
        total_count: int,
        *,
        next: Optional['PageLink'] = None,
    ) -> None:
        """
        Initialize a VPNServerRouteCollection object.

        :param PageLink 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: A page of routes for the VPN server.
        :param int total_count: The total number of resources across all pages.
        :param PageLink 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 := _dict.get('first')) is not None:
            args['first'] = PageLink.from_dict(first)
        else:
            raise ValueError('Required property \'first\' not present in VPNServerRouteCollection JSON')
        if (limit := _dict.get('limit')) is not None:
            args['limit'] = limit
        else:
            raise ValueError('Required property \'limit\' not present in VPNServerRouteCollection JSON')
        if (next := _dict.get('next')) is not None:
            args['next'] = PageLink.from_dict(next)
        if (routes := _dict.get('routes')) is not None:
            args['routes'] = [VPNServerRoute.from_dict(v) for v in routes]
        else:
            raise ValueError('Required property \'routes\' not present in VPNServerRouteCollection JSON')
        if (total_count := _dict.get('total_count')) is not None:
            args['total_count'] = 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 VPNServerRouteHealthReason:
    """
    VPNServerRouteHealthReason.

    :param str code: A reason code for this health state:
          - `internal_error`: Internal error (contact IBM support)
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :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.
    """

    def __init__(
        self,
        code: str,
        message: str,
        *,
        more_info: Optional[str] = None,
    ) -> None:
        """
        Initialize a VPNServerRouteHealthReason object.

        :param str code: A reason code for this health state:
               - `internal_error`: Internal error (contact IBM support)
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :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 := _dict.get('code')) is not None:
            args['code'] = code
        else:
            raise ValueError('Required property \'code\' not present in VPNServerRouteHealthReason JSON')
        if (message := _dict.get('message')) is not None:
            args['message'] = message
        else:
            raise ValueError('Required property \'message\' not present in VPNServerRouteHealthReason JSON')
        if (more_info := _dict.get('more_info')) is not None:
            args['more_info'] = 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 reason code for this health state:
        - `internal_error`: Internal error (contact IBM support)
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        INTERNAL_ERROR = 'internal_error'



class VPNServerRouteLifecycleReason:
    """
    VPNServerRouteLifecycleReason.

    :param str code: A reason code for this lifecycle state:
          - `internal_error`: internal error (contact IBM support)
          - `resource_suspended_by_provider`: The resource has been suspended (contact IBM
            support)
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :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.
    """

    def __init__(
        self,
        code: str,
        message: str,
        *,
        more_info: Optional[str] = None,
    ) -> None:
        """
        Initialize a VPNServerRouteLifecycleReason object.

        :param str code: A reason code for this lifecycle state:
               - `internal_error`: internal error (contact IBM support)
               - `resource_suspended_by_provider`: The resource has been suspended
               (contact IBM
                 support)
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :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 := _dict.get('code')) is not None:
            args['code'] = code
        else:
            raise ValueError('Required property \'code\' not present in VPNServerRouteLifecycleReason JSON')
        if (message := _dict.get('message')) is not None:
            args['message'] = message
        else:
            raise ValueError('Required property \'message\' not present in VPNServerRouteLifecycleReason JSON')
        if (more_info := _dict.get('more_info')) is not None:
            args['more_info'] = 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 reason code for this lifecycle state:
        - `internal_error`: internal error (contact IBM support)
        - `resource_suspended_by_provider`: The resource has been suspended (contact IBM
          support)
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        INTERNAL_ERROR = 'internal_error'
        RESOURCE_SUSPENDED_BY_PROVIDER = 'resource_suspended_by_provider'



class VPNServerRoutePatch:
    """
    VPNServerRoutePatch.

    :param 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: Optional[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 := _dict.get('name')) is not None:
            args['name'] = 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.

    :param bool allow_ip_spoofing: Indicates whether source IP spoofing is allowed
          on this interface. If `false`, source IP spoofing is prevented on this
          interface. If `true`, source IP spoofing is allowed on this interface.
    :param 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 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 virtual network interface,
            allowing the workload to perform any needed NAT operations.
          - `allow_ip_spoofing` must be `false`.
          - Can only be attached to a `target` with a `resource_type` of
            `bare_metal_server_network_attachment`.
    :param str href: The URL for this virtual network interface.
    :param str id: The unique identifier for this virtual network interface.
    :param List[ReservedIPReference] ips: The reserved IPs bound to this virtual
          network interface.
          May be empty when `lifecycle_state` is `pending`.
    :param str lifecycle_state: The lifecycle state of the virtual network
          interface.
    :param str mac_address: (optional) The MAC address of the virtual network
          interface. May be absent if `lifecycle_state` is `pending`.
    :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 str protocol_state_filtering_mode: The protocol state filtering mode used
          for this virtual network interface. If `auto`, protocol state packet filtering
          is enabled or disabled based on the virtual network interface's `target`
          resource type:
          - `bare_metal_server_network_attachment`: disabled
          - `instance_network_attachment`: enabled
          - `share_mount_target`: enabled
          Protocol state filtering monitors each network connection flowing over this
          virtual network interface, and drops any packets that are invalid based on the
          current connection state and protocol. See [Protocol state filtering
          mode](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#protocol-state-filtering))
          for more information.
    :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 VirtualNetworkInterfaceTarget target: (optional) The target of this
          virtual network interface.
          If absent, this virtual network interface is not attached to a target.
    :param VPCReference vpc: The VPC this virtual network interface resides in.
    :param ZoneReference zone: The zone this virtual network interface resides in.
    """

    def __init__(
        self,
        allow_ip_spoofing: bool,
        auto_delete: bool,
        created_at: datetime,
        crn: str,
        enable_infrastructure_nat: bool,
        href: str,
        id: str,
        ips: List['ReservedIPReference'],
        lifecycle_state: str,
        name: str,
        primary_ip: 'ReservedIPReference',
        protocol_state_filtering_mode: str,
        resource_group: 'ResourceGroupReference',
        resource_type: str,
        security_groups: List['SecurityGroupReference'],
        subnet: 'SubnetReference',
        vpc: 'VPCReference',
        zone: 'ZoneReference',
        *,
        mac_address: Optional[str] = None,
        target: Optional['VirtualNetworkInterfaceTarget'] = None,
    ) -> None:
        """
        Initialize a VirtualNetworkInterface object.

        :param bool allow_ip_spoofing: Indicates whether source IP spoofing is
               allowed on this interface. If `false`, source IP spoofing is prevented on
               this interface. If `true`, source IP spoofing is allowed on this interface.
        :param 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 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 virtual network interface,
                 allowing the workload to perform any needed NAT operations.
               - `allow_ip_spoofing` must be `false`.
               - Can only be attached to a `target` with a `resource_type` of
                 `bare_metal_server_network_attachment`.
        :param str href: The URL for this virtual network interface.
        :param str id: The unique identifier for this virtual network interface.
        :param List[ReservedIPReference] ips: The reserved IPs bound to this
               virtual network interface.
               May be empty when `lifecycle_state` is `pending`.
        :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 str protocol_state_filtering_mode: The protocol state filtering mode
               used for this virtual network interface. If `auto`, protocol state packet
               filtering is enabled or disabled based on the virtual network interface's
               `target` resource type:
               - `bare_metal_server_network_attachment`: disabled
               - `instance_network_attachment`: enabled
               - `share_mount_target`: enabled
               Protocol state filtering monitors each network connection flowing over this
               virtual network interface, and drops any packets that are invalid based on
               the current connection state and protocol. See [Protocol state filtering
               mode](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#protocol-state-filtering))
               for more information.
        :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 str mac_address: (optional) The MAC address of the virtual network
               interface. May be absent if `lifecycle_state` is `pending`.
        :param VirtualNetworkInterfaceTarget target: (optional) The target of this
               virtual network interface.
               If absent, this virtual network interface is not attached to a target.
        """
        self.allow_ip_spoofing = allow_ip_spoofing
        self.auto_delete = auto_delete
        self.created_at = created_at
        self.crn = crn
        self.enable_infrastructure_nat = enable_infrastructure_nat
        self.href = href
        self.id = id
        self.ips = ips
        self.lifecycle_state = lifecycle_state
        self.mac_address = mac_address
        self.name = name
        self.primary_ip = primary_ip
        self.protocol_state_filtering_mode = protocol_state_filtering_mode
        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 (allow_ip_spoofing := _dict.get('allow_ip_spoofing')) is not None:
            args['allow_ip_spoofing'] = allow_ip_spoofing
        else:
            raise ValueError('Required property \'allow_ip_spoofing\' not present in VirtualNetworkInterface JSON')
        if (auto_delete := _dict.get('auto_delete')) is not None:
            args['auto_delete'] = auto_delete
        else:
            raise ValueError('Required property \'auto_delete\' not present in VirtualNetworkInterface JSON')
        if (created_at := _dict.get('created_at')) is not None:
            args['created_at'] = string_to_datetime(created_at)
        else:
            raise ValueError('Required property \'created_at\' not present in VirtualNetworkInterface JSON')
        if (crn := _dict.get('crn')) is not None:
            args['crn'] = crn
        else:
            raise ValueError('Required property \'crn\' not present in VirtualNetworkInterface JSON')
        if (enable_infrastructure_nat := _dict.get('enable_infrastructure_nat')) is not None:
            args['enable_infrastructure_nat'] = enable_infrastructure_nat
        else:
            raise ValueError('Required property \'enable_infrastructure_nat\' not present in VirtualNetworkInterface JSON')
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in VirtualNetworkInterface JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in VirtualNetworkInterface JSON')
        if (ips := _dict.get('ips')) is not None:
            args['ips'] = [ReservedIPReference.from_dict(v) for v in ips]
        else:
            raise ValueError('Required property \'ips\' not present in VirtualNetworkInterface JSON')
        if (lifecycle_state := _dict.get('lifecycle_state')) is not None:
            args['lifecycle_state'] = lifecycle_state
        else:
            raise ValueError('Required property \'lifecycle_state\' not present in VirtualNetworkInterface JSON')
        if (mac_address := _dict.get('mac_address')) is not None:
            args['mac_address'] = mac_address
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in VirtualNetworkInterface JSON')
        if (primary_ip := _dict.get('primary_ip')) is not None:
            args['primary_ip'] = ReservedIPReference.from_dict(primary_ip)
        else:
            raise ValueError('Required property \'primary_ip\' not present in VirtualNetworkInterface JSON')
        if (protocol_state_filtering_mode := _dict.get('protocol_state_filtering_mode')) is not None:
            args['protocol_state_filtering_mode'] = protocol_state_filtering_mode
        else:
            raise ValueError('Required property \'protocol_state_filtering_mode\' not present in VirtualNetworkInterface JSON')
        if (resource_group := _dict.get('resource_group')) is not None:
            args['resource_group'] = ResourceGroupReference.from_dict(resource_group)
        else:
            raise ValueError('Required property \'resource_group\' not present in VirtualNetworkInterface JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = resource_type
        else:
            raise ValueError('Required property \'resource_type\' not present in VirtualNetworkInterface JSON')
        if (security_groups := _dict.get('security_groups')) is not None:
            args['security_groups'] = [SecurityGroupReference.from_dict(v) for v in security_groups]
        else:
            raise ValueError('Required property \'security_groups\' not present in VirtualNetworkInterface JSON')
        if (subnet := _dict.get('subnet')) is not None:
            args['subnet'] = SubnetReference.from_dict(subnet)
        else:
            raise ValueError('Required property \'subnet\' not present in VirtualNetworkInterface JSON')
        if (target := _dict.get('target')) is not None:
            args['target'] = target
        if (vpc := _dict.get('vpc')) is not None:
            args['vpc'] = VPCReference.from_dict(vpc)
        else:
            raise ValueError('Required property \'vpc\' not present in VirtualNetworkInterface JSON')
        if (zone := _dict.get('zone')) is not None:
            args['zone'] = ZoneReference.from_dict(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, 'allow_ip_spoofing') and self.allow_ip_spoofing is not None:
            _dict['allow_ip_spoofing'] = self.allow_ip_spoofing
        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, 'enable_infrastructure_nat') and self.enable_infrastructure_nat is not None:
            _dict['enable_infrastructure_nat'] = self.enable_infrastructure_nat
        if hasattr(self, 'href') and self.href 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, '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, '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, 'protocol_state_filtering_mode') and self.protocol_state_filtering_mode is not None:
            _dict['protocol_state_filtering_mode'] = self.protocol_state_filtering_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
        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 ProtocolStateFilteringModeEnum(str, Enum):
        """
        The protocol state filtering mode used for this virtual network interface. If
        `auto`, protocol state packet filtering is enabled or disabled based on the
        virtual network interface's `target` resource type:
        - `bare_metal_server_network_attachment`: disabled
        - `instance_network_attachment`: enabled
        - `share_mount_target`: enabled
        Protocol state filtering monitors each network connection flowing over this
        virtual network interface, and drops any packets that are invalid based on the
        current connection state and protocol. See [Protocol state filtering
        mode](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#protocol-state-filtering))
        for more information.
        """

        AUTO = 'auto'
        DISABLED = 'disabled'
        ENABLED = 'enabled'


    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        VIRTUAL_NETWORK_INTERFACE = 'virtual_network_interface'



class VirtualNetworkInterfaceCollection:
    """
    VirtualNetworkInterfaceCollection.

    :param PageLink 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 PageLink next: (optional) A link to the next page of resources. This
          property is present for all pages
          except the last page.
    :param int total_count: The total number of resources across all pages.
    :param List[VirtualNetworkInterface] virtual_network_interfaces: A page of
          virtual network interfaces.
    """

    def __init__(
        self,
        first: 'PageLink',
        limit: int,
        total_count: int,
        virtual_network_interfaces: List['VirtualNetworkInterface'],
        *,
        next: Optional['PageLink'] = None,
    ) -> None:
        """
        Initialize a VirtualNetworkInterfaceCollection object.

        :param PageLink 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: A page of
               virtual network interfaces.
        :param PageLink 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 := _dict.get('first')) is not None:
            args['first'] = PageLink.from_dict(first)
        else:
            raise ValueError('Required property \'first\' not present in VirtualNetworkInterfaceCollection JSON')
        if (limit := _dict.get('limit')) is not None:
            args['limit'] = limit
        else:
            raise ValueError('Required property \'limit\' not present in VirtualNetworkInterfaceCollection JSON')
        if (next := _dict.get('next')) is not None:
            args['next'] = PageLink.from_dict(next)
        if (total_count := _dict.get('total_count')) is not None:
            args['total_count'] = total_count
        else:
            raise ValueError('Required property \'total_count\' not present in VirtualNetworkInterfaceCollection JSON')
        if (virtual_network_interfaces := _dict.get('virtual_network_interfaces')) is not None:
            args['virtual_network_interfaces'] = [VirtualNetworkInterface.from_dict(v) for v in 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 VirtualNetworkInterfaceIPPrototype:
    """
    VirtualNetworkInterfaceIPPrototype.

    """

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

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


class VirtualNetworkInterfacePatch:
    """
    VirtualNetworkInterfacePatch.

    :param bool allow_ip_spoofing: (optional) Indicates whether source IP spoofing
          is allowed on this interface.
          Must be `false` if `target` is a file share mount target.
    :param bool auto_delete: (optional) Indicates whether this virtual network
          interface will be automatically deleted when
          `target` is deleted. Must be `false` if the virtual network interface is
          unbound.
    :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 virtual network interface,
            allowing the workload to perform any needed NAT operations.
          - `allow_ip_spoofing` must be `false`.
          - Can only be attached to a `target` with a `resource_type` of
            `bare_metal_server_network_attachment`.
    :param str name: (optional) The name for this virtual network interface. The
          name must not be used by another virtual network interface in the region. Names
          beginning with `ibm-` are reserved for provider-owned resources, and are not
          allowed.
    :param str protocol_state_filtering_mode: (optional) The protocol state
          filtering mode to use for this virtual network interface. If
          `auto`, protocol state packet filtering is enabled or disabled based on the
          virtual network interface's `target` resource type:
          - `bare_metal_server_network_attachment`: disabled
          - `instance_network_attachment`: enabled
          - `share_mount_target`: enabled
          Must not be `disabled` if the virtual network interface's `target` resource type
          is
          `share_mount_target`.
          Protocol state filtering monitors each network connection flowing over this
          virtual network interface, and drops any packets that are invalid based on the
          current connection state and protocol. See [Protocol state filtering
          mode](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#protocol-state-filtering)
          for more information.
    """

    def __init__(
        self,
        *,
        allow_ip_spoofing: Optional[bool] = None,
        auto_delete: Optional[bool] = None,
        enable_infrastructure_nat: Optional[bool] = None,
        name: Optional[str] = None,
        protocol_state_filtering_mode: Optional[str] = None,
    ) -> None:
        """
        Initialize a VirtualNetworkInterfacePatch object.

        :param bool allow_ip_spoofing: (optional) Indicates whether source IP
               spoofing is allowed on this interface.
               Must be `false` if `target` is a file share mount target.
        :param bool auto_delete: (optional) Indicates whether this virtual network
               interface will be automatically deleted when
               `target` is deleted. Must be `false` if the virtual network interface is
               unbound.
        :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 virtual network interface,
                 allowing the workload to perform any needed NAT operations.
               - `allow_ip_spoofing` must be `false`.
               - Can only be attached to a `target` with a `resource_type` of
                 `bare_metal_server_network_attachment`.
        :param str name: (optional) The name for this virtual network interface.
               The name must not be used by another virtual network interface in the
               region. Names beginning with `ibm-` are reserved for provider-owned
               resources, and are not allowed.
        :param str protocol_state_filtering_mode: (optional) The protocol state
               filtering mode to use for this virtual network interface. If
               `auto`, protocol state packet filtering is enabled or disabled based on the
               virtual network interface's `target` resource type:
               - `bare_metal_server_network_attachment`: disabled
               - `instance_network_attachment`: enabled
               - `share_mount_target`: enabled
               Must not be `disabled` if the virtual network interface's `target` resource
               type is
               `share_mount_target`.
               Protocol state filtering monitors each network connection flowing over this
               virtual network interface, and drops any packets that are invalid based on
               the current connection state and protocol. See [Protocol state filtering
               mode](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#protocol-state-filtering)
               for more information.
        """
        self.allow_ip_spoofing = allow_ip_spoofing
        self.auto_delete = auto_delete
        self.enable_infrastructure_nat = enable_infrastructure_nat
        self.name = name
        self.protocol_state_filtering_mode = protocol_state_filtering_mode

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VirtualNetworkInterfacePatch':
        """Initialize a VirtualNetworkInterfacePatch object from a json dictionary."""
        args = {}
        if (allow_ip_spoofing := _dict.get('allow_ip_spoofing')) is not None:
            args['allow_ip_spoofing'] = allow_ip_spoofing
        if (auto_delete := _dict.get('auto_delete')) is not None:
            args['auto_delete'] = auto_delete
        if (enable_infrastructure_nat := _dict.get('enable_infrastructure_nat')) is not None:
            args['enable_infrastructure_nat'] = enable_infrastructure_nat
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        if (protocol_state_filtering_mode := _dict.get('protocol_state_filtering_mode')) is not None:
            args['protocol_state_filtering_mode'] = protocol_state_filtering_mode
        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, 'allow_ip_spoofing') and self.allow_ip_spoofing is not None:
            _dict['allow_ip_spoofing'] = self.allow_ip_spoofing
        if hasattr(self, 'auto_delete') and self.auto_delete is not None:
            _dict['auto_delete'] = self.auto_delete
        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, 'protocol_state_filtering_mode') and self.protocol_state_filtering_mode is not None:
            _dict['protocol_state_filtering_mode'] = self.protocol_state_filtering_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 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 ProtocolStateFilteringModeEnum(str, Enum):
        """
        The protocol state filtering mode to use for this virtual network interface. If
        `auto`, protocol state packet filtering is enabled or disabled based on the
        virtual network interface's `target` resource type:
        - `bare_metal_server_network_attachment`: disabled
        - `instance_network_attachment`: enabled
        - `share_mount_target`: enabled
        Must not be `disabled` if the virtual network interface's `target` resource type
        is
        `share_mount_target`.
        Protocol state filtering monitors each network connection flowing over this
        virtual network interface, and drops any packets that are invalid based on the
        current connection state and protocol. See [Protocol state filtering
        mode](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#protocol-state-filtering)
        for more information.
        """

        AUTO = 'auto'
        DISABLED = 'disabled'
        ENABLED = 'enabled'



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.

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

    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 := _dict.get('crn')) is not None:
            args['crn'] = crn
        else:
            raise ValueError('Required property \'crn\' not present in VirtualNetworkInterfaceReferenceAttachmentContext JSON')
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in VirtualNetworkInterfaceReferenceAttachmentContext JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in VirtualNetworkInterfaceReferenceAttachmentContext JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in VirtualNetworkInterfaceReferenceAttachmentContext JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = 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 VirtualNetworkInterfaceTarget:
    """
    A virtual network interface target.
    The resources supported by this property may
    [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the future.

    """

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

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


class Volume:
    """
    Volume.

    :param bool active: Indicates whether a running virtual server instance has an
          attachment to this volume.
    :param List[str] adjustable_capacity_states: The attachment states that support
          adjustable capacity for this volume.
    :param List[str] adjustable_iops_states: The attachment states that support
          adjustable IOPS for 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 minimum and maximum limits for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :param VolumeCatalogOffering catalog_offering: (optional) The
          [catalog](https://cloud.ibm.com/docs/account?topic=account-restrict-by-user)
          offering this volume was created from. If a virtual server instance is
          provisioned
          with a `boot_volume_attachment` specifying this volume, the virtual server
          instance
          will use this volume's catalog offering, including its pricing plan.
          If absent, this volume was not created from a catalog offering.
    :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 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 List[VolumeHealthReason] health_reasons: The reasons for the current
          `health_state` (if any).
    :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 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 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 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.
    :param str status: The status of the volume.
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :param List[VolumeStatusReason] status_reasons: The reasons for the current
          status (if any).
    :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.
    """

    def __init__(
        self,
        active: bool,
        adjustable_capacity_states: List[str],
        adjustable_iops_states: List[str],
        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',
        *,
        catalog_offering: Optional['VolumeCatalogOffering'] = None,
        encryption_key: Optional['EncryptionKeyReference'] = None,
        operating_system: Optional['OperatingSystem'] = None,
        source_image: Optional['ImageReference'] = None,
        source_snapshot: Optional['SnapshotReference'] = None,
    ) -> None:
        """
        Initialize a Volume object.

        :param bool active: Indicates whether a running virtual server instance has
               an attachment to this volume.
        :param List[str] adjustable_capacity_states: The attachment states that
               support adjustable capacity for this volume.
        :param List[str] adjustable_iops_states: The attachment states that support
               adjustable IOPS for 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 minimum and maximum limits for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) 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).
        :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 may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :param List[VolumeStatusReason] status_reasons: The reasons for the current
               status (if any).
        :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 VolumeCatalogOffering catalog_offering: (optional) The
               [catalog](https://cloud.ibm.com/docs/account?topic=account-restrict-by-user)
               offering this volume was created from. If a virtual server instance is
               provisioned
               with a `boot_volume_attachment` specifying this volume, the virtual server
               instance
               will use this volume's catalog offering, including its pricing plan.
               If absent, this volume was not created from a catalog offering.
        :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.adjustable_capacity_states = adjustable_capacity_states
        self.adjustable_iops_states = adjustable_iops_states
        self.attachment_state = attachment_state
        self.bandwidth = bandwidth
        self.busy = busy
        self.capacity = capacity
        self.catalog_offering = catalog_offering
        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 := _dict.get('active')) is not None:
            args['active'] = active
        else:
            raise ValueError('Required property \'active\' not present in Volume JSON')
        if (adjustable_capacity_states := _dict.get('adjustable_capacity_states')) is not None:
            args['adjustable_capacity_states'] = adjustable_capacity_states
        else:
            raise ValueError('Required property \'adjustable_capacity_states\' not present in Volume JSON')
        if (adjustable_iops_states := _dict.get('adjustable_iops_states')) is not None:
            args['adjustable_iops_states'] = adjustable_iops_states
        else:
            raise ValueError('Required property \'adjustable_iops_states\' not present in Volume JSON')
        if (attachment_state := _dict.get('attachment_state')) is not None:
            args['attachment_state'] = attachment_state
        else:
            raise ValueError('Required property \'attachment_state\' not present in Volume JSON')
        if (bandwidth := _dict.get('bandwidth')) is not None:
            args['bandwidth'] = bandwidth
        else:
            raise ValueError('Required property \'bandwidth\' not present in Volume JSON')
        if (busy := _dict.get('busy')) is not None:
            args['busy'] = busy
        else:
            raise ValueError('Required property \'busy\' not present in Volume JSON')
        if (capacity := _dict.get('capacity')) is not None:
            args['capacity'] = capacity
        else:
            raise ValueError('Required property \'capacity\' not present in Volume JSON')
        if (catalog_offering := _dict.get('catalog_offering')) is not None:
            args['catalog_offering'] = VolumeCatalogOffering.from_dict(catalog_offering)
        if (created_at := _dict.get('created_at')) is not None:
            args['created_at'] = string_to_datetime(created_at)
        else:
            raise ValueError('Required property \'created_at\' not present in Volume JSON')
        if (crn := _dict.get('crn')) is not None:
            args['crn'] = crn
        else:
            raise ValueError('Required property \'crn\' not present in Volume JSON')
        if (encryption := _dict.get('encryption')) is not None:
            args['encryption'] = encryption
        else:
            raise ValueError('Required property \'encryption\' not present in Volume JSON')
        if (encryption_key := _dict.get('encryption_key')) is not None:
            args['encryption_key'] = EncryptionKeyReference.from_dict(encryption_key)
        if (health_reasons := _dict.get('health_reasons')) is not None:
            args['health_reasons'] = [VolumeHealthReason.from_dict(v) for v in health_reasons]
        else:
            raise ValueError('Required property \'health_reasons\' not present in Volume JSON')
        if (health_state := _dict.get('health_state')) is not None:
            args['health_state'] = health_state
        else:
            raise ValueError('Required property \'health_state\' not present in Volume JSON')
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in Volume JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in Volume JSON')
        if (iops := _dict.get('iops')) is not None:
            args['iops'] = iops
        else:
            raise ValueError('Required property \'iops\' not present in Volume JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in Volume JSON')
        if (operating_system := _dict.get('operating_system')) is not None:
            args['operating_system'] = OperatingSystem.from_dict(operating_system)
        if (profile := _dict.get('profile')) is not None:
            args['profile'] = VolumeProfileReference.from_dict(profile)
        else:
            raise ValueError('Required property \'profile\' not present in Volume JSON')
        if (resource_group := _dict.get('resource_group')) is not None:
            args['resource_group'] = ResourceGroupReference.from_dict(resource_group)
        else:
            raise ValueError('Required property \'resource_group\' not present in Volume JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = resource_type
        else:
            raise ValueError('Required property \'resource_type\' not present in Volume JSON')
        if (source_image := _dict.get('source_image')) is not None:
            args['source_image'] = ImageReference.from_dict(source_image)
        if (source_snapshot := _dict.get('source_snapshot')) is not None:
            args['source_snapshot'] = SnapshotReference.from_dict(source_snapshot)
        if (status := _dict.get('status')) is not None:
            args['status'] = status
        else:
            raise ValueError('Required property \'status\' not present in Volume JSON')
        if (status_reasons := _dict.get('status_reasons')) is not None:
            args['status_reasons'] = [VolumeStatusReason.from_dict(v) for v in status_reasons]
        else:
            raise ValueError('Required property \'status_reasons\' not present in Volume JSON')
        if (user_tags := _dict.get('user_tags')) is not None:
            args['user_tags'] = user_tags
        else:
            raise ValueError('Required property \'user_tags\' not present in Volume JSON')
        if (volume_attachments := _dict.get('volume_attachments')) is not None:
            args['volume_attachments'] = [VolumeAttachmentReferenceVolumeContext.from_dict(v) for v in volume_attachments]
        else:
            raise ValueError('Required property \'volume_attachments\' not present in Volume JSON')
        if (zone := _dict.get('zone')) is not None:
            args['zone'] = ZoneReference.from_dict(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, 'adjustable_capacity_states') and self.adjustable_capacity_states is not None:
            _dict['adjustable_capacity_states'] = self.adjustable_capacity_states
        if hasattr(self, 'adjustable_iops_states') and self.adjustable_iops_states is not None:
            _dict['adjustable_iops_states'] = self.adjustable_iops_states
        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, '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, '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 AdjustableCapacityStatesEnum(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 AdjustableIopsStatesEnum(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 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 may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        AVAILABLE = 'available'
        FAILED = 'failed'
        PENDING = 'pending'
        PENDING_DELETION = 'pending_deletion'
        UNUSABLE = 'unusable'
        UPDATING = 'updating'



class VolumeAttachment:
    """
    VolumeAttachment.

    :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 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 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.
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :param str type: The type of volume attachment.
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :param 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: Optional['VolumeAttachmentDevice'] = None,
        volume: Optional['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.
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :param str type: The type of volume attachment.
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :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 := _dict.get('bandwidth')) is not None:
            args['bandwidth'] = bandwidth
        else:
            raise ValueError('Required property \'bandwidth\' not present in VolumeAttachment JSON')
        if (created_at := _dict.get('created_at')) is not None:
            args['created_at'] = string_to_datetime(created_at)
        else:
            raise ValueError('Required property \'created_at\' not present in VolumeAttachment JSON')
        if (delete_volume_on_instance_delete := _dict.get('delete_volume_on_instance_delete')) is not None:
            args['delete_volume_on_instance_delete'] = delete_volume_on_instance_delete
        else:
            raise ValueError('Required property \'delete_volume_on_instance_delete\' not present in VolumeAttachment JSON')
        if (device := _dict.get('device')) is not None:
            args['device'] = VolumeAttachmentDevice.from_dict(device)
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in VolumeAttachment JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in VolumeAttachment JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in VolumeAttachment JSON')
        if (status := _dict.get('status')) is not None:
            args['status'] = status
        else:
            raise ValueError('Required property \'status\' not present in VolumeAttachment JSON')
        if (type := _dict.get('type')) is not None:
            args['type'] = type
        else:
            raise ValueError('Required property \'type\' not present in VolumeAttachment JSON')
        if (volume := _dict.get('volume')) is not None:
            args['volume'] = VolumeReferenceVolumeAttachmentContext.from_dict(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.
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        ATTACHED = 'attached'
        ATTACHING = 'attaching'
        DELETING = 'deleting'
        DETACHING = 'detaching'


    class TypeEnum(str, Enum):
        """
        The type of volume attachment.
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        BOOT = 'boot'
        DATA = 'data'



class VolumeAttachmentCollection:
    """
    VolumeAttachmentCollection.

    :param List[VolumeAttachment] volume_attachments: The volume attachments for the
          instance.
    """

    def __init__(
        self,
        volume_attachments: List['VolumeAttachment'],
    ) -> None:
        """
        Initialize a VolumeAttachmentCollection object.

        :param List[VolumeAttachment] volume_attachments: The volume attachments
               for the instance.
        """
        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 := _dict.get('volume_attachments')) is not None:
            args['volume_attachments'] = [VolumeAttachment.from_dict(v) for v in 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.

    :param str id: A unique identifier for the device which is exposed to the
          instance operating system.
    """

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

        :param str id: 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 := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in VolumeAttachmentDevice JSON')
        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.

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

    def __init__(
        self,
        *,
        delete_volume_on_instance_delete: Optional[bool] = None,
        name: Optional[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 := _dict.get('delete_volume_on_instance_delete')) is not None:
            args['delete_volume_on_instance_delete'] = delete_volume_on_instance_delete
        if (name := _dict.get('name')) is not None:
            args['name'] = 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.

    :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 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: Optional[bool] = None,
        name: Optional[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 := _dict.get('delete_volume_on_instance_delete')) is not None:
            args['delete_volume_on_instance_delete'] = delete_volume_on_instance_delete
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        if (volume := _dict.get('volume')) is not None:
            args['volume'] = 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.

    :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 VolumePrototypeInstanceByImageContext volume: A prototype object for a
          new volume.
    """

    def __init__(
        self,
        volume: 'VolumePrototypeInstanceByImageContext',
        *,
        delete_volume_on_instance_delete: Optional[bool] = None,
        name: Optional[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 := _dict.get('delete_volume_on_instance_delete')) is not None:
            args['delete_volume_on_instance_delete'] = delete_volume_on_instance_delete
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        if (volume := _dict.get('volume')) is not None:
            args['volume'] = VolumePrototypeInstanceByImageContext.from_dict(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.

    :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 VolumePrototypeInstanceBySourceSnapshotContext volume: A prototype object
          for a new volume from a snapshot.
    """

    def __init__(
        self,
        volume: 'VolumePrototypeInstanceBySourceSnapshotContext',
        *,
        delete_volume_on_instance_delete: Optional[bool] = None,
        name: Optional[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 := _dict.get('delete_volume_on_instance_delete')) is not None:
            args['delete_volume_on_instance_delete'] = delete_volume_on_instance_delete
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        if (volume := _dict.get('volume')) is not None:
            args['volume'] = VolumePrototypeInstanceBySourceSnapshotContext.from_dict(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.

    :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 VolumeIdentity volume: An existing volume to attach.
    """

    def __init__(
        self,
        volume: 'VolumeIdentity',
        *,
        delete_volume_on_instance_delete: Optional[bool] = None,
        name: Optional[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 := _dict.get('delete_volume_on_instance_delete')) is not None:
            args['delete_volume_on_instance_delete'] = delete_volume_on_instance_delete
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        if (volume := _dict.get('volume')) is not None:
            args['volume'] = 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.

    :param Deleted 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 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 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: Optional['Deleted'] = None,
        device: Optional['VolumeAttachmentDevice'] = None,
        volume: Optional['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 Deleted 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 := _dict.get('deleted')) is not None:
            args['deleted'] = Deleted.from_dict(deleted)
        if (device := _dict.get('device')) is not None:
            args['device'] = VolumeAttachmentDevice.from_dict(device)
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in VolumeAttachmentReferenceInstanceContext JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in VolumeAttachmentReferenceInstanceContext JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in VolumeAttachmentReferenceInstanceContext JSON')
        if (volume := _dict.get('volume')) is not None:
            args['volume'] = VolumeReferenceVolumeAttachmentContext.from_dict(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 VolumeAttachmentReferenceVolumeContext:
    """
    VolumeAttachmentReferenceVolumeContext.

    :param bool delete_volume_on_instance_delete: Indicates whether deleting the
          instance will also delete the attached volume.
    :param Deleted 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 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.
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    """

    def __init__(
        self,
        delete_volume_on_instance_delete: bool,
        href: str,
        id: str,
        instance: 'InstanceReference',
        name: str,
        type: str,
        *,
        deleted: Optional['Deleted'] = None,
        device: Optional['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.
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :param Deleted 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 := _dict.get('delete_volume_on_instance_delete')) is not None:
            args['delete_volume_on_instance_delete'] = delete_volume_on_instance_delete
        else:
            raise ValueError('Required property \'delete_volume_on_instance_delete\' not present in VolumeAttachmentReferenceVolumeContext JSON')
        if (deleted := _dict.get('deleted')) is not None:
            args['deleted'] = Deleted.from_dict(deleted)
        if (device := _dict.get('device')) is not None:
            args['device'] = VolumeAttachmentDevice.from_dict(device)
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in VolumeAttachmentReferenceVolumeContext JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in VolumeAttachmentReferenceVolumeContext JSON')
        if (instance := _dict.get('instance')) is not None:
            args['instance'] = InstanceReference.from_dict(instance)
        else:
            raise ValueError('Required property \'instance\' not present in VolumeAttachmentReferenceVolumeContext JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in VolumeAttachmentReferenceVolumeContext JSON')
        if (type := _dict.get('type')) is not None:
            args['type'] = 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.
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        BOOT = 'boot'
        DATA = 'data'



class VolumeCatalogOffering:
    """
    VolumeCatalogOffering.

    :param CatalogOfferingVersionPlanReference plan: (optional) The billing plan
          associated with the catalog offering version.
          If absent, no billing plan is associated with the catalog offering version
          (free).
    :param CatalogOfferingVersionReference version: The
          [catalog](https://cloud.ibm.com/docs/account?topic=account-restrict-by-user)
          offering version this volume was created from.
    """

    def __init__(
        self,
        version: 'CatalogOfferingVersionReference',
        *,
        plan: Optional['CatalogOfferingVersionPlanReference'] = None,
    ) -> None:
        """
        Initialize a VolumeCatalogOffering object.

        :param CatalogOfferingVersionReference version: The
               [catalog](https://cloud.ibm.com/docs/account?topic=account-restrict-by-user)
               offering version this volume was created from.
        :param CatalogOfferingVersionPlanReference plan: (optional) The billing
               plan associated with the catalog offering version.
               If absent, no billing plan is associated with the catalog offering version
               (free).
        """
        self.plan = plan
        self.version = version

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

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

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

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

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


class VolumeCollection:
    """
    VolumeCollection.

    :param PageLink 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 PageLink next: (optional) A link to the next page of resources. This
          property is present for all pages
          except the last page.
    :param int total_count: The total number of resources across all pages.
    :param List[Volume] volumes: A page of volumes.
    """

    def __init__(
        self,
        first: 'PageLink',
        limit: int,
        total_count: int,
        volumes: List['Volume'],
        *,
        next: Optional['PageLink'] = None,
    ) -> None:
        """
        Initialize a VolumeCollection object.

        :param PageLink 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: A page of volumes.
        :param PageLink 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 := _dict.get('first')) is not None:
            args['first'] = PageLink.from_dict(first)
        else:
            raise ValueError('Required property \'first\' not present in VolumeCollection JSON')
        if (limit := _dict.get('limit')) is not None:
            args['limit'] = limit
        else:
            raise ValueError('Required property \'limit\' not present in VolumeCollection JSON')
        if (next := _dict.get('next')) is not None:
            args['next'] = PageLink.from_dict(next)
        if (total_count := _dict.get('total_count')) is not None:
            args['total_count'] = total_count
        else:
            raise ValueError('Required property \'total_count\' not present in VolumeCollection JSON')
        if (volumes := _dict.get('volumes')) is not None:
            args['volumes'] = [Volume.from_dict(v) for v in 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 VolumeHealthReason:
    """
    VolumeHealthReason.

    :param str code: A reason code 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.
    """

    def __init__(
        self,
        code: str,
        message: str,
        *,
        more_info: Optional[str] = None,
    ) -> None:
        """
        Initialize a VolumeHealthReason object.

        :param str code: A reason code 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 := _dict.get('code')) is not None:
            args['code'] = code
        else:
            raise ValueError('Required property \'code\' not present in VolumeHealthReason JSON')
        if (message := _dict.get('message')) is not None:
            args['message'] = message
        else:
            raise ValueError('Required property \'message\' not present in VolumeHealthReason JSON')
        if (more_info := _dict.get('more_info')) is not None:
            args['more_info'] = 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 reason code for this health state.
        """

        INITIALIZING_FROM_SNAPSHOT = 'initializing_from_snapshot'
        THROTTLED_BY_INSUFFICIENT_INSTANCE_BANDWIDTH = 'throttled_by_insufficient_instance_bandwidth'



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.

    :param int capacity: (optional) The capacity to use for the volume (in
          gigabytes). For the capacity to be changed the volume's current
          `attachment_state` must be one of the values included in
          `adjustable_capacity_states`. If `adjustable_capacity_states` is empty, then the
          volume capacity cannot be changed.  Additionally:
          - The specified value must not be less than the current capacity.
          - If the volume is attached as a boot volume, the specified value must not
          exceed
            the `boot_capacity.max` of the volume profile.
          - If the volume is attached as a data volume, the specified value must not
          exceed
            the `capacity.max` of the volume profile.
    :param int iops: (optional) The maximum I/O operations per second (IOPS) to use
          for this volume.  For the IOPS to be changed the volume's current
          `attachment_state` must be one of the values included in
          `adjustable_iops_states`. If `adjustable_iops_states` is empty, then the IOPS
          cannot be changed.
    :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.  Additionally:
          - If the volume is a boot volume then the value specified for `capacity`
          property
          must not be less than the `boot_capacity.min` and must not exceed the
          `boot_capacity.max` of the specified volume profile.
          - If the volume is a data volume then the value specified for `capacity`
          property
          must not be less than the `capacity.min` and must not exceed the `capacity.max`
          of the specified volume profile.
    :param 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: Optional[int] = None,
        iops: Optional[int] = None,
        name: Optional[str] = None,
        profile: Optional['VolumeProfileIdentity'] = None,
        user_tags: Optional[List[str]] = None,
    ) -> None:
        """
        Initialize a VolumePatch object.

        :param int capacity: (optional) The capacity to use for the volume (in
               gigabytes). For the capacity to be changed the volume's current
               `attachment_state` must be one of the values included in
               `adjustable_capacity_states`. If `adjustable_capacity_states` is empty,
               then the volume capacity cannot be changed.  Additionally:
               - The specified value must not be less than the current capacity.
               - If the volume is attached as a boot volume, the specified value must not
               exceed
                 the `boot_capacity.max` of the volume profile.
               - If the volume is attached as a data volume, the specified value must not
               exceed
                 the `capacity.max` of the volume profile.
        :param int iops: (optional) The maximum I/O operations per second (IOPS) to
               use for this volume.  For the IOPS to be changed the volume's current
               `attachment_state` must be one of the values included in
               `adjustable_iops_states`. If `adjustable_iops_states` is empty, then the
               IOPS cannot be changed.
        :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.  Additionally:
               - If the volume is a boot volume then the value specified for `capacity`
               property
               must not be less than the `boot_capacity.min` and must not exceed the
               `boot_capacity.max` of the specified volume profile.
               - If the volume is a data volume then the value specified for `capacity`
               property
               must not be less than the `capacity.min` and must not exceed the
               `capacity.max`
               of the specified volume 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 := _dict.get('capacity')) is not None:
            args['capacity'] = capacity
        if (iops := _dict.get('iops')) is not None:
            args['iops'] = iops
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        if (profile := _dict.get('profile')) is not None:
            args['profile'] = profile
        if (user_tags := _dict.get('user_tags')) is not None:
            args['user_tags'] = 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.

    :param VolumeProfileAdjustableCapacityStates adjustable_capacity_states:
    :param VolumeProfileAdjustableIOPSStates adjustable_iops_states:
    :param VolumeProfileBootCapacity boot_capacity:
    :param VolumeProfileCapacity capacity:
    :param str family: The product family this volume profile belongs to.
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :param str href: The URL for this volume profile.
    :param VolumeProfileIOPS iops:
    :param str name: The globally unique name for this volume profile.
    """

    def __init__(
        self,
        adjustable_capacity_states: 'VolumeProfileAdjustableCapacityStates',
        adjustable_iops_states: 'VolumeProfileAdjustableIOPSStates',
        boot_capacity: 'VolumeProfileBootCapacity',
        capacity: 'VolumeProfileCapacity',
        family: str,
        href: str,
        iops: 'VolumeProfileIOPS',
        name: str,
    ) -> None:
        """
        Initialize a VolumeProfile object.

        :param VolumeProfileAdjustableCapacityStates adjustable_capacity_states:
        :param VolumeProfileAdjustableIOPSStates adjustable_iops_states:
        :param VolumeProfileBootCapacity boot_capacity:
        :param VolumeProfileCapacity capacity:
        :param str family: The product family this volume profile belongs to.
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :param str href: The URL for this volume profile.
        :param VolumeProfileIOPS iops:
        :param str name: The globally unique name for this volume profile.
        """
        self.adjustable_capacity_states = adjustable_capacity_states
        self.adjustable_iops_states = adjustable_iops_states
        self.boot_capacity = boot_capacity
        self.capacity = capacity
        self.family = family
        self.href = href
        self.iops = iops
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VolumeProfile':
        """Initialize a VolumeProfile object from a json dictionary."""
        args = {}
        if (adjustable_capacity_states := _dict.get('adjustable_capacity_states')) is not None:
            args['adjustable_capacity_states'] = VolumeProfileAdjustableCapacityStates.from_dict(adjustable_capacity_states)
        else:
            raise ValueError('Required property \'adjustable_capacity_states\' not present in VolumeProfile JSON')
        if (adjustable_iops_states := _dict.get('adjustable_iops_states')) is not None:
            args['adjustable_iops_states'] = VolumeProfileAdjustableIOPSStates.from_dict(adjustable_iops_states)
        else:
            raise ValueError('Required property \'adjustable_iops_states\' not present in VolumeProfile JSON')
        if (boot_capacity := _dict.get('boot_capacity')) is not None:
            args['boot_capacity'] = boot_capacity
        else:
            raise ValueError('Required property \'boot_capacity\' not present in VolumeProfile JSON')
        if (capacity := _dict.get('capacity')) is not None:
            args['capacity'] = capacity
        else:
            raise ValueError('Required property \'capacity\' not present in VolumeProfile JSON')
        if (family := _dict.get('family')) is not None:
            args['family'] = family
        else:
            raise ValueError('Required property \'family\' not present in VolumeProfile JSON')
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in VolumeProfile JSON')
        if (iops := _dict.get('iops')) is not None:
            args['iops'] = iops
        else:
            raise ValueError('Required property \'iops\' not present in VolumeProfile JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = 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, 'adjustable_capacity_states') and self.adjustable_capacity_states is not None:
            if isinstance(self.adjustable_capacity_states, dict):
                _dict['adjustable_capacity_states'] = self.adjustable_capacity_states
            else:
                _dict['adjustable_capacity_states'] = self.adjustable_capacity_states.to_dict()
        if hasattr(self, 'adjustable_iops_states') and self.adjustable_iops_states is not None:
            if isinstance(self.adjustable_iops_states, dict):
                _dict['adjustable_iops_states'] = self.adjustable_iops_states
            else:
                _dict['adjustable_iops_states'] = self.adjustable_iops_states.to_dict()
        if hasattr(self, 'boot_capacity') and self.boot_capacity is not None:
            if isinstance(self.boot_capacity, dict):
                _dict['boot_capacity'] = self.boot_capacity
            else:
                _dict['boot_capacity'] = self.boot_capacity.to_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
        return _dict

    def _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 may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        CUSTOM = 'custom'
        DEFINED_PERFORMANCE = 'defined_performance'
        TIERED = 'tiered'



class VolumeProfileAdjustableCapacityStates:
    """
    VolumeProfileAdjustableCapacityStates.

    :param str type: The type for this profile field.
    :param List[str] values: The attachment states that support adjustable capacity
          for a volume with this profile.
    """

    def __init__(
        self,
        type: str,
        values: List[str],
    ) -> None:
        """
        Initialize a VolumeProfileAdjustableCapacityStates object.

        :param str type: The type for this profile field.
        :param List[str] values: The attachment states that support adjustable
               capacity for a volume with this profile.
        """
        self.type = type
        self.values = values

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

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

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

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

    :param str type: The type for this profile field.
    :param List[str] values: The attachment states that support adjustable IOPS for
          a volume with this profile.
    """

    def __init__(
        self,
        type: str,
        values: List[str],
    ) -> None:
        """
        Initialize a VolumeProfileAdjustableIOPSStates object.

        :param str type: The type for this profile field.
        :param List[str] values: The attachment states that support adjustable IOPS
               for a volume with this profile.
        """
        self.type = type
        self.values = values

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

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

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

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

    """

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

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


class VolumeProfileCapacity:
    """
    VolumeProfileCapacity.

    """

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

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


class VolumeProfileCollection:
    """
    VolumeProfileCollection.

    :param PageLink 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 PageLink next: (optional) A link to the next page of resources. This
          property is present for all pages
          except the last page.
    :param List[VolumeProfile] profiles: A page of volume profiles.
    :param int total_count: The total number of resources across all pages.
    """

    def __init__(
        self,
        first: 'PageLink',
        limit: int,
        profiles: List['VolumeProfile'],
        total_count: int,
        *,
        next: Optional['PageLink'] = None,
    ) -> None:
        """
        Initialize a VolumeProfileCollection object.

        :param PageLink 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: A page of volume profiles.
        :param int total_count: The total number of resources across all pages.
        :param PageLink 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 := _dict.get('first')) is not None:
            args['first'] = PageLink.from_dict(first)
        else:
            raise ValueError('Required property \'first\' not present in VolumeProfileCollection JSON')
        if (limit := _dict.get('limit')) is not None:
            args['limit'] = limit
        else:
            raise ValueError('Required property \'limit\' not present in VolumeProfileCollection JSON')
        if (next := _dict.get('next')) is not None:
            args['next'] = PageLink.from_dict(next)
        if (profiles := _dict.get('profiles')) is not None:
            args['profiles'] = [VolumeProfile.from_dict(v) for v in profiles]
        else:
            raise ValueError('Required property \'profiles\' not present in VolumeProfileCollection JSON')
        if (total_count := _dict.get('total_count')) is not None:
            args['total_count'] = 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 VolumeProfileIOPS:
    """
    VolumeProfileIOPS.

    """

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

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


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.

    :param str href: The URL for this volume profile.
    :param 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 := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in VolumeProfileReference JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = 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.

    :param int iops: (optional) The maximum I/O operations per second (IOPS) to use
          for this volume. If specified, the `family` of the volume profile must be
          `custom` or `defined_performance`.
    :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 VolumeProfileIdentity profile: The
          [profile](https://cloud.ibm.com/docs/vpc?topic=vpc-block-storage-profiles) to
          use for this volume.
    :param ResourceGroupIdentity resource_group: (optional) The resource group to
          use. If unspecified, the account's [default resource
          group](https://cloud.ibm.com/apidocs/resource-manager#introduction) 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 ZoneIdentity zone: The zone this volume will reside in.
    """

    def __init__(
        self,
        profile: 'VolumeProfileIdentity',
        zone: 'ZoneIdentity',
        *,
        iops: Optional[int] = None,
        name: Optional[str] = None,
        resource_group: Optional['ResourceGroupIdentity'] = None,
        user_tags: Optional[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. If specified, the `family` of the volume profile must
               be `custom` or `defined_performance`.
        :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.

    :param int capacity: (optional) The capacity to use for the volume (in
          gigabytes). The specified value must be at least the image's
          `minimum_provisioned_size`, at most 250 gigabytes, and within the
          `boot_capacity` range of the volume's profile.
          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. If specified, the `family` of the volume profile must be
          `custom` or `defined_performance`.
    :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 VolumeProfileIdentity profile: The
          [profile](https://cloud.ibm.com/docs/vpc?topic=vpc-block-storage-profiles) to
          use for this volume.
    :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.
    """

    def __init__(
        self,
        profile: 'VolumeProfileIdentity',
        *,
        capacity: Optional[int] = None,
        encryption_key: Optional['EncryptionKeyIdentity'] = None,
        iops: Optional[int] = None,
        name: Optional[str] = None,
        resource_group: Optional['ResourceGroupIdentity'] = None,
        user_tags: Optional[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). The specified value must be at least the image's
               `minimum_provisioned_size`, at most 250 gigabytes, and within the
               `boot_capacity` range of the volume's profile.
               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. If specified, the `family` of the volume profile must
               be `custom` or `defined_performance`.
        :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 := _dict.get('capacity')) is not None:
            args['capacity'] = capacity
        if (encryption_key := _dict.get('encryption_key')) is not None:
            args['encryption_key'] = encryption_key
        if (iops := _dict.get('iops')) is not None:
            args['iops'] = iops
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        if (profile := _dict.get('profile')) is not None:
            args['profile'] = profile
        else:
            raise ValueError('Required property \'profile\' not present in VolumePrototypeInstanceByImageContext JSON')
        if (resource_group := _dict.get('resource_group')) is not None:
            args['resource_group'] = resource_group
        if (user_tags := _dict.get('user_tags')) is not None:
            args['user_tags'] = 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.

    :param int capacity: (optional) The capacity to use for the volume (in
          gigabytes). The specified value must be at least the snapshot's
          `minimum_capacity`, at most 250 gigabytes, and within the `boot_capacity` range
          of the volume's profile.
    :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. If specified, the `family` of the volume profile must be
          `custom` or `defined_performance`.
    :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 VolumeProfileIdentity profile: The
          [profile](https://cloud.ibm.com/docs/vpc?topic=vpc-block-storage-profiles) to
          use for this volume.
    :param ResourceGroupIdentity resource_group: (optional) The resource group to
          use for this volume. If unspecified, the instance's resource
          group will be used.
    :param SnapshotIdentity source_snapshot: The snapshot to use as a source for the
          volume's data.
          The specified snapshot may be in a different account, subject to IAM policies.
    :param 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: Optional[int] = None,
        encryption_key: Optional['EncryptionKeyIdentity'] = None,
        iops: Optional[int] = None,
        name: Optional[str] = None,
        resource_group: Optional['ResourceGroupIdentity'] = None,
        user_tags: Optional[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 to use as a source
               for the volume's data.
               The specified snapshot may be in a different account, subject to IAM
               policies.
        :param int capacity: (optional) The capacity to use for the volume (in
               gigabytes). The specified value must be at least the snapshot's
               `minimum_capacity`, at most 250 gigabytes, and within the `boot_capacity`
               range of the volume's profile.
        :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. If specified, the `family` of the volume profile must
               be `custom` or `defined_performance`.
        :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 := _dict.get('capacity')) is not None:
            args['capacity'] = capacity
        if (encryption_key := _dict.get('encryption_key')) is not None:
            args['encryption_key'] = encryption_key
        if (iops := _dict.get('iops')) is not None:
            args['iops'] = iops
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        if (profile := _dict.get('profile')) is not None:
            args['profile'] = profile
        else:
            raise ValueError('Required property \'profile\' not present in VolumePrototypeInstanceBySourceSnapshotContext JSON')
        if (resource_group := _dict.get('resource_group')) is not None:
            args['resource_group'] = resource_group
        if (source_snapshot := _dict.get('source_snapshot')) is not None:
            args['source_snapshot'] = source_snapshot
        else:
            raise ValueError('Required property \'source_snapshot\' not present in VolumePrototypeInstanceBySourceSnapshotContext JSON')
        if (user_tags := _dict.get('user_tags')) is not None:
            args['user_tags'] = 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.

    :param str crn: The CRN for this volume.
    :param Deleted deleted: (optional) If present, this property indicates the
          referenced resource has been deleted, and provides
          some supplementary information.
    :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 VolumeRemote remote: (optional) If present, this property indicates that
          the resource associated with this reference
          is remote and therefore may not be directly retrievable.
    :param str resource_type: The resource type.
    """

    def __init__(
        self,
        crn: str,
        href: str,
        id: str,
        name: str,
        resource_type: str,
        *,
        deleted: Optional['Deleted'] = None,
        remote: Optional['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 Deleted 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 := _dict.get('crn')) is not None:
            args['crn'] = crn
        else:
            raise ValueError('Required property \'crn\' not present in VolumeReference JSON')
        if (deleted := _dict.get('deleted')) is not None:
            args['deleted'] = Deleted.from_dict(deleted)
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in VolumeReference JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in VolumeReference JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in VolumeReference JSON')
        if (remote := _dict.get('remote')) is not None:
            args['remote'] = VolumeRemote.from_dict(remote)
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = 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 VolumeReferenceVolumeAttachmentContext:
    """
    VolumeReferenceVolumeAttachmentContext.

    :param str crn: The CRN for this volume.
    :param Deleted deleted: (optional) If present, this property indicates the
          referenced resource has been deleted, and provides
          some supplementary information.
    :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.
    """

    def __init__(
        self,
        crn: str,
        href: str,
        id: str,
        name: str,
        resource_type: str,
        *,
        deleted: Optional['Deleted'] = 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 Deleted 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 := _dict.get('crn')) is not None:
            args['crn'] = crn
        else:
            raise ValueError('Required property \'crn\' not present in VolumeReferenceVolumeAttachmentContext JSON')
        if (deleted := _dict.get('deleted')) is not None:
            args['deleted'] = Deleted.from_dict(deleted)
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in VolumeReferenceVolumeAttachmentContext JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in VolumeReferenceVolumeAttachmentContext JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in VolumeReferenceVolumeAttachmentContext JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = 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 VolumeRemote:
    """
    If present, this property indicates that the resource associated with this reference
    is remote and therefore may not be directly retrievable.

    :param 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: Optional['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 := _dict.get('region')) is not None:
            args['region'] = RegionReference.from_dict(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.

    :param str code: A snake case string succinctly identifying the status reason.
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :param str message: An explanation of the status reason.
    :param str more_info: (optional) Link to documentation about this status reason.
    """

    def __init__(
        self,
        code: str,
        message: str,
        *,
        more_info: Optional[str] = None,
    ) -> None:
        """
        Initialize a VolumeStatusReason object.

        :param str code: A snake case string succinctly identifying the status
               reason.
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :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 := _dict.get('code')) is not None:
            args['code'] = code
        else:
            raise ValueError('Required property \'code\' not present in VolumeStatusReason JSON')
        if (message := _dict.get('message')) is not None:
            args['message'] = message
        else:
            raise ValueError('Required property \'message\' not present in VolumeStatusReason JSON')
        if (more_info := _dict.get('more_info')) is not None:
            args['more_info'] = 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.
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        ENCRYPTION_KEY_DELETED = 'encryption_key_deleted'



class Zone:
    """
    Zone.

    :param str data_center: (optional) The physical data center assigned to this
          logical zone.
          If absent, no physical data center has been assigned.
    :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 status of the zone.
          - `available`: The zone is available to create and manage resources.
          - `impaired`: The zone's availability and performance to create and manage
          resources
            may be impaired.
          - `unavailable`: The zone is unavailable to create and manage resources.
          - `unassigned`: The zone has not been assigned to a physical zone.
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :param str universal_name: (optional) The [universal
          name](https://cloud.ibm.com/docs/overview?topic=overview-locations#zone-mapping)
          for this zone. Will be absent if this zone has a `status` of `unassigned`.
    """

    def __init__(
        self,
        href: str,
        name: str,
        region: 'RegionReference',
        status: str,
        *,
        data_center: Optional[str] = None,
        universal_name: Optional[str] = None,
    ) -> 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 status of the zone.
               - `available`: The zone is available to create and manage resources.
               - `impaired`: The zone's availability and performance to create and manage
               resources
                 may be impaired.
               - `unavailable`: The zone is unavailable to create and manage resources.
               - `unassigned`: The zone has not been assigned to a physical zone.
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :param str data_center: (optional) The physical data center assigned to
               this logical zone.
               If absent, no physical data center has been assigned.
        :param str universal_name: (optional) The [universal
               name](https://cloud.ibm.com/docs/overview?topic=overview-locations#zone-mapping)
               for this zone. Will be absent if this zone has a `status` of `unassigned`.
        """
        self.data_center = data_center
        self.href = href
        self.name = name
        self.region = region
        self.status = status
        self.universal_name = universal_name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'Zone':
        """Initialize a Zone object from a json dictionary."""
        args = {}
        if (data_center := _dict.get('data_center')) is not None:
            args['data_center'] = data_center
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in Zone JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in Zone JSON')
        if (region := _dict.get('region')) is not None:
            args['region'] = RegionReference.from_dict(region)
        else:
            raise ValueError('Required property \'region\' not present in Zone JSON')
        if (status := _dict.get('status')) is not None:
            args['status'] = status
        else:
            raise ValueError('Required property \'status\' not present in Zone JSON')
        if (universal_name := _dict.get('universal_name')) is not None:
            args['universal_name'] = universal_name
        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, 'data_center') and self.data_center is not None:
            _dict['data_center'] = self.data_center
        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
        if hasattr(self, 'universal_name') and self.universal_name is not None:
            _dict['universal_name'] = self.universal_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 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 status of the zone.
        - `available`: The zone is available to create and manage resources.
        - `impaired`: The zone's availability and performance to create and manage
        resources
          may be impaired.
        - `unavailable`: The zone is unavailable to create and manage resources.
        - `unassigned`: The zone has not been assigned to a physical zone.
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        AVAILABLE = 'available'
        IMPAIRED = 'impaired'
        UNASSIGNED = 'unassigned'
        UNAVAILABLE = 'unavailable'



class ZoneCollection:
    """
    ZoneCollection.

    :param List[Zone] zones: The zones for the region.
    """

    def __init__(
        self,
        zones: List['Zone'],
    ) -> None:
        """
        Initialize a ZoneCollection object.

        :param List[Zone] zones: The zones for the region.
        """
        self.zones = zones

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ZoneCollection':
        """Initialize a ZoneCollection object from a json dictionary."""
        args = {}
        if (zones := _dict.get('zones')) is not None:
            args['zones'] = [Zone.from_dict(v) for v in 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.

    :param str href: The URL for this zone.
    :param 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 := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in ZoneReference JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = 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 AccountIdentityById(AccountIdentity):
    """
    AccountIdentityById.

    :param str id: The unique identifier for this account.
    """

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

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

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

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

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

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


class BackupPolicyJobSourceInstanceReference(BackupPolicyJobSource):
    """
    BackupPolicyJobSourceInstanceReference.

    :param str crn: The CRN for this virtual server instance.
    :param Deleted deleted: (optional) If present, this property indicates the
          referenced resource has been deleted, and provides
          some supplementary information.
    :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.
    """

    def __init__(
        self,
        crn: str,
        href: str,
        id: str,
        name: str,
        *,
        deleted: Optional['Deleted'] = None,
    ) -> None:
        """
        Initialize a BackupPolicyJobSourceInstanceReference 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 Deleted 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) -> 'BackupPolicyJobSourceInstanceReference':
        """Initialize a BackupPolicyJobSourceInstanceReference object from a json dictionary."""
        args = {}
        if (crn := _dict.get('crn')) is not None:
            args['crn'] = crn
        else:
            raise ValueError('Required property \'crn\' not present in BackupPolicyJobSourceInstanceReference JSON')
        if (deleted := _dict.get('deleted')) is not None:
            args['deleted'] = Deleted.from_dict(deleted)
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in BackupPolicyJobSourceInstanceReference JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in BackupPolicyJobSourceInstanceReference JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in BackupPolicyJobSourceInstanceReference JSON')
        return cls(**args)

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

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

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


class BackupPolicyJobSourceVolumeReference(BackupPolicyJobSource):
    """
    BackupPolicyJobSourceVolumeReference.

    :param str crn: The CRN for this volume.
    :param Deleted deleted: (optional) If present, this property indicates the
          referenced resource has been deleted, and provides
          some supplementary information.
    :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 VolumeRemote remote: (optional) If present, this property indicates that
          the resource associated with this reference
          is remote and therefore may not be directly retrievable.
    :param str resource_type: The resource type.
    """

    def __init__(
        self,
        crn: str,
        href: str,
        id: str,
        name: str,
        resource_type: str,
        *,
        deleted: Optional['Deleted'] = None,
        remote: Optional['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 Deleted 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 := _dict.get('crn')) is not None:
            args['crn'] = crn
        else:
            raise ValueError('Required property \'crn\' not present in BackupPolicyJobSourceVolumeReference JSON')
        if (deleted := _dict.get('deleted')) is not None:
            args['deleted'] = Deleted.from_dict(deleted)
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in BackupPolicyJobSourceVolumeReference JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in BackupPolicyJobSourceVolumeReference JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in BackupPolicyJobSourceVolumeReference JSON')
        if (remote := _dict.get('remote')) is not None:
            args['remote'] = VolumeRemote.from_dict(remote)
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = 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 BackupPolicyMatchResourceTypeInstance(BackupPolicy):
    """
    BackupPolicyMatchResourceTypeInstance.

    :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).
    :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 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.
    :param str lifecycle_state: The lifecycle state of the backup policy.
    :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:
    :param List[str] included_content: The included content for backups created
          using this policy:
          - `boot_volume`: Include the instance's boot volume.
          - `data_volumes`: Include the instance's data volumes.
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :param str match_resource_type: The resource type 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 may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    """

    def __init__(
        self,
        created_at: datetime,
        crn: str,
        health_reasons: List['BackupPolicyHealthReason'],
        health_state: str,
        href: str,
        id: str,
        lifecycle_state: str,
        match_user_tags: List[str],
        name: str,
        plans: List['BackupPolicyPlanReference'],
        resource_group: 'ResourceGroupReference',
        resource_type: str,
        scope: 'BackupPolicyScope',
        included_content: List[str],
        match_resource_type: str,
        *,
        last_job_completed_at: Optional[datetime] = None,
    ) -> None:
        """
        Initialize a BackupPolicyMatchResourceTypeInstance 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).
        :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_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:
        :param List[str] included_content: The included content for backups created
               using this policy:
               - `boot_volume`: Include the instance's boot volume.
               - `data_volumes`: Include the instance's data volumes.
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :param str match_resource_type: The resource type 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 may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :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.
        """
        # pylint: disable=super-init-not-called
        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_user_tags = match_user_tags
        self.name = name
        self.plans = plans
        self.resource_group = resource_group
        self.resource_type = resource_type
        self.scope = scope
        self.included_content = included_content
        self.match_resource_type = match_resource_type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'BackupPolicyMatchResourceTypeInstance':
        """Initialize a BackupPolicyMatchResourceTypeInstance object from a json dictionary."""
        args = {}
        if (created_at := _dict.get('created_at')) is not None:
            args['created_at'] = string_to_datetime(created_at)
        else:
            raise ValueError('Required property \'created_at\' not present in BackupPolicyMatchResourceTypeInstance JSON')
        if (crn := _dict.get('crn')) is not None:
            args['crn'] = crn
        else:
            raise ValueError('Required property \'crn\' not present in BackupPolicyMatchResourceTypeInstance JSON')
        if (health_reasons := _dict.get('health_reasons')) is not None:
            args['health_reasons'] = [BackupPolicyHealthReason.from_dict(v) for v in health_reasons]
        else:
            raise ValueError('Required property \'health_reasons\' not present in BackupPolicyMatchResourceTypeInstance JSON')
        if (health_state := _dict.get('health_state')) is not None:
            args['health_state'] = health_state
        else:
            raise ValueError('Required property \'health_state\' not present in BackupPolicyMatchResourceTypeInstance JSON')
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in BackupPolicyMatchResourceTypeInstance JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in BackupPolicyMatchResourceTypeInstance JSON')
        if (last_job_completed_at := _dict.get('last_job_completed_at')) is not None:
            args['last_job_completed_at'] = string_to_datetime(last_job_completed_at)
        if (lifecycle_state := _dict.get('lifecycle_state')) is not None:
            args['lifecycle_state'] = lifecycle_state
        else:
            raise ValueError('Required property \'lifecycle_state\' not present in BackupPolicyMatchResourceTypeInstance JSON')
        if (match_user_tags := _dict.get('match_user_tags')) is not None:
            args['match_user_tags'] = match_user_tags
        else:
            raise ValueError('Required property \'match_user_tags\' not present in BackupPolicyMatchResourceTypeInstance JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in BackupPolicyMatchResourceTypeInstance JSON')
        if (plans := _dict.get('plans')) is not None:
            args['plans'] = [BackupPolicyPlanReference.from_dict(v) for v in plans]
        else:
            raise ValueError('Required property \'plans\' not present in BackupPolicyMatchResourceTypeInstance JSON')
        if (resource_group := _dict.get('resource_group')) is not None:
            args['resource_group'] = ResourceGroupReference.from_dict(resource_group)
        else:
            raise ValueError('Required property \'resource_group\' not present in BackupPolicyMatchResourceTypeInstance JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = resource_type
        else:
            raise ValueError('Required property \'resource_type\' not present in BackupPolicyMatchResourceTypeInstance JSON')
        if (scope := _dict.get('scope')) is not None:
            args['scope'] = scope
        else:
            raise ValueError('Required property \'scope\' not present in BackupPolicyMatchResourceTypeInstance JSON')
        if (included_content := _dict.get('included_content')) is not None:
            args['included_content'] = included_content
        else:
            raise ValueError('Required property \'included_content\' not present in BackupPolicyMatchResourceTypeInstance JSON')
        if (match_resource_type := _dict.get('match_resource_type')) is not None:
            args['match_resource_type'] = match_resource_type
        else:
            raise ValueError('Required property \'match_resource_type\' not present in BackupPolicyMatchResourceTypeInstance JSON')
        return cls(**args)

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

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

    def __ne__(self, other: 'BackupPolicyMatchResourceTypeInstance') -> 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 ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        BACKUP_POLICY = 'backup_policy'


    class IncludedContentEnum(str, Enum):
        """
        An item to include.
        """

        BOOT_VOLUME = 'boot_volume'
        DATA_VOLUMES = 'data_volumes'


    class MatchResourceTypeEnum(str, Enum):
        """
        The resource type 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 may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        INSTANCE = 'instance'



class BackupPolicyMatchResourceTypeVolume(BackupPolicy):
    """
    BackupPolicyMatchResourceTypeVolume.

    :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).
    :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 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.
    :param str lifecycle_state: The lifecycle state of the backup policy.
    :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:
    :param str match_resource_type: The resource type 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 may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    """

    def __init__(
        self,
        created_at: datetime,
        crn: str,
        health_reasons: List['BackupPolicyHealthReason'],
        health_state: str,
        href: str,
        id: str,
        lifecycle_state: str,
        match_user_tags: List[str],
        name: str,
        plans: List['BackupPolicyPlanReference'],
        resource_group: 'ResourceGroupReference',
        resource_type: str,
        scope: 'BackupPolicyScope',
        match_resource_type: str,
        *,
        last_job_completed_at: Optional[datetime] = None,
    ) -> None:
        """
        Initialize a BackupPolicyMatchResourceTypeVolume 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).
        :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_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:
        :param str match_resource_type: The resource type 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 may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :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.
        """
        # pylint: disable=super-init-not-called
        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_user_tags = match_user_tags
        self.name = name
        self.plans = plans
        self.resource_group = resource_group
        self.resource_type = resource_type
        self.scope = scope
        self.match_resource_type = match_resource_type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'BackupPolicyMatchResourceTypeVolume':
        """Initialize a BackupPolicyMatchResourceTypeVolume object from a json dictionary."""
        args = {}
        if (created_at := _dict.get('created_at')) is not None:
            args['created_at'] = string_to_datetime(created_at)
        else:
            raise ValueError('Required property \'created_at\' not present in BackupPolicyMatchResourceTypeVolume JSON')
        if (crn := _dict.get('crn')) is not None:
            args['crn'] = crn
        else:
            raise ValueError('Required property \'crn\' not present in BackupPolicyMatchResourceTypeVolume JSON')
        if (health_reasons := _dict.get('health_reasons')) is not None:
            args['health_reasons'] = [BackupPolicyHealthReason.from_dict(v) for v in health_reasons]
        else:
            raise ValueError('Required property \'health_reasons\' not present in BackupPolicyMatchResourceTypeVolume JSON')
        if (health_state := _dict.get('health_state')) is not None:
            args['health_state'] = health_state
        else:
            raise ValueError('Required property \'health_state\' not present in BackupPolicyMatchResourceTypeVolume JSON')
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in BackupPolicyMatchResourceTypeVolume JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in BackupPolicyMatchResourceTypeVolume JSON')
        if (last_job_completed_at := _dict.get('last_job_completed_at')) is not None:
            args['last_job_completed_at'] = string_to_datetime(last_job_completed_at)
        if (lifecycle_state := _dict.get('lifecycle_state')) is not None:
            args['lifecycle_state'] = lifecycle_state
        else:
            raise ValueError('Required property \'lifecycle_state\' not present in BackupPolicyMatchResourceTypeVolume JSON')
        if (match_user_tags := _dict.get('match_user_tags')) is not None:
            args['match_user_tags'] = match_user_tags
        else:
            raise ValueError('Required property \'match_user_tags\' not present in BackupPolicyMatchResourceTypeVolume JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in BackupPolicyMatchResourceTypeVolume JSON')
        if (plans := _dict.get('plans')) is not None:
            args['plans'] = [BackupPolicyPlanReference.from_dict(v) for v in plans]
        else:
            raise ValueError('Required property \'plans\' not present in BackupPolicyMatchResourceTypeVolume JSON')
        if (resource_group := _dict.get('resource_group')) is not None:
            args['resource_group'] = ResourceGroupReference.from_dict(resource_group)
        else:
            raise ValueError('Required property \'resource_group\' not present in BackupPolicyMatchResourceTypeVolume JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = resource_type
        else:
            raise ValueError('Required property \'resource_type\' not present in BackupPolicyMatchResourceTypeVolume JSON')
        if (scope := _dict.get('scope')) is not None:
            args['scope'] = scope
        else:
            raise ValueError('Required property \'scope\' not present in BackupPolicyMatchResourceTypeVolume JSON')
        if (match_resource_type := _dict.get('match_resource_type')) is not None:
            args['match_resource_type'] = match_resource_type
        else:
            raise ValueError('Required property \'match_resource_type\' not present in BackupPolicyMatchResourceTypeVolume JSON')
        return cls(**args)

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

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

    def __ne__(self, other: 'BackupPolicyMatchResourceTypeVolume') -> 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 ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        BACKUP_POLICY = 'backup_policy'


    class MatchResourceTypeEnum(str, Enum):
        """
        The resource type 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 may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        VOLUME = 'volume'



class BackupPolicyPrototypeBackupPolicyMatchResourceTypeInstancePrototype(BackupPolicyPrototype):
    """
    BackupPolicyPrototypeBackupPolicyMatchResourceTypeInstancePrototype.

    :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 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)
    :param BackupPolicyScopePrototype scope: (optional)
    :param List[str] included_content: (optional) The included content for backups
          created using this policy:
          - `boot_volume`: Include the instance's boot volume.
          - `data_volumes`: Include the instance's data volumes.
    :param str match_resource_type: The resource type 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.
    """

    def __init__(
        self,
        match_user_tags: List[str],
        match_resource_type: str,
        *,
        name: Optional[str] = None,
        plans: Optional[List['BackupPolicyPlanPrototype']] = None,
        resource_group: Optional['ResourceGroupIdentity'] = None,
        scope: Optional['BackupPolicyScopePrototype'] = None,
        included_content: Optional[List[str]] = None,
    ) -> None:
        """
        Initialize a BackupPolicyPrototypeBackupPolicyMatchResourceTypeInstancePrototype object.

        :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 str match_resource_type: The resource type 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)
        :param BackupPolicyScopePrototype scope: (optional)
        :param List[str] included_content: (optional) The included content for
               backups created using this policy:
               - `boot_volume`: Include the instance's boot volume.
               - `data_volumes`: Include the instance's data volumes.
        """
        # pylint: disable=super-init-not-called
        self.match_user_tags = match_user_tags
        self.name = name
        self.plans = plans
        self.resource_group = resource_group
        self.scope = scope
        self.included_content = included_content
        self.match_resource_type = match_resource_type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'BackupPolicyPrototypeBackupPolicyMatchResourceTypeInstancePrototype':
        """Initialize a BackupPolicyPrototypeBackupPolicyMatchResourceTypeInstancePrototype object from a json dictionary."""
        args = {}
        if (match_user_tags := _dict.get('match_user_tags')) is not None:
            args['match_user_tags'] = match_user_tags
        else:
            raise ValueError('Required property \'match_user_tags\' not present in BackupPolicyPrototypeBackupPolicyMatchResourceTypeInstancePrototype JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        if (plans := _dict.get('plans')) is not None:
            args['plans'] = [BackupPolicyPlanPrototype.from_dict(v) for v in plans]
        if (resource_group := _dict.get('resource_group')) is not None:
            args['resource_group'] = resource_group
        if (scope := _dict.get('scope')) is not None:
            args['scope'] = scope
        if (included_content := _dict.get('included_content')) is not None:
            args['included_content'] = included_content
        if (match_resource_type := _dict.get('match_resource_type')) is not None:
            args['match_resource_type'] = match_resource_type
        else:
            raise ValueError('Required property \'match_resource_type\' not present in BackupPolicyPrototypeBackupPolicyMatchResourceTypeInstancePrototype JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a BackupPolicyPrototypeBackupPolicyMatchResourceTypeInstancePrototype object from 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
        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, 'scope') and self.scope is not None:
            if isinstance(self.scope, dict):
                _dict['scope'] = self.scope
            else:
                _dict['scope'] = self.scope.to_dict()
        if hasattr(self, 'included_content') and self.included_content is not None:
            _dict['included_content'] = self.included_content
        if hasattr(self, 'match_resource_type') and self.match_resource_type is not None:
            _dict['match_resource_type'] = self.match_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 BackupPolicyPrototypeBackupPolicyMatchResourceTypeInstancePrototype object."""
        return json.dumps(self.to_dict(), indent=2)

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

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

    class IncludedContentEnum(str, Enum):
        """
        An item to include.
        """

        BOOT_VOLUME = 'boot_volume'
        DATA_VOLUMES = 'data_volumes'


    class MatchResourceTypeEnum(str, Enum):
        """
        The resource type 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.
        """

        INSTANCE = 'instance'



class BackupPolicyPrototypeBackupPolicyMatchResourceTypeVolumePrototype(BackupPolicyPrototype):
    """
    BackupPolicyPrototypeBackupPolicyMatchResourceTypeVolumePrototype.

    :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 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)
    :param BackupPolicyScopePrototype scope: (optional)
    :param str match_resource_type: The resource type 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.
    """

    def __init__(
        self,
        match_user_tags: List[str],
        match_resource_type: str,
        *,
        name: Optional[str] = None,
        plans: Optional[List['BackupPolicyPlanPrototype']] = None,
        resource_group: Optional['ResourceGroupIdentity'] = None,
        scope: Optional['BackupPolicyScopePrototype'] = None,
    ) -> None:
        """
        Initialize a BackupPolicyPrototypeBackupPolicyMatchResourceTypeVolumePrototype object.

        :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 str match_resource_type: The resource type 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)
        :param BackupPolicyScopePrototype scope: (optional)
        """
        # pylint: disable=super-init-not-called
        self.match_user_tags = match_user_tags
        self.name = name
        self.plans = plans
        self.resource_group = resource_group
        self.scope = scope
        self.match_resource_type = match_resource_type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'BackupPolicyPrototypeBackupPolicyMatchResourceTypeVolumePrototype':
        """Initialize a BackupPolicyPrototypeBackupPolicyMatchResourceTypeVolumePrototype object from a json dictionary."""
        args = {}
        if (match_user_tags := _dict.get('match_user_tags')) is not None:
            args['match_user_tags'] = match_user_tags
        else:
            raise ValueError('Required property \'match_user_tags\' not present in BackupPolicyPrototypeBackupPolicyMatchResourceTypeVolumePrototype JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        if (plans := _dict.get('plans')) is not None:
            args['plans'] = [BackupPolicyPlanPrototype.from_dict(v) for v in plans]
        if (resource_group := _dict.get('resource_group')) is not None:
            args['resource_group'] = resource_group
        if (scope := _dict.get('scope')) is not None:
            args['scope'] = scope
        if (match_resource_type := _dict.get('match_resource_type')) is not None:
            args['match_resource_type'] = match_resource_type
        else:
            raise ValueError('Required property \'match_resource_type\' not present in BackupPolicyPrototypeBackupPolicyMatchResourceTypeVolumePrototype JSON')
        return cls(**args)

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

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

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

    class MatchResourceTypeEnum(str, Enum):
        """
        The resource type 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.
        """

        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.

    :param str id: The unique identifier for this account.
    :param 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 := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in BackupPolicyScopeAccountReference JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = 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.

    :param str crn: The CRN for this enterprise.
    :param str id: The unique identifier for this enterprise.
    :param 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 := _dict.get('crn')) is not None:
            args['crn'] = crn
        else:
            raise ValueError('Required property \'crn\' not present in BackupPolicyScopeEnterpriseReference JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in BackupPolicyScopeEnterpriseReference JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = 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.

    :param Deleted deleted: (optional) If present, this property indicates the
          referenced resource has been deleted, and provides
          some supplementary information.
    :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.
    """

    def __init__(
        self,
        href: str,
        id: str,
        name: str,
        resource_type: str,
        *,
        deleted: Optional['Deleted'] = 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 Deleted 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 := _dict.get('deleted')) is not None:
            args['deleted'] = Deleted.from_dict(deleted)
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in BareMetalServerBootTargetBareMetalServerDiskReference JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in BareMetalServerBootTargetBareMetalServerDiskReference JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in BareMetalServerBootTargetBareMetalServerDiskReference JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = 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.

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

    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 := _dict.get('encrypted_password')) is not None:
            args['encrypted_password'] = base64.b64decode(encrypted_password)
        else:
            raise ValueError('Required property \'encrypted_password\' not present in BareMetalServerInitializationUserAccountBareMetalServerInitializationHostUserAccount JSON')
        if (encryption_key := _dict.get('encryption_key')) is not None:
            args['encryption_key'] = KeyReference.from_dict(encryption_key)
        else:
            raise ValueError('Required property \'encryption_key\' not present in BareMetalServerInitializationUserAccountBareMetalServerInitializationHostUserAccount JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = resource_type
        else:
            raise ValueError('Required property \'resource_type\' not present in BareMetalServerInitializationUserAccountBareMetalServerInitializationHostUserAccount JSON')
        if (username := _dict.get('username')) is not None:
            args['username'] = 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 BareMetalServerNetworkAttachmentByPCI(BareMetalServerNetworkAttachment):
    """
    BareMetalServerNetworkAttachmentByPCI.

    :param datetime created_at: The date and time that the bare metal server network
          attachment was created.
    :param str href: The URL for this bare metal server network attachment.
    :param str id: The unique identifier for this bare metal server network
          attachment.
    :param str lifecycle_state: The lifecycle state of the bare metal server network
          attachment.
    :param str name: The name for this bare metal server network attachment. The
          name is unique across all network attachments for the bare metal server.
    :param int port_speed: The port speed for this bare metal server network
          attachment in Mbps.
    :param ReservedIPReference primary_ip: The primary IP address of the virtual
          network interface for the bare metal server network attachment.
    :param str resource_type: The resource type.
    :param SubnetReference subnet: The subnet of the virtual network interface for
          the bare metal server network attachment.
    :param str type: The bare metal server network attachment type.
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :param VirtualNetworkInterfaceReferenceAttachmentContext
          virtual_network_interface: The virtual network interface for this bare metal
          server network attachment.
    :param List[int] allowed_vlans: The VLAN IDs allowed for `vlan` attachments
          using this PCI attachment.
    :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 attachment
            - Cannot directly use an IEEE 802.1Q tag.
    """

    def __init__(
        self,
        created_at: datetime,
        href: str,
        id: str,
        lifecycle_state: str,
        name: str,
        port_speed: int,
        primary_ip: 'ReservedIPReference',
        resource_type: str,
        subnet: 'SubnetReference',
        type: str,
        virtual_network_interface: 'VirtualNetworkInterfaceReferenceAttachmentContext',
        allowed_vlans: List[int],
        interface_type: str,
    ) -> None:
        """
        Initialize a BareMetalServerNetworkAttachmentByPCI object.

        :param datetime created_at: The date and time that the bare metal server
               network attachment was created.
        :param str href: The URL for this bare metal server network attachment.
        :param str id: The unique identifier for this bare metal server network
               attachment.
        :param str lifecycle_state: The lifecycle state of the bare metal server
               network attachment.
        :param str name: The name for this bare metal server network attachment.
               The name is unique across all network attachments for the bare metal
               server.
        :param int port_speed: The port speed for this bare metal server network
               attachment in Mbps.
        :param ReservedIPReference primary_ip: The primary IP address of the
               virtual network interface for the bare metal server network attachment.
        :param str resource_type: The resource type.
        :param SubnetReference subnet: The subnet of the virtual network interface
               for the bare metal server network attachment.
        :param str type: The bare metal server network attachment type.
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :param VirtualNetworkInterfaceReferenceAttachmentContext
               virtual_network_interface: The virtual network interface for this bare
               metal server network attachment.
        :param List[int] allowed_vlans: The VLAN IDs allowed for `vlan` attachments
               using this PCI attachment.
        :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 attachment
                 - Cannot directly use an IEEE 802.1Q tag.
        """
        # pylint: disable=super-init-not-called
        self.created_at = created_at
        self.href = href
        self.id = id
        self.lifecycle_state = lifecycle_state
        self.name = name
        self.port_speed = port_speed
        self.primary_ip = primary_ip
        self.resource_type = resource_type
        self.subnet = subnet
        self.type = type
        self.virtual_network_interface = virtual_network_interface
        self.allowed_vlans = allowed_vlans
        self.interface_type = interface_type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'BareMetalServerNetworkAttachmentByPCI':
        """Initialize a BareMetalServerNetworkAttachmentByPCI object from a json dictionary."""
        args = {}
        if (created_at := _dict.get('created_at')) is not None:
            args['created_at'] = string_to_datetime(created_at)
        else:
            raise ValueError('Required property \'created_at\' not present in BareMetalServerNetworkAttachmentByPCI JSON')
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in BareMetalServerNetworkAttachmentByPCI JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in BareMetalServerNetworkAttachmentByPCI JSON')
        if (lifecycle_state := _dict.get('lifecycle_state')) is not None:
            args['lifecycle_state'] = lifecycle_state
        else:
            raise ValueError('Required property \'lifecycle_state\' not present in BareMetalServerNetworkAttachmentByPCI JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in BareMetalServerNetworkAttachmentByPCI JSON')
        if (port_speed := _dict.get('port_speed')) is not None:
            args['port_speed'] = port_speed
        else:
            raise ValueError('Required property \'port_speed\' not present in BareMetalServerNetworkAttachmentByPCI JSON')
        if (primary_ip := _dict.get('primary_ip')) is not None:
            args['primary_ip'] = ReservedIPReference.from_dict(primary_ip)
        else:
            raise ValueError('Required property \'primary_ip\' not present in BareMetalServerNetworkAttachmentByPCI JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = resource_type
        else:
            raise ValueError('Required property \'resource_type\' not present in BareMetalServerNetworkAttachmentByPCI JSON')
        if (subnet := _dict.get('subnet')) is not None:
            args['subnet'] = SubnetReference.from_dict(subnet)
        else:
            raise ValueError('Required property \'subnet\' not present in BareMetalServerNetworkAttachmentByPCI JSON')
        if (type := _dict.get('type')) is not None:
            args['type'] = type
        else:
            raise ValueError('Required property \'type\' not present in BareMetalServerNetworkAttachmentByPCI JSON')
        if (virtual_network_interface := _dict.get('virtual_network_interface')) is not None:
            args['virtual_network_interface'] = VirtualNetworkInterfaceReferenceAttachmentContext.from_dict(virtual_network_interface)
        else:
            raise ValueError('Required property \'virtual_network_interface\' not present in BareMetalServerNetworkAttachmentByPCI JSON')
        if (allowed_vlans := _dict.get('allowed_vlans')) is not None:
            args['allowed_vlans'] = allowed_vlans
        else:
            raise ValueError('Required property \'allowed_vlans\' not present in BareMetalServerNetworkAttachmentByPCI JSON')
        if (interface_type := _dict.get('interface_type')) is not None:
            args['interface_type'] = interface_type
        else:
            raise ValueError('Required property \'interface_type\' not present in BareMetalServerNetworkAttachmentByPCI JSON')
        return cls(**args)

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

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

    def __ne__(self, other: 'BareMetalServerNetworkAttachmentByPCI') -> 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 network attachment.
        """

        DELETING = 'deleting'
        FAILED = 'failed'
        PENDING = 'pending'
        STABLE = 'stable'
        SUSPENDED = 'suspended'
        UPDATING = 'updating'
        WAITING = 'waiting'


    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        BARE_METAL_SERVER_NETWORK_ATTACHMENT = 'bare_metal_server_network_attachment'


    class TypeEnum(str, Enum):
        """
        The bare metal server network attachment type.
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        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 attachment
          - Cannot directly use an IEEE 802.1Q tag.
        """

        PCI = 'pci'



class BareMetalServerNetworkAttachmentByVLAN(BareMetalServerNetworkAttachment):
    """
    BareMetalServerNetworkAttachmentByVLAN.

    :param datetime created_at: The date and time that the bare metal server network
          attachment was created.
    :param str href: The URL for this bare metal server network attachment.
    :param str id: The unique identifier for this bare metal server network
          attachment.
    :param str lifecycle_state: The lifecycle state of the bare metal server network
          attachment.
    :param str name: The name for this bare metal server network attachment. The
          name is unique across all network attachments for the bare metal server.
    :param int port_speed: The port speed for this bare metal server network
          attachment in Mbps.
    :param ReservedIPReference primary_ip: The primary IP address of the virtual
          network interface for the bare metal server network attachment.
    :param str resource_type: The resource type.
    :param SubnetReference subnet: The subnet of the virtual network interface for
          the bare metal server network attachment.
    :param str type: The bare metal server network attachment type.
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :param VirtualNetworkInterfaceReferenceAttachmentContext
          virtual_network_interface: The virtual network interface for this bare metal
          server network attachment.
    :param bool allow_to_float: Indicates if the data path for the network
          attachment can float to another bare metal server. Can only be `true` for
          network attachments 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 attachment will be automatically
          deleted from this bare metal server and a new network attachment with the same
          `id`, `name` and `vlan` will be created on the other bare metal server.  The
          virtual network interface for this network attachment will be automatically be
          attached to the new network attachment.
          For the data path to float, the other bare metal server must be in the same
          `resource_group`, and must have a network attachment with `interface_type` of
          `pci` with `allowed_vlans` including this network attachment'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.
    :param int vlan: The IEEE 802.1Q VLAN ID that must be used for all traffic on
          this attachment.
    """

    def __init__(
        self,
        created_at: datetime,
        href: str,
        id: str,
        lifecycle_state: str,
        name: str,
        port_speed: int,
        primary_ip: 'ReservedIPReference',
        resource_type: str,
        subnet: 'SubnetReference',
        type: str,
        virtual_network_interface: 'VirtualNetworkInterfaceReferenceAttachmentContext',
        allow_to_float: bool,
        interface_type: str,
        vlan: int,
    ) -> None:
        """
        Initialize a BareMetalServerNetworkAttachmentByVLAN object.

        :param datetime created_at: The date and time that the bare metal server
               network attachment was created.
        :param str href: The URL for this bare metal server network attachment.
        :param str id: The unique identifier for this bare metal server network
               attachment.
        :param str lifecycle_state: The lifecycle state of the bare metal server
               network attachment.
        :param str name: The name for this bare metal server network attachment.
               The name is unique across all network attachments for the bare metal
               server.
        :param int port_speed: The port speed for this bare metal server network
               attachment in Mbps.
        :param ReservedIPReference primary_ip: The primary IP address of the
               virtual network interface for the bare metal server network attachment.
        :param str resource_type: The resource type.
        :param SubnetReference subnet: The subnet of the virtual network interface
               for the bare metal server network attachment.
        :param str type: The bare metal server network attachment type.
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :param VirtualNetworkInterfaceReferenceAttachmentContext
               virtual_network_interface: The virtual network interface for this bare
               metal server network attachment.
        :param bool allow_to_float: Indicates if the data path for the network
               attachment can float to another bare metal server. Can only be `true` for
               network attachments 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 attachment will be
               automatically deleted from this bare metal server and a new network
               attachment with the same `id`, `name` and `vlan` will be created on the
               other bare metal server.  The virtual network interface for this network
               attachment will be automatically be attached to the new network attachment.
               For the data path to float, the other bare metal server must be in the same
               `resource_group`, and must have a network attachment with `interface_type`
               of `pci` with `allowed_vlans` including this network attachment'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.
        :param int vlan: The IEEE 802.1Q VLAN ID that must be used for all traffic
               on this attachment.
        """
        # pylint: disable=super-init-not-called
        self.created_at = created_at
        self.href = href
        self.id = id
        self.lifecycle_state = lifecycle_state
        self.name = name
        self.port_speed = port_speed
        self.primary_ip = primary_ip
        self.resource_type = resource_type
        self.subnet = subnet
        self.type = type
        self.virtual_network_interface = virtual_network_interface
        self.allow_to_float = allow_to_float
        self.interface_type = interface_type
        self.vlan = vlan

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'BareMetalServerNetworkAttachmentByVLAN':
        """Initialize a BareMetalServerNetworkAttachmentByVLAN object from a json dictionary."""
        args = {}
        if (created_at := _dict.get('created_at')) is not None:
            args['created_at'] = string_to_datetime(created_at)
        else:
            raise ValueError('Required property \'created_at\' not present in BareMetalServerNetworkAttachmentByVLAN JSON')
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in BareMetalServerNetworkAttachmentByVLAN JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in BareMetalServerNetworkAttachmentByVLAN JSON')
        if (lifecycle_state := _dict.get('lifecycle_state')) is not None:
            args['lifecycle_state'] = lifecycle_state
        else:
            raise ValueError('Required property \'lifecycle_state\' not present in BareMetalServerNetworkAttachmentByVLAN JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in BareMetalServerNetworkAttachmentByVLAN JSON')
        if (port_speed := _dict.get('port_speed')) is not None:
            args['port_speed'] = port_speed
        else:
            raise ValueError('Required property \'port_speed\' not present in BareMetalServerNetworkAttachmentByVLAN JSON')
        if (primary_ip := _dict.get('primary_ip')) is not None:
            args['primary_ip'] = ReservedIPReference.from_dict(primary_ip)
        else:
            raise ValueError('Required property \'primary_ip\' not present in BareMetalServerNetworkAttachmentByVLAN JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = resource_type
        else:
            raise ValueError('Required property \'resource_type\' not present in BareMetalServerNetworkAttachmentByVLAN JSON')
        if (subnet := _dict.get('subnet')) is not None:
            args['subnet'] = SubnetReference.from_dict(subnet)
        else:
            raise ValueError('Required property \'subnet\' not present in BareMetalServerNetworkAttachmentByVLAN JSON')
        if (type := _dict.get('type')) is not None:
            args['type'] = type
        else:
            raise ValueError('Required property \'type\' not present in BareMetalServerNetworkAttachmentByVLAN JSON')
        if (virtual_network_interface := _dict.get('virtual_network_interface')) is not None:
            args['virtual_network_interface'] = VirtualNetworkInterfaceReferenceAttachmentContext.from_dict(virtual_network_interface)
        else:
            raise ValueError('Required property \'virtual_network_interface\' not present in BareMetalServerNetworkAttachmentByVLAN JSON')
        if (allow_to_float := _dict.get('allow_to_float')) is not None:
            args['allow_to_float'] = allow_to_float
        else:
            raise ValueError('Required property \'allow_to_float\' not present in BareMetalServerNetworkAttachmentByVLAN JSON')
        if (interface_type := _dict.get('interface_type')) is not None:
            args['interface_type'] = interface_type
        else:
            raise ValueError('Required property \'interface_type\' not present in BareMetalServerNetworkAttachmentByVLAN JSON')
        if (vlan := _dict.get('vlan')) is not None:
            args['vlan'] = vlan
        else:
            raise ValueError('Required property \'vlan\' not present in BareMetalServerNetworkAttachmentByVLAN JSON')
        return cls(**args)

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

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

    def __ne__(self, other: 'BareMetalServerNetworkAttachmentByVLAN') -> 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 network attachment.
        """

        DELETING = 'deleting'
        FAILED = 'failed'
        PENDING = 'pending'
        STABLE = 'stable'
        SUSPENDED = 'suspended'
        UPDATING = 'updating'
        WAITING = 'waiting'


    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        BARE_METAL_SERVER_NETWORK_ATTACHMENT = 'bare_metal_server_network_attachment'


    class TypeEnum(str, Enum):
        """
        The bare metal server network attachment type.
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

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

        VLAN = 'vlan'



class BareMetalServerNetworkAttachmentPrototypeVirtualNetworkInterfaceVirtualNetworkInterfaceIdentity(BareMetalServerNetworkAttachmentPrototypeVirtualNetworkInterface):
    """
    Identifies a virtual network interface by a unique property.

    """

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

        """
        # pylint: disable=super-init-not-called
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['BareMetalServerNetworkAttachmentPrototypeVirtualNetworkInterfaceVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityById', 'BareMetalServerNetworkAttachmentPrototypeVirtualNetworkInterfaceVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByHref', 'BareMetalServerNetworkAttachmentPrototypeVirtualNetworkInterfaceVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByCRN'])
        )
        raise Exception(msg)


class BareMetalServerNetworkAttachmentPrototypeVirtualNetworkInterfaceVirtualNetworkInterfacePrototypeBareMetalServerNetworkAttachmentContext(BareMetalServerNetworkAttachmentPrototypeVirtualNetworkInterface):
    """
    The virtual network interface for this target.

    :param bool allow_ip_spoofing: (optional) Indicates whether source IP spoofing
          is allowed on this interface. If `false`, source IP spoofing is prevented on
          this interface. If `true`, source IP spoofing is allowed on this interface.
    :param bool auto_delete: (optional) Indicates whether this virtual network
          interface will be automatically deleted when
          `target` is deleted.
    :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 virtual network interface,
            allowing the workload to perform any needed NAT operations.
          - `allow_ip_spoofing` must be `false`.
          - Can only be attached to a `target` with a `resource_type` of
            `bare_metal_server_network_attachment`.
    :param List[VirtualNetworkInterfaceIPPrototype] ips: (optional) Additional IP
          addresses to bind to the virtual network interface. Each item may be either a
          reserved IP identity, or a reserved IP prototype object which will be used to
          create a new reserved IP. All IP addresses must be in the primary IP's subnet.
          If reserved IP identities are provided, the specified reserved IPs must be
          unbound.
          If reserved IP prototype objects with addresses are provided, the addresses must
          be available on the virtual network interface's subnet. For any prototype
          objects that do not specify an address, an available address on the subnet will
          be automatically selected and reserved.
    :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 str protocol_state_filtering_mode: (optional) The protocol state
          filtering mode to use for this virtual network interface. If
          `auto`, protocol state packet filtering is enabled or disabled based on the
          virtual network interface's `target` resource type:
          - `bare_metal_server_network_attachment`: disabled
          - `instance_network_attachment`: enabled
          - `share_mount_target`: enabled
          Protocol state filtering monitors each network connection flowing over this
          virtual network interface, and drops any packets that are invalid based on the
          current connection state and protocol. See [Protocol state filtering
          mode](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#protocol-state-filtering)
          for more information.
    :param ResourceGroupIdentity resource_group: (optional) The resource group to
          use for this virtual network interface. If unspecified, the
          bare metal server'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.
    """

    def __init__(
        self,
        *,
        allow_ip_spoofing: Optional[bool] = None,
        auto_delete: Optional[bool] = None,
        enable_infrastructure_nat: Optional[bool] = None,
        ips: Optional[List['VirtualNetworkInterfaceIPPrototype']] = None,
        name: Optional[str] = None,
        primary_ip: Optional['VirtualNetworkInterfacePrimaryIPPrototype'] = None,
        protocol_state_filtering_mode: Optional[str] = None,
        resource_group: Optional['ResourceGroupIdentity'] = None,
        security_groups: Optional[List['SecurityGroupIdentity']] = None,
        subnet: Optional['SubnetIdentity'] = None,
    ) -> None:
        """
        Initialize a BareMetalServerNetworkAttachmentPrototypeVirtualNetworkInterfaceVirtualNetworkInterfacePrototypeBareMetalServerNetworkAttachmentContext object.

        :param bool allow_ip_spoofing: (optional) Indicates whether source IP
               spoofing is allowed on this interface. If `false`, source IP spoofing is
               prevented on this interface. If `true`, source IP spoofing is allowed on
               this interface.
        :param bool auto_delete: (optional) Indicates whether this virtual network
               interface will be automatically deleted when
               `target` is deleted.
        :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 virtual network interface,
                 allowing the workload to perform any needed NAT operations.
               - `allow_ip_spoofing` must be `false`.
               - Can only be attached to a `target` with a `resource_type` of
                 `bare_metal_server_network_attachment`.
        :param List[VirtualNetworkInterfaceIPPrototype] ips: (optional) Additional
               IP addresses to bind to the virtual network interface. Each item may be
               either a reserved IP identity, or a reserved IP prototype object which will
               be used to create a new reserved IP. All IP addresses must be in the
               primary IP's subnet.
               If reserved IP identities are provided, the specified reserved IPs must be
               unbound.
               If reserved IP prototype objects with addresses are provided, the addresses
               must be available on the virtual network interface's subnet. For any
               prototype objects that do not specify an address, an available address on
               the subnet will be automatically selected and reserved.
        :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 str protocol_state_filtering_mode: (optional) The protocol state
               filtering mode to use for this virtual network interface. If
               `auto`, protocol state packet filtering is enabled or disabled based on the
               virtual network interface's `target` resource type:
               - `bare_metal_server_network_attachment`: disabled
               - `instance_network_attachment`: enabled
               - `share_mount_target`: enabled
               Protocol state filtering monitors each network connection flowing over this
               virtual network interface, and drops any packets that are invalid based on
               the current connection state and protocol. See [Protocol state filtering
               mode](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#protocol-state-filtering)
               for more information.
        :param ResourceGroupIdentity resource_group: (optional) The resource group
               to use for this virtual network interface. If unspecified, the
               bare metal server'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.allow_ip_spoofing = allow_ip_spoofing
        self.auto_delete = auto_delete
        self.enable_infrastructure_nat = enable_infrastructure_nat
        self.ips = ips
        self.name = name
        self.primary_ip = primary_ip
        self.protocol_state_filtering_mode = protocol_state_filtering_mode
        self.resource_group = resource_group
        self.security_groups = security_groups
        self.subnet = subnet

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'BareMetalServerNetworkAttachmentPrototypeVirtualNetworkInterfaceVirtualNetworkInterfacePrototypeBareMetalServerNetworkAttachmentContext':
        """Initialize a BareMetalServerNetworkAttachmentPrototypeVirtualNetworkInterfaceVirtualNetworkInterfacePrototypeBareMetalServerNetworkAttachmentContext object from a json dictionary."""
        args = {}
        if (allow_ip_spoofing := _dict.get('allow_ip_spoofing')) is not None:
            args['allow_ip_spoofing'] = allow_ip_spoofing
        if (auto_delete := _dict.get('auto_delete')) is not None:
            args['auto_delete'] = auto_delete
        if (enable_infrastructure_nat := _dict.get('enable_infrastructure_nat')) is not None:
            args['enable_infrastructure_nat'] = enable_infrastructure_nat
        if (ips := _dict.get('ips')) is not None:
            args['ips'] = ips
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        if (primary_ip := _dict.get('primary_ip')) is not None:
            args['primary_ip'] = primary_ip
        if (protocol_state_filtering_mode := _dict.get('protocol_state_filtering_mode')) is not None:
            args['protocol_state_filtering_mode'] = protocol_state_filtering_mode
        if (resource_group := _dict.get('resource_group')) is not None:
            args['resource_group'] = resource_group
        if (security_groups := _dict.get('security_groups')) is not None:
            args['security_groups'] = security_groups
        if (subnet := _dict.get('subnet')) is not None:
            args['subnet'] = subnet
        return cls(**args)

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

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

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

    class ProtocolStateFilteringModeEnum(str, Enum):
        """
        The protocol state filtering mode to use for this virtual network interface. If
        `auto`, protocol state packet filtering is enabled or disabled based on the
        virtual network interface's `target` resource type:
        - `bare_metal_server_network_attachment`: disabled
        - `instance_network_attachment`: enabled
        - `share_mount_target`: enabled
        Protocol state filtering monitors each network connection flowing over this
        virtual network interface, and drops any packets that are invalid based on the
        current connection state and protocol. See [Protocol state filtering
        mode](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#protocol-state-filtering)
        for more information.
        """

        AUTO = 'auto'
        DISABLED = 'disabled'
        ENABLED = 'enabled'



class BareMetalServerNetworkAttachmentPrototypeBareMetalServerNetworkAttachmentByPCIPrototype(BareMetalServerNetworkAttachmentPrototype):
    """
    BareMetalServerNetworkAttachmentPrototypeBareMetalServerNetworkAttachmentByPCIPrototype.

    :param str name: (optional) The name for this bare metal server network
          attachment. Names must be unique within the bare metal server the network
          attachment resides in. If unspecified, the name will be a hyphenated list of
          randomly-selected words.
    :param BareMetalServerNetworkAttachmentPrototypeVirtualNetworkInterface
          virtual_network_interface:
    :param List[int] allowed_vlans: (optional) The VLAN IDs to allow for `vlan`
          attachments using this PCI attachment.
    :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 attachment
            - Cannot directly use an IEEE 802.1Q tag.
            - Not supported on bare metal servers with a `cpu.architecture` of `s390x`.
    """

    def __init__(
        self,
        virtual_network_interface: 'BareMetalServerNetworkAttachmentPrototypeVirtualNetworkInterface',
        interface_type: str,
        *,
        name: Optional[str] = None,
        allowed_vlans: Optional[List[int]] = None,
    ) -> None:
        """
        Initialize a BareMetalServerNetworkAttachmentPrototypeBareMetalServerNetworkAttachmentByPCIPrototype object.

        :param BareMetalServerNetworkAttachmentPrototypeVirtualNetworkInterface
               virtual_network_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 attachment
                 - 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
               attachment. Names must be unique within the bare metal server the network
               attachment resides in. If unspecified, the name will be a hyphenated list
               of randomly-selected words.
        :param List[int] allowed_vlans: (optional) The VLAN IDs to allow for `vlan`
               attachments using this PCI attachment.
        """
        # pylint: disable=super-init-not-called
        self.name = name
        self.virtual_network_interface = virtual_network_interface
        self.allowed_vlans = allowed_vlans
        self.interface_type = interface_type

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

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

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

    def __ne__(self, other: 'BareMetalServerNetworkAttachmentPrototypeBareMetalServerNetworkAttachmentByPCIPrototype') -> 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 attachment
          - Cannot directly use an IEEE 802.1Q tag.
          - Not supported on bare metal servers with a `cpu.architecture` of `s390x`.
        """

        PCI = 'pci'



class BareMetalServerNetworkAttachmentPrototypeBareMetalServerNetworkAttachmentByVLANPrototype(BareMetalServerNetworkAttachmentPrototype):
    """
    BareMetalServerNetworkAttachmentPrototypeBareMetalServerNetworkAttachmentByVLANPrototype.

    :param str name: (optional) The name for this bare metal server network
          attachment. Names must be unique within the bare metal server the network
          attachment resides in. If unspecified, the name will be a hyphenated list of
          randomly-selected words.
    :param BareMetalServerNetworkAttachmentPrototypeVirtualNetworkInterface
          virtual_network_interface:
    :param bool allow_to_float: (optional) Indicates if the data path for the
          network attachment can float to another bare metal server. Can only be `true`
          for network attachments 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 attachment will be automatically
          deleted from this bare metal server and a new network attachment with the same
          `id`, `name` and `vlan` will be created on the other bare metal server.  The
          virtual network interface for this network attachment will be automatically be
          attached to the new network attachment.
          For the data path to float, the other bare metal server must be in the same
          `resource_group`, and must have a network attachment with `interface_type` of
          `pci` with `allowed_vlans` including this network attachment'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.
    :param int vlan: The IEEE 802.1Q VLAN ID that must be used for all traffic on
          this attachment.
    """

    def __init__(
        self,
        virtual_network_interface: 'BareMetalServerNetworkAttachmentPrototypeVirtualNetworkInterface',
        interface_type: str,
        vlan: int,
        *,
        name: Optional[str] = None,
        allow_to_float: Optional[bool] = None,
    ) -> None:
        """
        Initialize a BareMetalServerNetworkAttachmentPrototypeBareMetalServerNetworkAttachmentByVLANPrototype object.

        :param BareMetalServerNetworkAttachmentPrototypeVirtualNetworkInterface
               virtual_network_interface:
        :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.
        :param int vlan: The IEEE 802.1Q VLAN ID that must be used for all traffic
               on this attachment.
        :param str name: (optional) The name for this bare metal server network
               attachment. Names must be unique within the bare metal server the network
               attachment resides in. If unspecified, the name will be a hyphenated list
               of randomly-selected words.
        :param bool allow_to_float: (optional) Indicates if the data path for the
               network attachment can float to another bare metal server. Can only be
               `true` for network attachments 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 attachment will be
               automatically deleted from this bare metal server and a new network
               attachment with the same `id`, `name` and `vlan` will be created on the
               other bare metal server.  The virtual network interface for this network
               attachment will be automatically be attached to the new network attachment.
               For the data path to float, the other bare metal server must be in the same
               `resource_group`, and must have a network attachment with `interface_type`
               of `pci` with `allowed_vlans` including this network attachment's `vlan`.
        """
        # pylint: disable=super-init-not-called
        self.name = name
        self.virtual_network_interface = virtual_network_interface
        self.allow_to_float = allow_to_float
        self.interface_type = interface_type
        self.vlan = vlan

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

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

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

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

        VLAN = 'vlan'



class BareMetalServerNetworkInterfaceByHiperSocket(BareMetalServerNetworkInterface):
    """
    BareMetalServerNetworkInterfaceByHiperSocket.

    :param bool allow_ip_spoofing: Indicates whether source IP spoofing is allowed
          on this bare metal server network interface.
          If this bare metal server has network attachments, this network interface is a
          [read-only
          representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
          of its corresponding network attachment and its attached virtual network
          interface, and source IP spoofing is managed on the attached virtual network
          interface.
    :param datetime created_at: The date and time that the bare metal server network
          interface was created.
          If this bare metal server has network attachments, this network interface was
          created as a [read-only
          representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
          when its corresponding network attachment 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`.
          If this bare metal server has network attachments, this network interface is a
          [read-only
          representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
          of its corresponding network attachment and its attached virtual network
          interface, and infrastructure NAT is managed on the attached virtual network
          interface.
    :param List[FloatingIPReference] floating_ips: The floating IPs associated with
          this bare metal server network interface.
          If this bare metal server has network attachments, this network interface is a
          [read-only
          representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
          of its corresponding network attachment and its attached virtual network
          interface, and the floating IPs are associated with the attached virtual network
          interface.
    :param str href: The URL for this bare metal server network interface.
          If this bare metal server has network attachments, this network interface is a
          [read-only
          representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
          of its corresponding network attachment.
    :param str id: The unique identifier for this bare metal server network
          interface.
          If this bare metal server has network attachments, this network interface is a
          [read-only
          representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
          of its corresponding network attachment and its attached virtual network
          interface, and the identifier is that of the corresponding network attachment.
    :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
          empty.
          If this bare metal server has network attachments, this network interface is a
          [read-only
          representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
          of its corresponding network attachment and its attached virtual network
          interface, and the MAC address is that of the attached virtual network
          interface.
    :param str name: The name for this bare metal server network interface.
          If this bare metal server has network attachments, this network interface is a
          [read-only
          representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
          of its corresponding network attachment and its attached virtual network
          interface, and the name matches its corresponding network attachment.
    :param int port_speed: The bare metal server network interface port speed in
          Mbps.
          If this bare metal server has network attachments, this network interface is a
          [read-only
          representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
          of its corresponding network attachment and its attached virtual network
          interface, and the port speed is that of its corresponding network attachment.
    :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.
          If this bare metal server has network attachments, this network interface is a
          [read-only
          representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
          of its corresponding network attachment and its attached virtual network
          interface, and the security groups are associated with the attached virtual
          network interface.
    :param str status: The status of the bare metal server network interface.
          If this bare metal server has network attachments, this network interface is a
          read-only representation of its corresponding network attachment and its
          attached virtual network interface, and the status is [computed from
          them](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients).
    :param SubnetReference subnet: The associated subnet.
    :param str type: The bare metal server network interface type.
          If this bare metal server has network attachments, this network interface is a
          [read-only
          representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
          of its corresponding network attachment and its attached virtual network
          interface, and the type is that of its corresponding network attachment.
    :param 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.
               If this bare metal server has network attachments, this network interface
               is a
               [read-only
               representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
               of its corresponding network attachment and its attached virtual network
               interface, and source IP spoofing is managed on the attached virtual
               network interface.
        :param datetime created_at: The date and time that the bare metal server
               network interface was created.
               If this bare metal server has network attachments, this network interface
               was created as a [read-only
               representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
               when its corresponding network attachment 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`.
               If this bare metal server has network attachments, this network interface
               is a
               [read-only
               representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
               of its corresponding network attachment and its attached virtual network
               interface, and infrastructure NAT is managed on the attached virtual
               network interface.
        :param List[FloatingIPReference] floating_ips: The floating IPs associated
               with this bare metal server network interface.
               If this bare metal server has network attachments, this network interface
               is a
               [read-only
               representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
               of its corresponding network attachment and its attached virtual network
               interface, and the floating IPs are associated with the attached virtual
               network interface.
        :param str href: The URL for this bare metal server network interface.
               If this bare metal server has network attachments, this network interface
               is a
               [read-only
               representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
               of its corresponding network attachment.
        :param str id: The unique identifier for this bare metal server network
               interface.
               If this bare metal server has network attachments, this network interface
               is a
               [read-only
               representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
               of its corresponding network attachment and its attached virtual network
               interface, and the identifier is that of the corresponding network
               attachment.
        :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
               empty.
               If this bare metal server has network attachments, this network interface
               is a
               [read-only
               representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
               of its corresponding network attachment and its attached virtual network
               interface, and the MAC address is that of the attached virtual network
               interface.
        :param str name: The name for this bare metal server network interface.
               If this bare metal server has network attachments, this network interface
               is a
               [read-only
               representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
               of its corresponding network attachment and its attached virtual network
               interface, and the name matches its corresponding network attachment.
        :param int port_speed: The bare metal server network interface port speed
               in Mbps.
               If this bare metal server has network attachments, this network interface
               is a
               [read-only
               representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
               of its corresponding network attachment and its attached virtual network
               interface, and the port speed is that of its corresponding network
               attachment.
        :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.
               If this bare metal server has network attachments, this network interface
               is a
               [read-only
               representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
               of its corresponding network attachment and its attached virtual network
               interface, and the security groups are associated with the attached virtual
               network interface.
        :param str status: The status of the bare metal server network interface.
               If this bare metal server has network attachments, this network interface
               is a read-only representation of its corresponding network attachment and
               its attached virtual network interface, and the status is [computed from
               them](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients).
        :param SubnetReference subnet: The associated subnet.
        :param str type: The bare metal server network interface type.
               If this bare metal server has network attachments, this network interface
               is a
               [read-only
               representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
               of its corresponding network attachment and its attached virtual network
               interface, and the type is that of its corresponding network attachment.
        :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 := _dict.get('allow_ip_spoofing')) is not None:
            args['allow_ip_spoofing'] = allow_ip_spoofing
        else:
            raise ValueError('Required property \'allow_ip_spoofing\' not present in BareMetalServerNetworkInterfaceByHiperSocket JSON')
        if (created_at := _dict.get('created_at')) is not None:
            args['created_at'] = string_to_datetime(created_at)
        else:
            raise ValueError('Required property \'created_at\' not present in BareMetalServerNetworkInterfaceByHiperSocket JSON')
        if (enable_infrastructure_nat := _dict.get('enable_infrastructure_nat')) is not None:
            args['enable_infrastructure_nat'] = enable_infrastructure_nat
        else:
            raise ValueError('Required property \'enable_infrastructure_nat\' not present in BareMetalServerNetworkInterfaceByHiperSocket JSON')
        if (floating_ips := _dict.get('floating_ips')) is not None:
            args['floating_ips'] = [FloatingIPReference.from_dict(v) for v in floating_ips]
        else:
            raise ValueError('Required property \'floating_ips\' not present in BareMetalServerNetworkInterfaceByHiperSocket JSON')
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in BareMetalServerNetworkInterfaceByHiperSocket JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in BareMetalServerNetworkInterfaceByHiperSocket JSON')
        if (mac_address := _dict.get('mac_address')) is not None:
            args['mac_address'] = mac_address
        else:
            raise ValueError('Required property \'mac_address\' not present in BareMetalServerNetworkInterfaceByHiperSocket JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in BareMetalServerNetworkInterfaceByHiperSocket JSON')
        if (port_speed := _dict.get('port_speed')) is not None:
            args['port_speed'] = port_speed
        else:
            raise ValueError('Required property \'port_speed\' not present in BareMetalServerNetworkInterfaceByHiperSocket JSON')
        if (primary_ip := _dict.get('primary_ip')) is not None:
            args['primary_ip'] = ReservedIPReference.from_dict(primary_ip)
        else:
            raise ValueError('Required property \'primary_ip\' not present in BareMetalServerNetworkInterfaceByHiperSocket JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = resource_type
        else:
            raise ValueError('Required property \'resource_type\' not present in BareMetalServerNetworkInterfaceByHiperSocket JSON')
        if (security_groups := _dict.get('security_groups')) is not None:
            args['security_groups'] = [SecurityGroupReference.from_dict(v) for v in security_groups]
        else:
            raise ValueError('Required property \'security_groups\' not present in BareMetalServerNetworkInterfaceByHiperSocket JSON')
        if (status := _dict.get('status')) is not None:
            args['status'] = status
        else:
            raise ValueError('Required property \'status\' not present in BareMetalServerNetworkInterfaceByHiperSocket JSON')
        if (subnet := _dict.get('subnet')) is not None:
            args['subnet'] = SubnetReference.from_dict(subnet)
        else:
            raise ValueError('Required property \'subnet\' not present in BareMetalServerNetworkInterfaceByHiperSocket JSON')
        if (type := _dict.get('type')) is not None:
            args['type'] = type
        else:
            raise ValueError('Required property \'type\' not present in BareMetalServerNetworkInterfaceByHiperSocket JSON')
        if (interface_type := _dict.get('interface_type')) is not None:
            args['interface_type'] = 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.
        If this bare metal server has network attachments, this network interface is a
        read-only representation of its corresponding network attachment and its attached
        virtual network interface, and the status is [computed from
        them](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients).
        """

        AVAILABLE = 'available'
        DELETING = 'deleting'
        FAILED = 'failed'
        PENDING = 'pending'


    class TypeEnum(str, Enum):
        """
        The bare metal server network interface type.
        If this bare metal server has network attachments, this network interface is a
        [read-only
        representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
        of its corresponding network attachment and its attached virtual network
        interface, and the type is that of its corresponding network attachment.
        """

        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.

    :param bool allow_ip_spoofing: Indicates whether source IP spoofing is allowed
          on this bare metal server network interface.
          If this bare metal server has network attachments, this network interface is a
          [read-only
          representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
          of its corresponding network attachment and its attached virtual network
          interface, and source IP spoofing is managed on the attached virtual network
          interface.
    :param datetime created_at: The date and time that the bare metal server network
          interface was created.
          If this bare metal server has network attachments, this network interface was
          created as a [read-only
          representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
          when its corresponding network attachment 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`.
          If this bare metal server has network attachments, this network interface is a
          [read-only
          representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
          of its corresponding network attachment and its attached virtual network
          interface, and infrastructure NAT is managed on the attached virtual network
          interface.
    :param List[FloatingIPReference] floating_ips: The floating IPs associated with
          this bare metal server network interface.
          If this bare metal server has network attachments, this network interface is a
          [read-only
          representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
          of its corresponding network attachment and its attached virtual network
          interface, and the floating IPs are associated with the attached virtual network
          interface.
    :param str href: The URL for this bare metal server network interface.
          If this bare metal server has network attachments, this network interface is a
          [read-only
          representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
          of its corresponding network attachment.
    :param str id: The unique identifier for this bare metal server network
          interface.
          If this bare metal server has network attachments, this network interface is a
          [read-only
          representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
          of its corresponding network attachment and its attached virtual network
          interface, and the identifier is that of the corresponding network attachment.
    :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
          empty.
          If this bare metal server has network attachments, this network interface is a
          [read-only
          representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
          of its corresponding network attachment and its attached virtual network
          interface, and the MAC address is that of the attached virtual network
          interface.
    :param str name: The name for this bare metal server network interface.
          If this bare metal server has network attachments, this network interface is a
          [read-only
          representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
          of its corresponding network attachment and its attached virtual network
          interface, and the name matches its corresponding network attachment.
    :param int port_speed: The bare metal server network interface port speed in
          Mbps.
          If this bare metal server has network attachments, this network interface is a
          [read-only
          representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
          of its corresponding network attachment and its attached virtual network
          interface, and the port speed is that of its corresponding network attachment.
    :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.
          If this bare metal server has network attachments, this network interface is a
          [read-only
          representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
          of its corresponding network attachment and its attached virtual network
          interface, and the security groups are associated with the attached virtual
          network interface.
    :param str status: The status of the bare metal server network interface.
          If this bare metal server has network attachments, this network interface is a
          read-only representation of its corresponding network attachment and its
          attached virtual network interface, and the status is [computed from
          them](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients).
    :param SubnetReference subnet: The associated subnet.
    :param str type: The bare metal server network interface type.
          If this bare metal server has network attachments, this network interface is a
          [read-only
          representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
          of its corresponding network attachment and its attached virtual network
          interface, and the type is that of its corresponding network attachment.
    :param List[int] allowed_vlans: The VLAN IDs allowed for `vlan` interfaces using
          this PCI interface.
          If this bare metal server has network attachments, this network interface is a
          [read-only
          representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
          of its corresponding network attachment and its attached virtual network
          interface, and the VLAN IDs match the `allow_vlans` of the corresponding network
          attachment.
    :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.
    """

    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.
               If this bare metal server has network attachments, this network interface
               is a
               [read-only
               representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
               of its corresponding network attachment and its attached virtual network
               interface, and source IP spoofing is managed on the attached virtual
               network interface.
        :param datetime created_at: The date and time that the bare metal server
               network interface was created.
               If this bare metal server has network attachments, this network interface
               was created as a [read-only
               representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
               when its corresponding network attachment 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`.
               If this bare metal server has network attachments, this network interface
               is a
               [read-only
               representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
               of its corresponding network attachment and its attached virtual network
               interface, and infrastructure NAT is managed on the attached virtual
               network interface.
        :param List[FloatingIPReference] floating_ips: The floating IPs associated
               with this bare metal server network interface.
               If this bare metal server has network attachments, this network interface
               is a
               [read-only
               representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
               of its corresponding network attachment and its attached virtual network
               interface, and the floating IPs are associated with the attached virtual
               network interface.
        :param str href: The URL for this bare metal server network interface.
               If this bare metal server has network attachments, this network interface
               is a
               [read-only
               representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
               of its corresponding network attachment.
        :param str id: The unique identifier for this bare metal server network
               interface.
               If this bare metal server has network attachments, this network interface
               is a
               [read-only
               representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
               of its corresponding network attachment and its attached virtual network
               interface, and the identifier is that of the corresponding network
               attachment.
        :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
               empty.
               If this bare metal server has network attachments, this network interface
               is a
               [read-only
               representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
               of its corresponding network attachment and its attached virtual network
               interface, and the MAC address is that of the attached virtual network
               interface.
        :param str name: The name for this bare metal server network interface.
               If this bare metal server has network attachments, this network interface
               is a
               [read-only
               representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
               of its corresponding network attachment and its attached virtual network
               interface, and the name matches its corresponding network attachment.
        :param int port_speed: The bare metal server network interface port speed
               in Mbps.
               If this bare metal server has network attachments, this network interface
               is a
               [read-only
               representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
               of its corresponding network attachment and its attached virtual network
               interface, and the port speed is that of its corresponding network
               attachment.
        :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.
               If this bare metal server has network attachments, this network interface
               is a
               [read-only
               representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
               of its corresponding network attachment and its attached virtual network
               interface, and the security groups are associated with the attached virtual
               network interface.
        :param str status: The status of the bare metal server network interface.
               If this bare metal server has network attachments, this network interface
               is a read-only representation of its corresponding network attachment and
               its attached virtual network interface, and the status is [computed from
               them](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients).
        :param SubnetReference subnet: The associated subnet.
        :param str type: The bare metal server network interface type.
               If this bare metal server has network attachments, this network interface
               is a
               [read-only
               representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
               of its corresponding network attachment and its attached virtual network
               interface, and the type is that of its corresponding network attachment.
        :param List[int] allowed_vlans: The VLAN IDs allowed for `vlan` interfaces
               using this PCI interface.
               If this bare metal server has network attachments, this network interface
               is a
               [read-only
               representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
               of its corresponding network attachment and its attached virtual network
               interface, and the VLAN IDs match the `allow_vlans` of the corresponding
               network attachment.
        :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 := _dict.get('allow_ip_spoofing')) is not None:
            args['allow_ip_spoofing'] = allow_ip_spoofing
        else:
            raise ValueError('Required property \'allow_ip_spoofing\' not present in BareMetalServerNetworkInterfaceByPCI JSON')
        if (created_at := _dict.get('created_at')) is not None:
            args['created_at'] = string_to_datetime(created_at)
        else:
            raise ValueError('Required property \'created_at\' not present in BareMetalServerNetworkInterfaceByPCI JSON')
        if (enable_infrastructure_nat := _dict.get('enable_infrastructure_nat')) is not None:
            args['enable_infrastructure_nat'] = enable_infrastructure_nat
        else:
            raise ValueError('Required property \'enable_infrastructure_nat\' not present in BareMetalServerNetworkInterfaceByPCI JSON')
        if (floating_ips := _dict.get('floating_ips')) is not None:
            args['floating_ips'] = [FloatingIPReference.from_dict(v) for v in floating_ips]
        else:
            raise ValueError('Required property \'floating_ips\' not present in BareMetalServerNetworkInterfaceByPCI JSON')
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in BareMetalServerNetworkInterfaceByPCI JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in BareMetalServerNetworkInterfaceByPCI JSON')
        if (mac_address := _dict.get('mac_address')) is not None:
            args['mac_address'] = mac_address
        else:
            raise ValueError('Required property \'mac_address\' not present in BareMetalServerNetworkInterfaceByPCI JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in BareMetalServerNetworkInterfaceByPCI JSON')
        if (port_speed := _dict.get('port_speed')) is not None:
            args['port_speed'] = port_speed
        else:
            raise ValueError('Required property \'port_speed\' not present in BareMetalServerNetworkInterfaceByPCI JSON')
        if (primary_ip := _dict.get('primary_ip')) is not None:
            args['primary_ip'] = ReservedIPReference.from_dict(primary_ip)
        else:
            raise ValueError('Required property \'primary_ip\' not present in BareMetalServerNetworkInterfaceByPCI JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = resource_type
        else:
            raise ValueError('Required property \'resource_type\' not present in BareMetalServerNetworkInterfaceByPCI JSON')
        if (security_groups := _dict.get('security_groups')) is not None:
            args['security_groups'] = [SecurityGroupReference.from_dict(v) for v in security_groups]
        else:
            raise ValueError('Required property \'security_groups\' not present in BareMetalServerNetworkInterfaceByPCI JSON')
        if (status := _dict.get('status')) is not None:
            args['status'] = status
        else:
            raise ValueError('Required property \'status\' not present in BareMetalServerNetworkInterfaceByPCI JSON')
        if (subnet := _dict.get('subnet')) is not None:
            args['subnet'] = SubnetReference.from_dict(subnet)
        else:
            raise ValueError('Required property \'subnet\' not present in BareMetalServerNetworkInterfaceByPCI JSON')
        if (type := _dict.get('type')) is not None:
            args['type'] = type
        else:
            raise ValueError('Required property \'type\' not present in BareMetalServerNetworkInterfaceByPCI JSON')
        if (allowed_vlans := _dict.get('allowed_vlans')) is not None:
            args['allowed_vlans'] = allowed_vlans
        else:
            raise ValueError('Required property \'allowed_vlans\' not present in BareMetalServerNetworkInterfaceByPCI JSON')
        if (interface_type := _dict.get('interface_type')) is not None:
            args['interface_type'] = 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.
        If this bare metal server has network attachments, this network interface is a
        read-only representation of its corresponding network attachment and its attached
        virtual network interface, and the status is [computed from
        them](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients).
        """

        AVAILABLE = 'available'
        DELETING = 'deleting'
        FAILED = 'failed'
        PENDING = 'pending'


    class TypeEnum(str, Enum):
        """
        The bare metal server network interface type.
        If this bare metal server has network attachments, this network interface is a
        [read-only
        representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
        of its corresponding network attachment and its attached virtual network
        interface, and the type is that of its corresponding network attachment.
        """

        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.

    :param bool allow_ip_spoofing: Indicates whether source IP spoofing is allowed
          on this bare metal server network interface.
          If this bare metal server has network attachments, this network interface is a
          [read-only
          representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
          of its corresponding network attachment and its attached virtual network
          interface, and source IP spoofing is managed on the attached virtual network
          interface.
    :param datetime created_at: The date and time that the bare metal server network
          interface was created.
          If this bare metal server has network attachments, this network interface was
          created as a [read-only
          representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
          when its corresponding network attachment 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`.
          If this bare metal server has network attachments, this network interface is a
          [read-only
          representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
          of its corresponding network attachment and its attached virtual network
          interface, and infrastructure NAT is managed on the attached virtual network
          interface.
    :param List[FloatingIPReference] floating_ips: The floating IPs associated with
          this bare metal server network interface.
          If this bare metal server has network attachments, this network interface is a
          [read-only
          representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
          of its corresponding network attachment and its attached virtual network
          interface, and the floating IPs are associated with the attached virtual network
          interface.
    :param str href: The URL for this bare metal server network interface.
          If this bare metal server has network attachments, this network interface is a
          [read-only
          representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
          of its corresponding network attachment.
    :param str id: The unique identifier for this bare metal server network
          interface.
          If this bare metal server has network attachments, this network interface is a
          [read-only
          representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
          of its corresponding network attachment and its attached virtual network
          interface, and the identifier is that of the corresponding network attachment.
    :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
          empty.
          If this bare metal server has network attachments, this network interface is a
          [read-only
          representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
          of its corresponding network attachment and its attached virtual network
          interface, and the MAC address is that of the attached virtual network
          interface.
    :param str name: The name for this bare metal server network interface.
          If this bare metal server has network attachments, this network interface is a
          [read-only
          representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
          of its corresponding network attachment and its attached virtual network
          interface, and the name matches its corresponding network attachment.
    :param int port_speed: The bare metal server network interface port speed in
          Mbps.
          If this bare metal server has network attachments, this network interface is a
          [read-only
          representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
          of its corresponding network attachment and its attached virtual network
          interface, and the port speed is that of its corresponding network attachment.
    :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.
          If this bare metal server has network attachments, this network interface is a
          [read-only
          representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
          of its corresponding network attachment and its attached virtual network
          interface, and the security groups are associated with the attached virtual
          network interface.
    :param str status: The status of the bare metal server network interface.
          If this bare metal server has network attachments, this network interface is a
          read-only representation of its corresponding network attachment and its
          attached virtual network interface, and the status is [computed from
          them](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients).
    :param SubnetReference subnet: The associated subnet.
    :param str type: The bare metal server network interface type.
          If this bare metal server has network attachments, this network interface is a
          [read-only
          representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
          of its corresponding network attachment and its attached virtual network
          interface, and the type is that of its corresponding network attachment.
    :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`.
          If this bare metal server has network attachments, this network interface is a
          [read-only
          representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
          of its corresponding network attachment and its attached virtual network
          interface, and the value of this property matches that of the `allow_to_float`
          property of the corresponding network attachment.
    :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.
          If this bare metal server has network attachments, this network interface is a
          [read-only
          representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
          of its corresponding network attachment and its attached virtual network
          interface, and the VLAN ID matches the `vlan` of the corresponding network
          attachment.
    """

    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.
               If this bare metal server has network attachments, this network interface
               is a
               [read-only
               representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
               of its corresponding network attachment and its attached virtual network
               interface, and source IP spoofing is managed on the attached virtual
               network interface.
        :param datetime created_at: The date and time that the bare metal server
               network interface was created.
               If this bare metal server has network attachments, this network interface
               was created as a [read-only
               representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
               when its corresponding network attachment 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`.
               If this bare metal server has network attachments, this network interface
               is a
               [read-only
               representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
               of its corresponding network attachment and its attached virtual network
               interface, and infrastructure NAT is managed on the attached virtual
               network interface.
        :param List[FloatingIPReference] floating_ips: The floating IPs associated
               with this bare metal server network interface.
               If this bare metal server has network attachments, this network interface
               is a
               [read-only
               representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
               of its corresponding network attachment and its attached virtual network
               interface, and the floating IPs are associated with the attached virtual
               network interface.
        :param str href: The URL for this bare metal server network interface.
               If this bare metal server has network attachments, this network interface
               is a
               [read-only
               representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
               of its corresponding network attachment.
        :param str id: The unique identifier for this bare metal server network
               interface.
               If this bare metal server has network attachments, this network interface
               is a
               [read-only
               representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
               of its corresponding network attachment and its attached virtual network
               interface, and the identifier is that of the corresponding network
               attachment.
        :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
               empty.
               If this bare metal server has network attachments, this network interface
               is a
               [read-only
               representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
               of its corresponding network attachment and its attached virtual network
               interface, and the MAC address is that of the attached virtual network
               interface.
        :param str name: The name for this bare metal server network interface.
               If this bare metal server has network attachments, this network interface
               is a
               [read-only
               representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
               of its corresponding network attachment and its attached virtual network
               interface, and the name matches its corresponding network attachment.
        :param int port_speed: The bare metal server network interface port speed
               in Mbps.
               If this bare metal server has network attachments, this network interface
               is a
               [read-only
               representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
               of its corresponding network attachment and its attached virtual network
               interface, and the port speed is that of its corresponding network
               attachment.
        :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.
               If this bare metal server has network attachments, this network interface
               is a
               [read-only
               representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
               of its corresponding network attachment and its attached virtual network
               interface, and the security groups are associated with the attached virtual
               network interface.
        :param str status: The status of the bare metal server network interface.
               If this bare metal server has network attachments, this network interface
               is a read-only representation of its corresponding network attachment and
               its attached virtual network interface, and the status is [computed from
               them](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients).
        :param SubnetReference subnet: The associated subnet.
        :param str type: The bare metal server network interface type.
               If this bare metal server has network attachments, this network interface
               is a
               [read-only
               representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
               of its corresponding network attachment and its attached virtual network
               interface, and the type is that of its corresponding network attachment.
        :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`.
               If this bare metal server has network attachments, this network interface
               is a
               [read-only
               representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
               of its corresponding network attachment and its attached virtual network
               interface, and the value of this property matches that of the
               `allow_to_float` property of the corresponding network attachment.
        :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.
               If this bare metal server has network attachments, this network interface
               is a
               [read-only
               representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
               of its corresponding network attachment and its attached virtual network
               interface, and the VLAN ID matches the `vlan` of the corresponding network
               attachment.
        """
        # 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 := _dict.get('allow_ip_spoofing')) is not None:
            args['allow_ip_spoofing'] = allow_ip_spoofing
        else:
            raise ValueError('Required property \'allow_ip_spoofing\' not present in BareMetalServerNetworkInterfaceByVLAN JSON')
        if (created_at := _dict.get('created_at')) is not None:
            args['created_at'] = string_to_datetime(created_at)
        else:
            raise ValueError('Required property \'created_at\' not present in BareMetalServerNetworkInterfaceByVLAN JSON')
        if (enable_infrastructure_nat := _dict.get('enable_infrastructure_nat')) is not None:
            args['enable_infrastructure_nat'] = enable_infrastructure_nat
        else:
            raise ValueError('Required property \'enable_infrastructure_nat\' not present in BareMetalServerNetworkInterfaceByVLAN JSON')
        if (floating_ips := _dict.get('floating_ips')) is not None:
            args['floating_ips'] = [FloatingIPReference.from_dict(v) for v in floating_ips]
        else:
            raise ValueError('Required property \'floating_ips\' not present in BareMetalServerNetworkInterfaceByVLAN JSON')
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in BareMetalServerNetworkInterfaceByVLAN JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in BareMetalServerNetworkInterfaceByVLAN JSON')
        if (mac_address := _dict.get('mac_address')) is not None:
            args['mac_address'] = mac_address
        else:
            raise ValueError('Required property \'mac_address\' not present in BareMetalServerNetworkInterfaceByVLAN JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in BareMetalServerNetworkInterfaceByVLAN JSON')
        if (port_speed := _dict.get('port_speed')) is not None:
            args['port_speed'] = port_speed
        else:
            raise ValueError('Required property \'port_speed\' not present in BareMetalServerNetworkInterfaceByVLAN JSON')
        if (primary_ip := _dict.get('primary_ip')) is not None:
            args['primary_ip'] = ReservedIPReference.from_dict(primary_ip)
        else:
            raise ValueError('Required property \'primary_ip\' not present in BareMetalServerNetworkInterfaceByVLAN JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = resource_type
        else:
            raise ValueError('Required property \'resource_type\' not present in BareMetalServerNetworkInterfaceByVLAN JSON')
        if (security_groups := _dict.get('security_groups')) is not None:
            args['security_groups'] = [SecurityGroupReference.from_dict(v) for v in security_groups]
        else:
            raise ValueError('Required property \'security_groups\' not present in BareMetalServerNetworkInterfaceByVLAN JSON')
        if (status := _dict.get('status')) is not None:
            args['status'] = status
        else:
            raise ValueError('Required property \'status\' not present in BareMetalServerNetworkInterfaceByVLAN JSON')
        if (subnet := _dict.get('subnet')) is not None:
            args['subnet'] = SubnetReference.from_dict(subnet)
        else:
            raise ValueError('Required property \'subnet\' not present in BareMetalServerNetworkInterfaceByVLAN JSON')
        if (type := _dict.get('type')) is not None:
            args['type'] = type
        else:
            raise ValueError('Required property \'type\' not present in BareMetalServerNetworkInterfaceByVLAN JSON')
        if (allow_interface_to_float := _dict.get('allow_interface_to_float')) is not None:
            args['allow_interface_to_float'] = allow_interface_to_float
        else:
            raise ValueError('Required property \'allow_interface_to_float\' not present in BareMetalServerNetworkInterfaceByVLAN JSON')
        if (interface_type := _dict.get('interface_type')) is not None:
            args['interface_type'] = interface_type
        else:
            raise ValueError('Required property \'interface_type\' not present in BareMetalServerNetworkInterfaceByVLAN JSON')
        if (vlan := _dict.get('vlan')) is not None:
            args['vlan'] = 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.
        If this bare metal server has network attachments, this network interface is a
        read-only representation of its corresponding network attachment and its attached
        virtual network interface, and the status is [computed from
        them](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients).
        """

        AVAILABLE = 'available'
        DELETING = 'deleting'
        FAILED = 'failed'
        PENDING = 'pending'


    class TypeEnum(str, Enum):
        """
        The bare metal server network interface type.
        If this bare metal server has network attachments, this network interface is a
        [read-only
        representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
        of its corresponding network attachment and its attached virtual network
        interface, and the type is that of its corresponding network attachment.
        """

        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.

    :param bool allow_ip_spoofing: (optional) Indicates whether source IP spoofing
          is allowed on this bare metal server network interface.
          If this bare metal server has network attachments, this network interface is a
          [read-only
          representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
          of its corresponding network attachment and its attached virtual network
          interface, and source IP spoofing is managed on the attached virtual 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`.
          If this bare metal server has network attachments, this network interface is a
          [read-only
          representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
          of its corresponding network attachment and its attached virtual network
          interface, and infrastructure NAT is managed on the attached virtual network
          interface.
    :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 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`.
    """

    def __init__(
        self,
        subnet: 'SubnetIdentity',
        interface_type: str,
        *,
        allow_ip_spoofing: Optional[bool] = None,
        enable_infrastructure_nat: Optional[bool] = None,
        name: Optional[str] = None,
        primary_ip: Optional['NetworkInterfaceIPPrototype'] = None,
        security_groups: Optional[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.
               If this bare metal server has network attachments, this network interface
               is a
               [read-only
               representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
               of its corresponding network attachment and its attached virtual network
               interface, and source IP spoofing is managed on the attached virtual
               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`.
               If this bare metal server has network attachments, this network interface
               is a
               [read-only
               representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
               of its corresponding network attachment and its attached virtual network
               interface, and infrastructure NAT is managed on the attached virtual
               network interface.
        :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 := _dict.get('allow_ip_spoofing')) is not None:
            args['allow_ip_spoofing'] = allow_ip_spoofing
        if (enable_infrastructure_nat := _dict.get('enable_infrastructure_nat')) is not None:
            args['enable_infrastructure_nat'] = enable_infrastructure_nat
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        if (primary_ip := _dict.get('primary_ip')) is not None:
            args['primary_ip'] = primary_ip
        if (security_groups := _dict.get('security_groups')) is not None:
            args['security_groups'] = security_groups
        if (subnet := _dict.get('subnet')) is not None:
            args['subnet'] = subnet
        else:
            raise ValueError('Required property \'subnet\' not present in BareMetalServerNetworkInterfacePrototypeBareMetalServerNetworkInterfaceByHiperSocketPrototype JSON')
        if (interface_type := _dict.get('interface_type')) is not None:
            args['interface_type'] = 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.

    :param bool allow_ip_spoofing: (optional) Indicates whether source IP spoofing
          is allowed on this bare metal server network interface.
          If this bare metal server has network attachments, this network interface is a
          [read-only
          representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
          of its corresponding network attachment and its attached virtual network
          interface, and source IP spoofing is managed on the attached virtual 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`.
          If this bare metal server has network attachments, this network interface is a
          [read-only
          representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
          of its corresponding network attachment and its attached virtual network
          interface, and infrastructure NAT is managed on the attached virtual network
          interface.
    :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 SubnetIdentity subnet: The associated subnet.
    :param List[int] allowed_vlans: (optional) The VLAN IDs to allow 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.
            - Not supported on bare metal servers with a `cpu.architecture` of `s390x`.
    """

    def __init__(
        self,
        subnet: 'SubnetIdentity',
        interface_type: str,
        *,
        allow_ip_spoofing: Optional[bool] = None,
        enable_infrastructure_nat: Optional[bool] = None,
        name: Optional[str] = None,
        primary_ip: Optional['NetworkInterfaceIPPrototype'] = None,
        security_groups: Optional[List['SecurityGroupIdentity']] = None,
        allowed_vlans: Optional[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.
               If this bare metal server has network attachments, this network interface
               is a
               [read-only
               representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
               of its corresponding network attachment and its attached virtual network
               interface, and source IP spoofing is managed on the attached virtual
               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`.
               If this bare metal server has network attachments, this network interface
               is a
               [read-only
               representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
               of its corresponding network attachment and its attached virtual network
               interface, and infrastructure NAT is managed on the attached virtual
               network interface.
        :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 := _dict.get('allow_ip_spoofing')) is not None:
            args['allow_ip_spoofing'] = allow_ip_spoofing
        if (enable_infrastructure_nat := _dict.get('enable_infrastructure_nat')) is not None:
            args['enable_infrastructure_nat'] = enable_infrastructure_nat
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        if (primary_ip := _dict.get('primary_ip')) is not None:
            args['primary_ip'] = primary_ip
        if (security_groups := _dict.get('security_groups')) is not None:
            args['security_groups'] = security_groups
        if (subnet := _dict.get('subnet')) is not None:
            args['subnet'] = subnet
        else:
            raise ValueError('Required property \'subnet\' not present in BareMetalServerNetworkInterfacePrototypeBareMetalServerNetworkInterfaceByPCIPrototype JSON')
        if (allowed_vlans := _dict.get('allowed_vlans')) is not None:
            args['allowed_vlans'] = allowed_vlans
        if (interface_type := _dict.get('interface_type')) is not None:
            args['interface_type'] = 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.

    :param bool allow_ip_spoofing: (optional) Indicates whether source IP spoofing
          is allowed on this bare metal server network interface.
          If this bare metal server has network attachments, this network interface is a
          [read-only
          representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
          of its corresponding network attachment and its attached virtual network
          interface, and source IP spoofing is managed on the attached virtual 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`.
          If this bare metal server has network attachments, this network interface is a
          [read-only
          representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
          of its corresponding network attachment and its attached virtual network
          interface, and infrastructure NAT is managed on the attached virtual network
          interface.
    :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 SubnetIdentity subnet: The associated subnet.
    :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`.
          If this bare metal server has network attachments, this network interface is a
          [read-only
          representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
          of its corresponding network attachment and its attached virtual network
          interface, and the value of this property matches that of the `allow_to_float`
          property of the corresponding network attachment.
    :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.
          If this bare metal server has network attachments, this network interface is a
          [read-only
          representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
          of its corresponding network attachment and its attached virtual network
          interface, and the VLAN ID matches the `vlan` of the corresponding network
          attachment.
    """

    def __init__(
        self,
        subnet: 'SubnetIdentity',
        interface_type: str,
        vlan: int,
        *,
        allow_ip_spoofing: Optional[bool] = None,
        enable_infrastructure_nat: Optional[bool] = None,
        name: Optional[str] = None,
        primary_ip: Optional['NetworkInterfaceIPPrototype'] = None,
        security_groups: Optional[List['SecurityGroupIdentity']] = None,
        allow_interface_to_float: Optional[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.
               If this bare metal server has network attachments, this network interface
               is a
               [read-only
               representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
               of its corresponding network attachment and its attached virtual network
               interface, and the VLAN ID matches the `vlan` of the corresponding network
               attachment.
        :param bool allow_ip_spoofing: (optional) Indicates whether source IP
               spoofing is allowed on this bare metal server network interface.
               If this bare metal server has network attachments, this network interface
               is a
               [read-only
               representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
               of its corresponding network attachment and its attached virtual network
               interface, and source IP spoofing is managed on the attached virtual
               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`.
               If this bare metal server has network attachments, this network interface
               is a
               [read-only
               representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
               of its corresponding network attachment and its attached virtual network
               interface, and infrastructure NAT is managed on the attached virtual
               network interface.
        :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`.
               If this bare metal server has network attachments, this network interface
               is a
               [read-only
               representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
               of its corresponding network attachment and its attached virtual network
               interface, and the value of this property matches that of the
               `allow_to_float` property of the corresponding network attachment.
        """
        # 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 := _dict.get('allow_ip_spoofing')) is not None:
            args['allow_ip_spoofing'] = allow_ip_spoofing
        if (enable_infrastructure_nat := _dict.get('enable_infrastructure_nat')) is not None:
            args['enable_infrastructure_nat'] = enable_infrastructure_nat
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        if (primary_ip := _dict.get('primary_ip')) is not None:
            args['primary_ip'] = primary_ip
        if (security_groups := _dict.get('security_groups')) is not None:
            args['security_groups'] = security_groups
        if (subnet := _dict.get('subnet')) is not None:
            args['subnet'] = subnet
        else:
            raise ValueError('Required property \'subnet\' not present in BareMetalServerNetworkInterfacePrototypeBareMetalServerNetworkInterfaceByVLANPrototype JSON')
        if (allow_interface_to_float := _dict.get('allow_interface_to_float')) is not None:
            args['allow_interface_to_float'] = allow_interface_to_float
        if (interface_type := _dict.get('interface_type')) is not None:
            args['interface_type'] = interface_type
        else:
            raise ValueError('Required property \'interface_type\' not present in BareMetalServerNetworkInterfacePrototypeBareMetalServerNetworkInterfaceByVLANPrototype JSON')
        if (vlan := _dict.get('vlan')) is not None:
            args['vlan'] = 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 BareMetalServerPrimaryNetworkAttachmentPrototypeBareMetalServerPrimaryNetworkAttachmentByPCIPrototype(BareMetalServerPrimaryNetworkAttachmentPrototype):
    """
    BareMetalServerPrimaryNetworkAttachmentPrototypeBareMetalServerPrimaryNetworkAttachmentByPCIPrototype.

    :param str name: (optional) The name for this bare metal server network
          attachment. Names must be unique within the bare metal server the network
          attachment resides in. If unspecified, the name will be a hyphenated list of
          randomly-selected words.
    :param BareMetalServerNetworkAttachmentPrototypeVirtualNetworkInterface
          virtual_network_interface:
    :param List[int] allowed_vlans: (optional) The VLAN IDs to allow for `vlan`
          attachments using this PCI attachment.
    :param str interface_type: (optional) - `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 attachment
            - Cannot directly use an IEEE 802.1Q tag.
            - Not supported on bare metal servers with a `cpu.architecture` of `s390x`.
    """

    def __init__(
        self,
        virtual_network_interface: 'BareMetalServerNetworkAttachmentPrototypeVirtualNetworkInterface',
        *,
        name: Optional[str] = None,
        allowed_vlans: Optional[List[int]] = None,
        interface_type: Optional[str] = None,
    ) -> None:
        """
        Initialize a BareMetalServerPrimaryNetworkAttachmentPrototypeBareMetalServerPrimaryNetworkAttachmentByPCIPrototype object.

        :param BareMetalServerNetworkAttachmentPrototypeVirtualNetworkInterface
               virtual_network_interface:
        :param str name: (optional) The name for this bare metal server network
               attachment. Names must be unique within the bare metal server the network
               attachment resides in. If unspecified, the name will be a hyphenated list
               of randomly-selected words.
        :param List[int] allowed_vlans: (optional) The VLAN IDs to allow for `vlan`
               attachments using this PCI attachment.
        :param str interface_type: (optional) - `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 attachment
                 - Cannot directly use an IEEE 802.1Q tag.
                 - Not supported on bare metal servers with a `cpu.architecture` of
               `s390x`.
        """
        # pylint: disable=super-init-not-called
        self.name = name
        self.virtual_network_interface = virtual_network_interface
        self.allowed_vlans = allowed_vlans
        self.interface_type = interface_type

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

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

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

    def __ne__(self, other: 'BareMetalServerPrimaryNetworkAttachmentPrototypeBareMetalServerPrimaryNetworkAttachmentByPCIPrototype') -> 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 attachment
          - Cannot directly use an IEEE 802.1Q tag.
          - Not supported on bare metal servers with a `cpu.architecture` of `s390x`.
        """

        PCI = 'pci'



class BareMetalServerProfileBandwidthDependent(BareMetalServerProfileBandwidth):
    """
    The total bandwidth shared across the bare metal server network attachments or bare
    metal server network interfaces of a bare metal server with this profile depends on
    its configuration.

    :param 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 := _dict.get('type')) is not None:
            args['type'] = 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 attachments or bare metal server network interfaces of a bare
    metal server with this profile.

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

    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 := _dict.get('default')) is not None:
            args['default'] = default
        else:
            raise ValueError('Required property \'default\' not present in BareMetalServerProfileBandwidthEnum JSON')
        if (type := _dict.get('type')) is not None:
            args['type'] = type
        else:
            raise ValueError('Required property \'type\' not present in BareMetalServerProfileBandwidthEnum JSON')
        if (values := _dict.get('values')) is not None:
            args['values'] = 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 attachments or bare metal server network interfaces of a bare metal server
    with this profile.

    :param str type: The type for this profile field.
    :param 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 := _dict.get('type')) is not None:
            args['type'] = type
        else:
            raise ValueError('Required property \'type\' not present in BareMetalServerProfileBandwidthFixed JSON')
        if (value := _dict.get('value')) is not None:
            args['value'] = 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 network
    attachments or network interfaces of a bare metal server with this profile.

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

    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 := _dict.get('default')) is not None:
            args['default'] = default
        else:
            raise ValueError('Required property \'default\' not present in BareMetalServerProfileBandwidthRange JSON')
        if (max := _dict.get('max')) is not None:
            args['max'] = max
        else:
            raise ValueError('Required property \'max\' not present in BareMetalServerProfileBandwidthRange JSON')
        if (min := _dict.get('min')) is not None:
            args['min'] = min
        else:
            raise ValueError('Required property \'min\' not present in BareMetalServerProfileBandwidthRange JSON')
        if (step := _dict.get('step')) is not None:
            args['step'] = step
        else:
            raise ValueError('Required property \'step\' not present in BareMetalServerProfileBandwidthRange JSON')
        if (type := _dict.get('type')) is not None:
            args['type'] = 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.

    :param 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 := _dict.get('type')) is not None:
            args['type'] = 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.

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

    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 := _dict.get('default')) is not None:
            args['default'] = default
        else:
            raise ValueError('Required property \'default\' not present in BareMetalServerProfileCPUCoreCountEnum JSON')
        if (type := _dict.get('type')) is not None:
            args['type'] = type
        else:
            raise ValueError('Required property \'type\' not present in BareMetalServerProfileCPUCoreCountEnum JSON')
        if (values := _dict.get('values')) is not None:
            args['values'] = 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.

    :param str type: The type for this profile field.
    :param 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 := _dict.get('type')) is not None:
            args['type'] = type
        else:
            raise ValueError('Required property \'type\' not present in BareMetalServerProfileCPUCoreCountFixed JSON')
        if (value := _dict.get('value')) is not None:
            args['value'] = 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.

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

    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 := _dict.get('default')) is not None:
            args['default'] = default
        else:
            raise ValueError('Required property \'default\' not present in BareMetalServerProfileCPUCoreCountRange JSON')
        if (max := _dict.get('max')) is not None:
            args['max'] = max
        else:
            raise ValueError('Required property \'max\' not present in BareMetalServerProfileCPUCoreCountRange JSON')
        if (min := _dict.get('min')) is not None:
            args['min'] = min
        else:
            raise ValueError('Required property \'min\' not present in BareMetalServerProfileCPUCoreCountRange JSON')
        if (step := _dict.get('step')) is not None:
            args['step'] = step
        else:
            raise ValueError('Required property \'step\' not present in BareMetalServerProfileCPUCoreCountRange JSON')
        if (type := _dict.get('type')) is not None:
            args['type'] = 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.

    :param 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 := _dict.get('type')) is not None:
            args['type'] = 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.

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

    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 := _dict.get('default')) is not None:
            args['default'] = default
        else:
            raise ValueError('Required property \'default\' not present in BareMetalServerProfileCPUSocketCountEnum JSON')
        if (type := _dict.get('type')) is not None:
            args['type'] = type
        else:
            raise ValueError('Required property \'type\' not present in BareMetalServerProfileCPUSocketCountEnum JSON')
        if (values := _dict.get('values')) is not None:
            args['values'] = 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.

    :param str type: The type for this profile field.
    :param 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 := _dict.get('type')) is not None:
            args['type'] = type
        else:
            raise ValueError('Required property \'type\' not present in BareMetalServerProfileCPUSocketCountFixed JSON')
        if (value := _dict.get('value')) is not None:
            args['value'] = 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.

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

    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 := _dict.get('default')) is not None:
            args['default'] = default
        else:
            raise ValueError('Required property \'default\' not present in BareMetalServerProfileCPUSocketCountRange JSON')
        if (max := _dict.get('max')) is not None:
            args['max'] = max
        else:
            raise ValueError('Required property \'max\' not present in BareMetalServerProfileCPUSocketCountRange JSON')
        if (min := _dict.get('min')) is not None:
            args['min'] = min
        else:
            raise ValueError('Required property \'min\' not present in BareMetalServerProfileCPUSocketCountRange JSON')
        if (step := _dict.get('step')) is not None:
            args['step'] = step
        else:
            raise ValueError('Required property \'step\' not present in BareMetalServerProfileCPUSocketCountRange JSON')
        if (type := _dict.get('type')) is not None:
            args['type'] = 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.

    :param 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 := _dict.get('type')) is not None:
            args['type'] = 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.

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

    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 := _dict.get('default')) is not None:
            args['default'] = default
        else:
            raise ValueError('Required property \'default\' not present in BareMetalServerProfileDiskQuantityEnum JSON')
        if (type := _dict.get('type')) is not None:
            args['type'] = type
        else:
            raise ValueError('Required property \'type\' not present in BareMetalServerProfileDiskQuantityEnum JSON')
        if (values := _dict.get('values')) is not None:
            args['values'] = 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.

    :param str type: The type for this profile field.
    :param 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 := _dict.get('type')) is not None:
            args['type'] = type
        else:
            raise ValueError('Required property \'type\' not present in BareMetalServerProfileDiskQuantityFixed JSON')
        if (value := _dict.get('value')) is not None:
            args['value'] = 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.

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

    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 := _dict.get('default')) is not None:
            args['default'] = default
        else:
            raise ValueError('Required property \'default\' not present in BareMetalServerProfileDiskQuantityRange JSON')
        if (max := _dict.get('max')) is not None:
            args['max'] = max
        else:
            raise ValueError('Required property \'max\' not present in BareMetalServerProfileDiskQuantityRange JSON')
        if (min := _dict.get('min')) is not None:
            args['min'] = min
        else:
            raise ValueError('Required property \'min\' not present in BareMetalServerProfileDiskQuantityRange JSON')
        if (step := _dict.get('step')) is not None:
            args['step'] = step
        else:
            raise ValueError('Required property \'step\' not present in BareMetalServerProfileDiskQuantityRange JSON')
        if (type := _dict.get('type')) is not None:
            args['type'] = 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.

    :param 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 := _dict.get('type')) is not None:
            args['type'] = 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.

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

    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 := _dict.get('default')) is not None:
            args['default'] = default
        else:
            raise ValueError('Required property \'default\' not present in BareMetalServerProfileDiskSizeEnum JSON')
        if (type := _dict.get('type')) is not None:
            args['type'] = type
        else:
            raise ValueError('Required property \'type\' not present in BareMetalServerProfileDiskSizeEnum JSON')
        if (values := _dict.get('values')) is not None:
            args['values'] = 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).

    :param str type: The type for this profile field.
    :param 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 := _dict.get('type')) is not None:
            args['type'] = type
        else:
            raise ValueError('Required property \'type\' not present in BareMetalServerProfileDiskSizeFixed JSON')
        if (value := _dict.get('value')) is not None:
            args['value'] = 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.

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

    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 := _dict.get('default')) is not None:
            args['default'] = default
        else:
            raise ValueError('Required property \'default\' not present in BareMetalServerProfileDiskSizeRange JSON')
        if (max := _dict.get('max')) is not None:
            args['max'] = max
        else:
            raise ValueError('Required property \'max\' not present in BareMetalServerProfileDiskSizeRange JSON')
        if (min := _dict.get('min')) is not None:
            args['min'] = min
        else:
            raise ValueError('Required property \'min\' not present in BareMetalServerProfileDiskSizeRange JSON')
        if (step := _dict.get('step')) is not None:
            args['step'] = step
        else:
            raise ValueError('Required property \'step\' not present in BareMetalServerProfileDiskSizeRange JSON')
        if (type := _dict.get('type')) is not None:
            args['type'] = 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.

    :param 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 := _dict.get('href')) is not None:
            args['href'] = 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.

    :param 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 := _dict.get('name')) is not None:
            args['name'] = 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.

    :param 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 := _dict.get('type')) is not None:
            args['type'] = 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.

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

    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 := _dict.get('default')) is not None:
            args['default'] = default
        else:
            raise ValueError('Required property \'default\' not present in BareMetalServerProfileMemoryEnum JSON')
        if (type := _dict.get('type')) is not None:
            args['type'] = type
        else:
            raise ValueError('Required property \'type\' not present in BareMetalServerProfileMemoryEnum JSON')
        if (values := _dict.get('values')) is not None:
            args['values'] = 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.

    :param str type: The type for this profile field.
    :param 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 := _dict.get('type')) is not None:
            args['type'] = type
        else:
            raise ValueError('Required property \'type\' not present in BareMetalServerProfileMemoryFixed JSON')
        if (value := _dict.get('value')) is not None:
            args['value'] = 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.

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

    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 := _dict.get('default')) is not None:
            args['default'] = default
        else:
            raise ValueError('Required property \'default\' not present in BareMetalServerProfileMemoryRange JSON')
        if (max := _dict.get('max')) is not None:
            args['max'] = max
        else:
            raise ValueError('Required property \'max\' not present in BareMetalServerProfileMemoryRange JSON')
        if (min := _dict.get('min')) is not None:
            args['min'] = min
        else:
            raise ValueError('Required property \'min\' not present in BareMetalServerProfileMemoryRange JSON')
        if (step := _dict.get('step')) is not None:
            args['step'] = step
        else:
            raise ValueError('Required property \'step\' not present in BareMetalServerProfileMemoryRange JSON')
        if (type := _dict.get('type')) is not None:
            args['type'] = 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 BareMetalServerProfileNetworkAttachmentCountDependent(BareMetalServerProfileNetworkAttachmentCount):
    """
    The number of network attachments supported on a bare metal server with this profile
    is dependent on its configuration.

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

    def __init__(
        self,
        type: str,
    ) -> None:
        """
        Initialize a BareMetalServerProfileNetworkAttachmentCountDependent 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) -> 'BareMetalServerProfileNetworkAttachmentCountDependent':
        """Initialize a BareMetalServerProfileNetworkAttachmentCountDependent object from a json dictionary."""
        args = {}
        if (type := _dict.get('type')) is not None:
            args['type'] = type
        else:
            raise ValueError('Required property \'type\' not present in BareMetalServerProfileNetworkAttachmentCountDependent JSON')
        return cls(**args)

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

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

    def __ne__(self, other: 'BareMetalServerProfileNetworkAttachmentCountDependent') -> 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 BareMetalServerProfileNetworkAttachmentCountRange(BareMetalServerProfileNetworkAttachmentCount):
    """
    The number of network attachments supported on a bare metal server with this profile.

    :param int max: (optional) The maximum value for this profile field.
    :param int min: (optional) The minimum value for this profile field.
    :param str type: The type for this profile field.
    """

    def __init__(
        self,
        type: str,
        *,
        max: Optional[int] = None,
        min: Optional[int] = None,
    ) -> None:
        """
        Initialize a BareMetalServerProfileNetworkAttachmentCountRange 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) -> 'BareMetalServerProfileNetworkAttachmentCountRange':
        """Initialize a BareMetalServerProfileNetworkAttachmentCountRange object from a json dictionary."""
        args = {}
        if (max := _dict.get('max')) is not None:
            args['max'] = max
        if (min := _dict.get('min')) is not None:
            args['min'] = min
        if (type := _dict.get('type')) is not None:
            args['type'] = type
        else:
            raise ValueError('Required property \'type\' not present in BareMetalServerProfileNetworkAttachmentCountRange JSON')
        return cls(**args)

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

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

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

    :param 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 := _dict.get('type')) is not None:
            args['type'] = 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.

    :param int max: (optional) The maximum value for this profile field.
    :param int min: (optional) The minimum value for this profile field.
    :param str type: The type for this profile field.
    """

    def __init__(
        self,
        type: str,
        *,
        max: Optional[int] = None,
        min: Optional[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 := _dict.get('max')) is not None:
            args['max'] = max
        if (min := _dict.get('min')) is not None:
            args['min'] = min
        if (type := _dict.get('type')) is not None:
            args['type'] = 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 BareMetalServerPrototypeBareMetalServerByNetworkAttachment(BareMetalServerPrototype):
    """
    BareMetalServerPrototypeBareMetalServerByNetworkAttachment.

    :param int bandwidth: (optional) The total bandwidth (in megabits per second)
          shared across the bare metal server's network interfaces. The specified value
          must match one of the bandwidth values in the bare metal server's profile. If
          unspecified, the default value from the profile will be used.
    :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 BareMetalServerInitializationPrototype initialization:
    :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 BareMetalServerProfileIdentity profile: The
          [profile](https://cloud.ibm.com/docs/vpc?topic=vpc-bare-metal-servers-profile)
          to use for this bare metal server.
    :param ResourceGroupIdentity resource_group: (optional)
    :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 attachments
          or network interfaces of the bare metal server are attached to.
    :param ZoneIdentity zone: The zone this bare metal server will reside in.
    :param List[BareMetalServerNetworkAttachmentPrototype] network_attachments:
          (optional) The additional network attachments to create for the bare metal
          server.
    :param BareMetalServerPrimaryNetworkAttachmentPrototype
          primary_network_attachment: The primary network attachment to create for the
          bare metal server.
    """

    def __init__(
        self,
        initialization: 'BareMetalServerInitializationPrototype',
        profile: 'BareMetalServerProfileIdentity',
        zone: 'ZoneIdentity',
        primary_network_attachment: 'BareMetalServerPrimaryNetworkAttachmentPrototype',
        *,
        bandwidth: Optional[int] = None,
        enable_secure_boot: Optional[bool] = None,
        name: Optional[str] = None,
        resource_group: Optional['ResourceGroupIdentity'] = None,
        trusted_platform_module: Optional['BareMetalServerTrustedPlatformModulePrototype'] = None,
        vpc: Optional['VPCIdentity'] = None,
        network_attachments: Optional[List['BareMetalServerNetworkAttachmentPrototype']] = None,
    ) -> None:
        """
        Initialize a BareMetalServerPrototypeBareMetalServerByNetworkAttachment object.

        :param BareMetalServerInitializationPrototype initialization:
        :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 BareMetalServerPrimaryNetworkAttachmentPrototype
               primary_network_attachment: The primary network attachment to create for
               the bare metal server.
        :param int bandwidth: (optional) The total bandwidth (in megabits per
               second) shared across the bare metal server's network interfaces. The
               specified value must match one of the bandwidth values in the bare metal
               server's profile. If unspecified, the default value from the profile will
               be used.
        :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 ResourceGroupIdentity resource_group: (optional)
        :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
               attachments or network interfaces of the bare metal server are attached to.
        :param List[BareMetalServerNetworkAttachmentPrototype] network_attachments:
               (optional) The additional network attachments to create for the bare metal
               server.
        """
        # pylint: disable=super-init-not-called
        self.bandwidth = bandwidth
        self.enable_secure_boot = enable_secure_boot
        self.initialization = initialization
        self.name = name
        self.profile = profile
        self.resource_group = resource_group
        self.trusted_platform_module = trusted_platform_module
        self.vpc = vpc
        self.zone = zone
        self.network_attachments = network_attachments
        self.primary_network_attachment = primary_network_attachment

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'BareMetalServerPrototypeBareMetalServerByNetworkAttachment':
        """Initialize a BareMetalServerPrototypeBareMetalServerByNetworkAttachment object from a json dictionary."""
        args = {}
        if (bandwidth := _dict.get('bandwidth')) is not None:
            args['bandwidth'] = bandwidth
        if (enable_secure_boot := _dict.get('enable_secure_boot')) is not None:
            args['enable_secure_boot'] = enable_secure_boot
        if (initialization := _dict.get('initialization')) is not None:
            args['initialization'] = BareMetalServerInitializationPrototype.from_dict(initialization)
        else:
            raise ValueError('Required property \'initialization\' not present in BareMetalServerPrototypeBareMetalServerByNetworkAttachment JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        if (profile := _dict.get('profile')) is not None:
            args['profile'] = profile
        else:
            raise ValueError('Required property \'profile\' not present in BareMetalServerPrototypeBareMetalServerByNetworkAttachment JSON')
        if (resource_group := _dict.get('resource_group')) is not None:
            args['resource_group'] = resource_group
        if (trusted_platform_module := _dict.get('trusted_platform_module')) is not None:
            args['trusted_platform_module'] = BareMetalServerTrustedPlatformModulePrototype.from_dict(trusted_platform_module)
        if (vpc := _dict.get('vpc')) is not None:
            args['vpc'] = vpc
        if (zone := _dict.get('zone')) is not None:
            args['zone'] = zone
        else:
            raise ValueError('Required property \'zone\' not present in BareMetalServerPrototypeBareMetalServerByNetworkAttachment JSON')
        if (network_attachments := _dict.get('network_attachments')) is not None:
            args['network_attachments'] = network_attachments
        if (primary_network_attachment := _dict.get('primary_network_attachment')) is not None:
            args['primary_network_attachment'] = primary_network_attachment
        else:
            raise ValueError('Required property \'primary_network_attachment\' not present in BareMetalServerPrototypeBareMetalServerByNetworkAttachment JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a BareMetalServerPrototypeBareMetalServerByNetworkAttachment object from 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, 'enable_secure_boot') and self.enable_secure_boot is not None:
            _dict['enable_secure_boot'] = self.enable_secure_boot
        if hasattr(self, 'initialization') and self.initialization is not None:
            if isinstance(self.initialization, dict):
                _dict['initialization'] = self.initialization
            else:
                _dict['initialization'] = self.initialization.to_dict()
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'profile') and self.profile is not None:
            if isinstance(self.profile, dict):
                _dict['profile'] = self.profile
            else:
                _dict['profile'] = self.profile.to_dict()
        if hasattr(self, '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, '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()
        if hasattr(self, 'network_attachments') and self.network_attachments is not None:
            network_attachments_list = []
            for v in self.network_attachments:
                if isinstance(v, dict):
                    network_attachments_list.append(v)
                else:
                    network_attachments_list.append(v.to_dict())
            _dict['network_attachments'] = network_attachments_list
        if hasattr(self, 'primary_network_attachment') and self.primary_network_attachment is not None:
            if isinstance(self.primary_network_attachment, dict):
                _dict['primary_network_attachment'] = self.primary_network_attachment
            else:
                _dict['primary_network_attachment'] = self.primary_network_attachment.to_dict()
        return _dict

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

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

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

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


class BareMetalServerPrototypeBareMetalServerByNetworkInterface(BareMetalServerPrototype):
    """
    BareMetalServerPrototypeBareMetalServerByNetworkInterface.

    :param int bandwidth: (optional) The total bandwidth (in megabits per second)
          shared across the bare metal server's network interfaces. The specified value
          must match one of the bandwidth values in the bare metal server's profile. If
          unspecified, the default value from the profile will be used.
    :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 BareMetalServerInitializationPrototype initialization:
    :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 BareMetalServerProfileIdentity profile: The
          [profile](https://cloud.ibm.com/docs/vpc?topic=vpc-bare-metal-servers-profile)
          to use for this bare metal server.
    :param ResourceGroupIdentity resource_group: (optional)
    :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 attachments
          or network interfaces of the bare metal server are attached to.
    :param ZoneIdentity zone: The zone this bare metal server will reside in.
    :param List[BareMetalServerNetworkInterfacePrototype] network_interfaces:
          (optional) The additional bare metal server network interfaces to create.
    :param BareMetalServerPrimaryNetworkInterfacePrototype
          primary_network_interface: The primary bare metal server network interface to
          create.
    """

    def __init__(
        self,
        initialization: 'BareMetalServerInitializationPrototype',
        profile: 'BareMetalServerProfileIdentity',
        zone: 'ZoneIdentity',
        primary_network_interface: 'BareMetalServerPrimaryNetworkInterfacePrototype',
        *,
        bandwidth: Optional[int] = None,
        enable_secure_boot: Optional[bool] = None,
        name: Optional[str] = None,
        resource_group: Optional['ResourceGroupIdentity'] = None,
        trusted_platform_module: Optional['BareMetalServerTrustedPlatformModulePrototype'] = None,
        vpc: Optional['VPCIdentity'] = None,
        network_interfaces: Optional[List['BareMetalServerNetworkInterfacePrototype']] = None,
    ) -> None:
        """
        Initialize a BareMetalServerPrototypeBareMetalServerByNetworkInterface object.

        :param BareMetalServerInitializationPrototype initialization:
        :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 BareMetalServerPrimaryNetworkInterfacePrototype
               primary_network_interface: The primary bare metal server network interface
               to create.
        :param int bandwidth: (optional) The total bandwidth (in megabits per
               second) shared across the bare metal server's network interfaces. The
               specified value must match one of the bandwidth values in the bare metal
               server's profile. If unspecified, the default value from the profile will
               be used.
        :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 ResourceGroupIdentity resource_group: (optional)
        :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
               attachments or network interfaces of the bare metal server are attached to.
        :param List[BareMetalServerNetworkInterfacePrototype] network_interfaces:
               (optional) The additional bare metal server network interfaces to create.
        """
        # pylint: disable=super-init-not-called
        self.bandwidth = bandwidth
        self.enable_secure_boot = enable_secure_boot
        self.initialization = initialization
        self.name = name
        self.profile = profile
        self.resource_group = resource_group
        self.trusted_platform_module = trusted_platform_module
        self.vpc = vpc
        self.zone = zone
        self.network_interfaces = network_interfaces
        self.primary_network_interface = primary_network_interface

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'BareMetalServerPrototypeBareMetalServerByNetworkInterface':
        """Initialize a BareMetalServerPrototypeBareMetalServerByNetworkInterface object from a json dictionary."""
        args = {}
        if (bandwidth := _dict.get('bandwidth')) is not None:
            args['bandwidth'] = bandwidth
        if (enable_secure_boot := _dict.get('enable_secure_boot')) is not None:
            args['enable_secure_boot'] = enable_secure_boot
        if (initialization := _dict.get('initialization')) is not None:
            args['initialization'] = BareMetalServerInitializationPrototype.from_dict(initialization)
        else:
            raise ValueError('Required property \'initialization\' not present in BareMetalServerPrototypeBareMetalServerByNetworkInterface JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        if (profile := _dict.get('profile')) is not None:
            args['profile'] = profile
        else:
            raise ValueError('Required property \'profile\' not present in BareMetalServerPrototypeBareMetalServerByNetworkInterface JSON')
        if (resource_group := _dict.get('resource_group')) is not None:
            args['resource_group'] = resource_group
        if (trusted_platform_module := _dict.get('trusted_platform_module')) is not None:
            args['trusted_platform_module'] = BareMetalServerTrustedPlatformModulePrototype.from_dict(trusted_platform_module)
        if (vpc := _dict.get('vpc')) is not None:
            args['vpc'] = vpc
        if (zone := _dict.get('zone')) is not None:
            args['zone'] = zone
        else:
            raise ValueError('Required property \'zone\' not present in BareMetalServerPrototypeBareMetalServerByNetworkInterface JSON')
        if (network_interfaces := _dict.get('network_interfaces')) is not None:
            args['network_interfaces'] = [BareMetalServerNetworkInterfacePrototype.from_dict(v) for v in network_interfaces]
        if (primary_network_interface := _dict.get('primary_network_interface')) is not None:
            args['primary_network_interface'] = BareMetalServerPrimaryNetworkInterfacePrototype.from_dict(primary_network_interface)
        else:
            raise ValueError('Required property \'primary_network_interface\' not present in BareMetalServerPrototypeBareMetalServerByNetworkInterface JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a BareMetalServerPrototypeBareMetalServerByNetworkInterface object from 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, 'enable_secure_boot') and self.enable_secure_boot is not None:
            _dict['enable_secure_boot'] = self.enable_secure_boot
        if hasattr(self, 'initialization') and self.initialization is not None:
            if isinstance(self.initialization, dict):
                _dict['initialization'] = self.initialization
            else:
                _dict['initialization'] = self.initialization.to_dict()
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'profile') and self.profile is not None:
            if isinstance(self.profile, dict):
                _dict['profile'] = self.profile
            else:
                _dict['profile'] = self.profile.to_dict()
        if hasattr(self, '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, '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()
        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()
        return _dict

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

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

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

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


class CatalogOfferingIdentityCatalogOfferingByCRN(CatalogOfferingIdentity):
    """
    CatalogOfferingIdentityCatalogOfferingByCRN.

    :param 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 := _dict.get('crn')) is not None:
            args['crn'] = 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.

    :param 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 := _dict.get('crn')) is not None:
            args['crn'] = 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 CatalogOfferingVersionPlanIdentityCatalogOfferingVersionPlanByCRN(CatalogOfferingVersionPlanIdentity):
    """
    CatalogOfferingVersionPlanIdentityCatalogOfferingVersionPlanByCRN.

    :param str crn: The CRN for this
          [catalog](https://cloud.ibm.com/docs/account?topic=account-restrict-by-user)
          offering version's billing plan.
    """

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

        :param str crn: The CRN for this
               [catalog](https://cloud.ibm.com/docs/account?topic=account-restrict-by-user)
               offering version's billing plan.
        """
        # pylint: disable=super-init-not-called
        self.crn = crn

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

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

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

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


class CertificateInstanceIdentityByCRN(CertificateInstanceIdentity):
    """
    CertificateInstanceIdentityByCRN.

    :param 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 := _dict.get('crn')) is not None:
            args['crn'] = 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.

    :param 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 := _dict.get('crn')) is not None:
            args['crn'] = 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.

    :param 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 := _dict.get('name')) is not None:
            args['name'] = 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 ClusterNetworkInterfacePrimaryIPPrototypeClusterNetworkSubnetReservedIPIdentityClusterNetworkInterfacePrimaryIPContext(ClusterNetworkInterfacePrimaryIPPrototype):
    """
    Identifies a cluster network subnet reserved IP by a unique property. Required if
    `subnet` is not specified. The cluster network subnet reserved IP must be currently
    unbound.

    """

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

        """
        # pylint: disable=super-init-not-called
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['ClusterNetworkInterfacePrimaryIPPrototypeClusterNetworkSubnetReservedIPIdentityClusterNetworkInterfacePrimaryIPContextById', 'ClusterNetworkInterfacePrimaryIPPrototypeClusterNetworkSubnetReservedIPIdentityClusterNetworkInterfacePrimaryIPContextByHref'])
        )
        raise Exception(msg)


class ClusterNetworkInterfacePrimaryIPPrototypeClusterNetworkSubnetReservedIPPrototypeClusterNetworkInterfacePrimaryIPContext(ClusterNetworkInterfacePrimaryIPPrototype):
    """
    The prototype for a new cluster network subnet reserved IP. Requires `subnet` to be
    specified.

    :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 cluster network
          subnet reserved IP member will be automatically deleted when either `target` is
          deleted, or the cluster network subnet reserved IP is unbound.
    :param str name: (optional) The name for this cluster network subnet reserved
          IP. The name must not be used by another reserved IP in the cluster network
          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: Optional[str] = None,
        auto_delete: Optional[bool] = None,
        name: Optional[str] = None,
    ) -> None:
        """
        Initialize a ClusterNetworkInterfacePrimaryIPPrototypeClusterNetworkSubnetReservedIPPrototypeClusterNetworkInterfacePrimaryIPContext 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 cluster network
               subnet reserved IP member will be automatically deleted when either
               `target` is deleted, or the cluster network subnet reserved IP is unbound.
        :param str name: (optional) The name for this cluster network subnet
               reserved IP. The name must not be used by another reserved IP in the
               cluster network 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) -> 'ClusterNetworkInterfacePrimaryIPPrototypeClusterNetworkSubnetReservedIPPrototypeClusterNetworkInterfacePrimaryIPContext':
        """Initialize a ClusterNetworkInterfacePrimaryIPPrototypeClusterNetworkSubnetReservedIPPrototypeClusterNetworkInterfacePrimaryIPContext object from a json dictionary."""
        args = {}
        if (address := _dict.get('address')) is not None:
            args['address'] = address
        if (auto_delete := _dict.get('auto_delete')) is not None:
            args['auto_delete'] = auto_delete
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        return cls(**args)

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

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

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


class ClusterNetworkInterfaceTargetInstanceClusterNetworkAttachmentReferenceClusterNetworkInterfaceContext(ClusterNetworkInterfaceTarget):
    """
    ClusterNetworkInterfaceTargetInstanceClusterNetworkAttachmentReferenceClusterNetworkInterfaceContext.

    :param str href: The URL for this instance cluster network attachment.
    :param str id: The unique identifier for this instance cluster network
          attachment.
    :param str name: The name for this instance cluster network attachment. The name
          is unique across all network attachments for the instance.
    :param str resource_type: The resource type.
    """

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

        :param str href: The URL for this instance cluster network attachment.
        :param str id: The unique identifier for this instance cluster network
               attachment.
        :param str name: The name for this instance cluster network attachment. The
               name is unique across all network attachments for the instance.
        :param str resource_type: The resource type.
        """
        # pylint: disable=super-init-not-called
        self.href = href
        self.id = id
        self.name = name
        self.resource_type = resource_type

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

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

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

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

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

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

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

    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        INSTANCE_CLUSTER_NETWORK_ATTACHMENT = 'instance_cluster_network_attachment'



class ClusterNetworkProfileIdentityByHref(ClusterNetworkProfileIdentity):
    """
    ClusterNetworkProfileIdentityByHref.

    :param str href: The URL for this cluster network profile.
    """

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

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

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

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

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

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

    def __str__(self) -> str:
        """Return a `str` version of this ClusterNetworkProfileIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ClusterNetworkProfileIdentityByHref') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ClusterNetworkProfileIdentityByHref') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class ClusterNetworkProfileIdentityByName(ClusterNetworkProfileIdentity):
    """
    ClusterNetworkProfileIdentityByName.

    :param str name: The globally unique name for this cluster network profile.
    """

    def __init__(
        self,
        name: str,
    ) -> None:
        """
        Initialize a ClusterNetworkProfileIdentityByName object.

        :param str name: The globally unique name for this cluster network profile.
        """
        # pylint: disable=super-init-not-called
        self.name = name

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ClusterNetworkProfileIdentityByName':
        """Initialize a ClusterNetworkProfileIdentityByName object from a json dictionary."""
        args = {}
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in ClusterNetworkProfileIdentityByName JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ClusterNetworkProfileIdentityByName object from 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 ClusterNetworkProfileIdentityByName object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ClusterNetworkProfileIdentityByName') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ClusterNetworkProfileIdentityByName') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class ClusterNetworkSubnetIdentityByHref(ClusterNetworkSubnetIdentity):
    """
    ClusterNetworkSubnetIdentityByHref.

    :param str href: The URL for this cluster network subnet.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a ClusterNetworkSubnetIdentityByHref object.

        :param str href: The URL for this cluster network subnet.
        """
        # pylint: disable=super-init-not-called
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ClusterNetworkSubnetIdentityByHref':
        """Initialize a ClusterNetworkSubnetIdentityByHref object from a json dictionary."""
        args = {}
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in ClusterNetworkSubnetIdentityByHref JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ClusterNetworkSubnetIdentityByHref object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this ClusterNetworkSubnetIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ClusterNetworkSubnetIdentityByHref') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ClusterNetworkSubnetIdentityByHref') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class ClusterNetworkSubnetIdentityById(ClusterNetworkSubnetIdentity):
    """
    ClusterNetworkSubnetIdentityById.

    :param str id: The unique identifier for this cluster network subnet.
    """

    def __init__(
        self,
        id: str,
    ) -> None:
        """
        Initialize a ClusterNetworkSubnetIdentityById object.

        :param str id: The unique identifier for this cluster network subnet.
        """
        # pylint: disable=super-init-not-called
        self.id = id

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ClusterNetworkSubnetIdentityById':
        """Initialize a ClusterNetworkSubnetIdentityById object from a json dictionary."""
        args = {}
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in ClusterNetworkSubnetIdentityById JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ClusterNetworkSubnetIdentityById object from 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 ClusterNetworkSubnetIdentityById object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ClusterNetworkSubnetIdentityById') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ClusterNetworkSubnetIdentityById') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class ClusterNetworkSubnetPrototypeClusterNetworkSubnetByIPv4CIDRBlockPrototype(ClusterNetworkSubnetPrototype):
    """
    ClusterNetworkSubnetPrototypeClusterNetworkSubnetByIPv4CIDRBlockPrototype.

    :param str ip_version: (optional) The IP version(s) to support for this cluster
          network subnet.
    :param str name: (optional) The name for this cluster network subnet. The name
          must not be used by another cluster network subnet in the cluster network. 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 str ipv4_cidr_block: The IPv4 range of the cluster network subnet,
          expressed in CIDR format. The prefix length of the cluster network subnet's CIDR
          must be between `/8` (16,777,216 addresses) and `/29`
          (8 addresses). The IPv4 range of the cluster network subnet's CIDR must be
          within the cluster network's `subnet_prefixes`.
          The range must not overlap with any of the following reserved address ranges:
            - `127.0.0.0/8` (IPv4 loopback addresses)
            - `169.254.0.0/16` (IPv4 link-local addresses)
            - `224.0.0.0/4` (IPv4 multicast addresses).
    """

    def __init__(
        self,
        ipv4_cidr_block: str,
        *,
        ip_version: Optional[str] = None,
        name: Optional[str] = None,
    ) -> None:
        """
        Initialize a ClusterNetworkSubnetPrototypeClusterNetworkSubnetByIPv4CIDRBlockPrototype object.

        :param str ipv4_cidr_block: The IPv4 range of the cluster network subnet,
               expressed in CIDR format. The prefix length of the cluster network subnet's
               CIDR must be between `/8` (16,777,216 addresses) and `/29`
               (8 addresses). The IPv4 range of the cluster network subnet's CIDR must be
               within the cluster network's `subnet_prefixes`.
               The range must not overlap with any of the following reserved address
               ranges:
                 - `127.0.0.0/8` (IPv4 loopback addresses)
                 - `169.254.0.0/16` (IPv4 link-local addresses)
                 - `224.0.0.0/4` (IPv4 multicast addresses).
        :param str ip_version: (optional) The IP version(s) to support for this
               cluster network subnet.
        :param str name: (optional) The name for this cluster network subnet. The
               name must not be used by another cluster network subnet in the cluster
               network. 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.ip_version = ip_version
        self.name = name
        self.ipv4_cidr_block = ipv4_cidr_block

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ClusterNetworkSubnetPrototypeClusterNetworkSubnetByIPv4CIDRBlockPrototype':
        """Initialize a ClusterNetworkSubnetPrototypeClusterNetworkSubnetByIPv4CIDRBlockPrototype object from a json dictionary."""
        args = {}
        if (ip_version := _dict.get('ip_version')) is not None:
            args['ip_version'] = ip_version
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        if (ipv4_cidr_block := _dict.get('ipv4_cidr_block')) is not None:
            args['ipv4_cidr_block'] = ipv4_cidr_block
        else:
            raise ValueError('Required property \'ipv4_cidr_block\' not present in ClusterNetworkSubnetPrototypeClusterNetworkSubnetByIPv4CIDRBlockPrototype JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ClusterNetworkSubnetPrototypeClusterNetworkSubnetByIPv4CIDRBlockPrototype object from 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, 'ipv4_cidr_block') and self.ipv4_cidr_block is not None:
            _dict['ipv4_cidr_block'] = self.ipv4_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 ClusterNetworkSubnetPrototypeClusterNetworkSubnetByIPv4CIDRBlockPrototype object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ClusterNetworkSubnetPrototypeClusterNetworkSubnetByIPv4CIDRBlockPrototype') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ClusterNetworkSubnetPrototypeClusterNetworkSubnetByIPv4CIDRBlockPrototype') -> 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 cluster network subnet.
        """

        IPV4 = 'ipv4'



class ClusterNetworkSubnetPrototypeClusterNetworkSubnetByTotalCountPrototype(ClusterNetworkSubnetPrototype):
    """
    ClusterNetworkSubnetPrototypeClusterNetworkSubnetByTotalCountPrototype.

    :param str ip_version: (optional) The IP version(s) to support for this cluster
          network subnet.
    :param str name: (optional) The name for this cluster network subnet. The name
          must not be used by another cluster network subnet in the cluster network. 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 int total_ipv4_address_count: The total number of IPv4 addresses
          required. Must be a power of 2.
          A CIDR will be allocated from a subnet prefix in the cluster network that has an
          `allocation_policy` of `auto`. There must be a subnet prefix that has a free
          CIDR range with at least this number of addresses.
    """

    def __init__(
        self,
        total_ipv4_address_count: int,
        *,
        ip_version: Optional[str] = None,
        name: Optional[str] = None,
    ) -> None:
        """
        Initialize a ClusterNetworkSubnetPrototypeClusterNetworkSubnetByTotalCountPrototype object.

        :param int total_ipv4_address_count: The total number of IPv4 addresses
               required. Must be a power of 2.
               A CIDR will be allocated from a subnet prefix in the cluster network that
               has an
               `allocation_policy` of `auto`. There must be a subnet prefix that has a
               free CIDR range with at least this number of addresses.
        :param str ip_version: (optional) The IP version(s) to support for this
               cluster network subnet.
        :param str name: (optional) The name for this cluster network subnet. The
               name must not be used by another cluster network subnet in the cluster
               network. 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.ip_version = ip_version
        self.name = name
        self.total_ipv4_address_count = total_ipv4_address_count

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ClusterNetworkSubnetPrototypeClusterNetworkSubnetByTotalCountPrototype':
        """Initialize a ClusterNetworkSubnetPrototypeClusterNetworkSubnetByTotalCountPrototype object from a json dictionary."""
        args = {}
        if (ip_version := _dict.get('ip_version')) is not None:
            args['ip_version'] = ip_version
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        if (total_ipv4_address_count := _dict.get('total_ipv4_address_count')) is not None:
            args['total_ipv4_address_count'] = total_ipv4_address_count
        else:
            raise ValueError('Required property \'total_ipv4_address_count\' not present in ClusterNetworkSubnetPrototypeClusterNetworkSubnetByTotalCountPrototype JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ClusterNetworkSubnetPrototypeClusterNetworkSubnetByTotalCountPrototype object from 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, 'total_ipv4_address_count') and self.total_ipv4_address_count is not None:
            _dict['total_ipv4_address_count'] = self.total_ipv4_address_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 ClusterNetworkSubnetPrototypeClusterNetworkSubnetByTotalCountPrototype object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ClusterNetworkSubnetPrototypeClusterNetworkSubnetByTotalCountPrototype') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ClusterNetworkSubnetPrototypeClusterNetworkSubnetByTotalCountPrototype') -> 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 cluster network subnet.
        """

        IPV4 = 'ipv4'



class ClusterNetworkSubnetReservedIPTargetClusterNetworkInterfaceReferenceClusterNetworkSubnetReservedIPTargetContext(ClusterNetworkSubnetReservedIPTarget):
    """
    ClusterNetworkSubnetReservedIPTargetClusterNetworkInterfaceReferenceClusterNetworkSubnetReservedIPTargetContext.

    :param Deleted deleted: (optional) If present, this property indicates the
          referenced resource has been deleted, and provides
          some supplementary information.
    :param str href: The URL for this cluster network interface.
    :param str id: The unique identifier for this cluster network interface.
    :param str name: The name for this cluster network interface. The name is unique
          across all interfaces in the cluster network.
    :param str resource_type: The resource type.
    """

    def __init__(
        self,
        href: str,
        id: str,
        name: str,
        resource_type: str,
        *,
        deleted: Optional['Deleted'] = None,
    ) -> None:
        """
        Initialize a ClusterNetworkSubnetReservedIPTargetClusterNetworkInterfaceReferenceClusterNetworkSubnetReservedIPTargetContext object.

        :param str href: The URL for this cluster network interface.
        :param str id: The unique identifier for this cluster network interface.
        :param str name: The name for this cluster network interface. The name is
               unique across all interfaces in the cluster network.
        :param str resource_type: The resource type.
        :param Deleted 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) -> 'ClusterNetworkSubnetReservedIPTargetClusterNetworkInterfaceReferenceClusterNetworkSubnetReservedIPTargetContext':
        """Initialize a ClusterNetworkSubnetReservedIPTargetClusterNetworkInterfaceReferenceClusterNetworkSubnetReservedIPTargetContext object from a json dictionary."""
        args = {}
        if (deleted := _dict.get('deleted')) is not None:
            args['deleted'] = Deleted.from_dict(deleted)
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in ClusterNetworkSubnetReservedIPTargetClusterNetworkInterfaceReferenceClusterNetworkSubnetReservedIPTargetContext JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in ClusterNetworkSubnetReservedIPTargetClusterNetworkInterfaceReferenceClusterNetworkSubnetReservedIPTargetContext JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in ClusterNetworkSubnetReservedIPTargetClusterNetworkInterfaceReferenceClusterNetworkSubnetReservedIPTargetContext JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = resource_type
        else:
            raise ValueError('Required property \'resource_type\' not present in ClusterNetworkSubnetReservedIPTargetClusterNetworkInterfaceReferenceClusterNetworkSubnetReservedIPTargetContext JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ClusterNetworkSubnetReservedIPTargetClusterNetworkInterfaceReferenceClusterNetworkSubnetReservedIPTargetContext object from 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 ClusterNetworkSubnetReservedIPTargetClusterNetworkInterfaceReferenceClusterNetworkSubnetReservedIPTargetContext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ClusterNetworkSubnetReservedIPTargetClusterNetworkInterfaceReferenceClusterNetworkSubnetReservedIPTargetContext') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ClusterNetworkSubnetReservedIPTargetClusterNetworkInterfaceReferenceClusterNetworkSubnetReservedIPTargetContext') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        CLUSTER_NETWORK_INTERFACE = 'cluster_network_interface'



class DNSInstanceIdentityByCRN(DNSInstanceIdentity):
    """
    DNSInstanceIdentityByCRN.

    :param 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 := _dict.get('crn')) is not None:
            args['crn'] = 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.

    :param 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 := _dict.get('id')) is not None:
            args['id'] = 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.

    :param 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 := _dict.get('crn')) is not None:
            args['crn'] = 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.

    :param 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 := _dict.get('href')) is not None:
            args['href'] = 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.

    :param 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 := _dict.get('id')) is not None:
            args['id'] = 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.

    :param 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 := _dict.get('href')) is not None:
            args['href'] = 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.

    :param 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 := _dict.get('name')) is not None:
            args['name'] = 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.

    :param 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 := _dict.get('type')) is not None:
            args['type'] = 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.

    :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.
    """

    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 := _dict.get('default')) is not None:
            args['default'] = default
        else:
            raise ValueError('Required property \'default\' not present in DedicatedHostProfileMemoryEnum JSON')
        if (type := _dict.get('type')) is not None:
            args['type'] = type
        else:
            raise ValueError('Required property \'type\' not present in DedicatedHostProfileMemoryEnum JSON')
        if (values := _dict.get('values')) is not None:
            args['values'] = 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.

    :param str type: The type for this profile field.
    :param 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 := _dict.get('type')) is not None:
            args['type'] = type
        else:
            raise ValueError('Required property \'type\' not present in DedicatedHostProfileMemoryFixed JSON')
        if (value := _dict.get('value')) is not None:
            args['value'] = 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.

    :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.
    """

    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 := _dict.get('default')) is not None:
            args['default'] = default
        else:
            raise ValueError('Required property \'default\' not present in DedicatedHostProfileMemoryRange JSON')
        if (max := _dict.get('max')) is not None:
            args['max'] = max
        else:
            raise ValueError('Required property \'max\' not present in DedicatedHostProfileMemoryRange JSON')
        if (min := _dict.get('min')) is not None:
            args['min'] = min
        else:
            raise ValueError('Required property \'min\' not present in DedicatedHostProfileMemoryRange JSON')
        if (step := _dict.get('step')) is not None:
            args['step'] = step
        else:
            raise ValueError('Required property \'step\' not present in DedicatedHostProfileMemoryRange JSON')
        if (type := _dict.get('type')) is not None:
            args['type'] = 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.

    :param 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 := _dict.get('type')) is not None:
            args['type'] = 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.

    :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.
    """

    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 := _dict.get('default')) is not None:
            args['default'] = default
        else:
            raise ValueError('Required property \'default\' not present in DedicatedHostProfileSocketEnum JSON')
        if (type := _dict.get('type')) is not None:
            args['type'] = type
        else:
            raise ValueError('Required property \'type\' not present in DedicatedHostProfileSocketEnum JSON')
        if (values := _dict.get('values')) is not None:
            args['values'] = 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.

    :param str type: The type for this profile field.
    :param 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 := _dict.get('type')) is not None:
            args['type'] = type
        else:
            raise ValueError('Required property \'type\' not present in DedicatedHostProfileSocketFixed JSON')
        if (value := _dict.get('value')) is not None:
            args['value'] = 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.

    :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.
    """

    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 := _dict.get('default')) is not None:
            args['default'] = default
        else:
            raise ValueError('Required property \'default\' not present in DedicatedHostProfileSocketRange JSON')
        if (max := _dict.get('max')) is not None:
            args['max'] = max
        else:
            raise ValueError('Required property \'max\' not present in DedicatedHostProfileSocketRange JSON')
        if (min := _dict.get('min')) is not None:
            args['min'] = min
        else:
            raise ValueError('Required property \'min\' not present in DedicatedHostProfileSocketRange JSON')
        if (step := _dict.get('step')) is not None:
            args['step'] = step
        else:
            raise ValueError('Required property \'step\' not present in DedicatedHostProfileSocketRange JSON')
        if (type := _dict.get('type')) is not None:
            args['type'] = 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.

    :param 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 := _dict.get('type')) is not None:
            args['type'] = 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.

    :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.
    """

    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 := _dict.get('default')) is not None:
            args['default'] = default
        else:
            raise ValueError('Required property \'default\' not present in DedicatedHostProfileVCPUEnum JSON')
        if (type := _dict.get('type')) is not None:
            args['type'] = type
        else:
            raise ValueError('Required property \'type\' not present in DedicatedHostProfileVCPUEnum JSON')
        if (values := _dict.get('values')) is not None:
            args['values'] = 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.

    :param str type: The type for this profile field.
    :param 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 := _dict.get('type')) is not None:
            args['type'] = type
        else:
            raise ValueError('Required property \'type\' not present in DedicatedHostProfileVCPUFixed JSON')
        if (value := _dict.get('value')) is not None:
            args['value'] = 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.

    :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.
    """

    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 := _dict.get('default')) is not None:
            args['default'] = default
        else:
            raise ValueError('Required property \'default\' not present in DedicatedHostProfileVCPURange JSON')
        if (max := _dict.get('max')) is not None:
            args['max'] = max
        else:
            raise ValueError('Required property \'max\' not present in DedicatedHostProfileVCPURange JSON')
        if (min := _dict.get('min')) is not None:
            args['min'] = min
        else:
            raise ValueError('Required property \'min\' not present in DedicatedHostProfileVCPURange JSON')
        if (step := _dict.get('step')) is not None:
            args['step'] = step
        else:
            raise ValueError('Required property \'step\' not present in DedicatedHostProfileVCPURange JSON')
        if (type := _dict.get('type')) is not None:
            args['type'] = 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.

    :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 DedicatedHostProfileIdentity profile: The
          [profile](https://cloud.ibm.com/docs/vpc?topic=vpc-dh-profiles) to use for this
          dedicated host.
    :param ResourceGroupIdentity resource_group: (optional)
    :param DedicatedHostGroupIdentity group: The dedicated host group for this
          dedicated host.
    """

    def __init__(
        self,
        profile: 'DedicatedHostProfileIdentity',
        group: 'DedicatedHostGroupIdentity',
        *,
        instance_placement_enabled: Optional[bool] = None,
        name: Optional[str] = None,
        resource_group: Optional['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 := _dict.get('instance_placement_enabled')) is not None:
            args['instance_placement_enabled'] = instance_placement_enabled
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        if (profile := _dict.get('profile')) is not None:
            args['profile'] = profile
        else:
            raise ValueError('Required property \'profile\' not present in DedicatedHostPrototypeDedicatedHostByGroup JSON')
        if (resource_group := _dict.get('resource_group')) is not None:
            args['resource_group'] = resource_group
        if (group := _dict.get('group')) is not None:
            args['group'] = 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.

    :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 DedicatedHostProfileIdentity profile: The
          [profile](https://cloud.ibm.com/docs/vpc?topic=vpc-dh-profiles) to use for this
          dedicated host.
    :param ResourceGroupIdentity resource_group: (optional)
    :param DedicatedHostGroupPrototypeDedicatedHostByZoneContext group: (optional)
    :param ZoneIdentity zone: The zone this dedicated host will reside in.
    """

    def __init__(
        self,
        profile: 'DedicatedHostProfileIdentity',
        zone: 'ZoneIdentity',
        *,
        instance_placement_enabled: Optional[bool] = None,
        name: Optional[str] = None,
        resource_group: Optional['ResourceGroupIdentity'] = None,
        group: Optional['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 := _dict.get('instance_placement_enabled')) is not None:
            args['instance_placement_enabled'] = instance_placement_enabled
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        if (profile := _dict.get('profile')) is not None:
            args['profile'] = profile
        else:
            raise ValueError('Required property \'profile\' not present in DedicatedHostPrototypeDedicatedHostByZone JSON')
        if (resource_group := _dict.get('resource_group')) is not None:
            args['resource_group'] = resource_group
        if (group := _dict.get('group')) is not None:
            args['group'] = DedicatedHostGroupPrototypeDedicatedHostByZoneContext.from_dict(group)
        if (zone := _dict.get('zone')) is not None:
            args['zone'] = 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.

    :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.
    """

    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 := _dict.get('crn')) is not None:
            args['crn'] = 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.

    :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.
    :param SubnetIdentity subnet: The subnet in which to create this reserved IP.
    """

    def __init__(
        self,
        subnet: 'SubnetIdentity',
        *,
        address: Optional[str] = None,
        auto_delete: Optional[bool] = None,
        name: Optional[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 := _dict.get('address')) is not None:
            args['address'] = address
        if (auto_delete := _dict.get('auto_delete')) is not None:
            args['auto_delete'] = auto_delete
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        if (subnet := _dict.get('subnet')) is not None:
            args['subnet'] = 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 EndpointGatewayTargetPrototypeEndpointGatewayTargetResourceTypePrivatePathServiceGatewayPrototype(EndpointGatewayTargetPrototype):
    """
    EndpointGatewayTargetPrototypeEndpointGatewayTargetResourceTypePrivatePathServiceGatewayPrototype.

    :param str crn: The CRN for this private path service gateway.
    :param str resource_type: The target resource type for this endpoint gateway.
    """

    def __init__(
        self,
        crn: str,
        resource_type: str,
    ) -> None:
        """
        Initialize a EndpointGatewayTargetPrototypeEndpointGatewayTargetResourceTypePrivatePathServiceGatewayPrototype object.

        :param str crn: The CRN for this private path service gateway.
        :param str resource_type: The target resource type for this endpoint
               gateway.
        """
        # pylint: disable=super-init-not-called
        self.crn = crn
        self.resource_type = resource_type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'EndpointGatewayTargetPrototypeEndpointGatewayTargetResourceTypePrivatePathServiceGatewayPrototype':
        """Initialize a EndpointGatewayTargetPrototypeEndpointGatewayTargetResourceTypePrivatePathServiceGatewayPrototype object from a json dictionary."""
        args = {}
        if (crn := _dict.get('crn')) is not None:
            args['crn'] = crn
        else:
            raise ValueError('Required property \'crn\' not present in EndpointGatewayTargetPrototypeEndpointGatewayTargetResourceTypePrivatePathServiceGatewayPrototype JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = resource_type
        else:
            raise ValueError('Required property \'resource_type\' not present in EndpointGatewayTargetPrototypeEndpointGatewayTargetResourceTypePrivatePathServiceGatewayPrototype JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a EndpointGatewayTargetPrototypeEndpointGatewayTargetResourceTypePrivatePathServiceGatewayPrototype object from 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 EndpointGatewayTargetPrototypeEndpointGatewayTargetResourceTypePrivatePathServiceGatewayPrototype object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'EndpointGatewayTargetPrototypeEndpointGatewayTargetResourceTypePrivatePathServiceGatewayPrototype') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'EndpointGatewayTargetPrototypeEndpointGatewayTargetResourceTypePrivatePathServiceGatewayPrototype') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ResourceTypeEnum(str, Enum):
        """
        The target resource type for this endpoint gateway.
        """

        PRIVATE_PATH_SERVICE_GATEWAY = 'private_path_service_gateway'



class EndpointGatewayTargetPrototypeEndpointGatewayTargetResourceTypeProviderCloudServicePrototype(EndpointGatewayTargetPrototype):
    """
    EndpointGatewayTargetPrototypeEndpointGatewayTargetResourceTypeProviderCloudServicePrototype.

    :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 target resource type for this endpoint gateway.
    """

    def __init__(
        self,
        crn: str,
        resource_type: str,
    ) -> None:
        """
        Initialize a EndpointGatewayTargetPrototypeEndpointGatewayTargetResourceTypeProviderCloudServicePrototype 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 target resource type for this endpoint
               gateway.
        """
        # pylint: disable=super-init-not-called
        self.crn = crn
        self.resource_type = resource_type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'EndpointGatewayTargetPrototypeEndpointGatewayTargetResourceTypeProviderCloudServicePrototype':
        """Initialize a EndpointGatewayTargetPrototypeEndpointGatewayTargetResourceTypeProviderCloudServicePrototype object from a json dictionary."""
        args = {}
        if (crn := _dict.get('crn')) is not None:
            args['crn'] = crn
        else:
            raise ValueError('Required property \'crn\' not present in EndpointGatewayTargetPrototypeEndpointGatewayTargetResourceTypeProviderCloudServicePrototype JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = resource_type
        else:
            raise ValueError('Required property \'resource_type\' not present in EndpointGatewayTargetPrototypeEndpointGatewayTargetResourceTypeProviderCloudServicePrototype JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a EndpointGatewayTargetPrototypeEndpointGatewayTargetResourceTypeProviderCloudServicePrototype object from 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 EndpointGatewayTargetPrototypeEndpointGatewayTargetResourceTypeProviderCloudServicePrototype object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'EndpointGatewayTargetPrototypeEndpointGatewayTargetResourceTypeProviderCloudServicePrototype') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'EndpointGatewayTargetPrototypeEndpointGatewayTargetResourceTypeProviderCloudServicePrototype') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ResourceTypeEnum(str, Enum):
        """
        The target resource type for this endpoint gateway.
        """

        PROVIDER_CLOUD_SERVICE = 'provider_cloud_service'



class EndpointGatewayTargetPrototypeEndpointGatewayTargetResourceTypeProviderInfrastructureServicePrototype(EndpointGatewayTargetPrototype):
    """
    The name of this provider infrastructure service.

    :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 target resource type for this endpoint gateway.
    """

    def __init__(
        self,
        name: str,
        resource_type: str,
    ) -> None:
        """
        Initialize a EndpointGatewayTargetPrototypeEndpointGatewayTargetResourceTypeProviderInfrastructureServicePrototype 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 target resource type for this endpoint
               gateway.
        """
        # pylint: disable=super-init-not-called
        self.name = name
        self.resource_type = resource_type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'EndpointGatewayTargetPrototypeEndpointGatewayTargetResourceTypeProviderInfrastructureServicePrototype':
        """Initialize a EndpointGatewayTargetPrototypeEndpointGatewayTargetResourceTypeProviderInfrastructureServicePrototype object from a json dictionary."""
        args = {}
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in EndpointGatewayTargetPrototypeEndpointGatewayTargetResourceTypeProviderInfrastructureServicePrototype JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = resource_type
        else:
            raise ValueError('Required property \'resource_type\' not present in EndpointGatewayTargetPrototypeEndpointGatewayTargetResourceTypeProviderInfrastructureServicePrototype JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a EndpointGatewayTargetPrototypeEndpointGatewayTargetResourceTypeProviderInfrastructureServicePrototype object from 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 EndpointGatewayTargetPrototypeEndpointGatewayTargetResourceTypeProviderInfrastructureServicePrototype object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'EndpointGatewayTargetPrototypeEndpointGatewayTargetResourceTypeProviderInfrastructureServicePrototype') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'EndpointGatewayTargetPrototypeEndpointGatewayTargetResourceTypeProviderInfrastructureServicePrototype') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ResourceTypeEnum(str, Enum):
        """
        The target resource type for this endpoint gateway.
        """

        PROVIDER_INFRASTRUCTURE_SERVICE = 'provider_infrastructure_service'



class EndpointGatewayTargetPrivatePathServiceGatewayReference(EndpointGatewayTarget):
    """
    EndpointGatewayTargetPrivatePathServiceGatewayReference.

    :param str crn: The CRN for this private path service gateway.
    :param Deleted deleted: (optional) If present, this property indicates the
          referenced resource has been deleted, and provides
          some supplementary information.
    :param str href: The URL for this private path service gateway.
    :param str id: The unique identifier for this private path service gateway.
    :param str name: The name for this private path service gateway. The name is
          unique across all private path service gateways in the VPC.
    :param PrivatePathServiceGatewayRemote remote: (optional) If present, this
          property indicates that the resource associated with this reference
          is remote and therefore may not be directly retrievable.
    :param str resource_type: The resource type.
    """

    def __init__(
        self,
        crn: str,
        href: str,
        id: str,
        name: str,
        resource_type: str,
        *,
        deleted: Optional['Deleted'] = None,
        remote: Optional['PrivatePathServiceGatewayRemote'] = None,
    ) -> None:
        """
        Initialize a EndpointGatewayTargetPrivatePathServiceGatewayReference object.

        :param str crn: The CRN for this private path service gateway.
        :param str href: The URL for this private path service gateway.
        :param str id: The unique identifier for this private path service gateway.
        :param str name: The name for this private path service gateway. The name
               is unique across all private path service gateways in the VPC.
        :param str resource_type: The resource type.
        :param Deleted deleted: (optional) If present, this property indicates the
               referenced resource has been deleted, and provides
               some supplementary information.
        :param PrivatePathServiceGatewayRemote 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) -> 'EndpointGatewayTargetPrivatePathServiceGatewayReference':
        """Initialize a EndpointGatewayTargetPrivatePathServiceGatewayReference object from a json dictionary."""
        args = {}
        if (crn := _dict.get('crn')) is not None:
            args['crn'] = crn
        else:
            raise ValueError('Required property \'crn\' not present in EndpointGatewayTargetPrivatePathServiceGatewayReference JSON')
        if (deleted := _dict.get('deleted')) is not None:
            args['deleted'] = Deleted.from_dict(deleted)
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in EndpointGatewayTargetPrivatePathServiceGatewayReference JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in EndpointGatewayTargetPrivatePathServiceGatewayReference JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in EndpointGatewayTargetPrivatePathServiceGatewayReference JSON')
        if (remote := _dict.get('remote')) is not None:
            args['remote'] = PrivatePathServiceGatewayRemote.from_dict(remote)
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = resource_type
        else:
            raise ValueError('Required property \'resource_type\' not present in EndpointGatewayTargetPrivatePathServiceGatewayReference JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a EndpointGatewayTargetPrivatePathServiceGatewayReference object from 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 EndpointGatewayTargetPrivatePathServiceGatewayReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'EndpointGatewayTargetPrivatePathServiceGatewayReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'EndpointGatewayTargetPrivatePathServiceGatewayReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        PRIVATE_PATH_SERVICE_GATEWAY = 'private_path_service_gateway'



class EndpointGatewayTargetProviderCloudServiceReference(EndpointGatewayTarget):
    """
    EndpointGatewayTargetProviderCloudServiceReference.

    :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.
    """

    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 := _dict.get('crn')) is not None:
            args['crn'] = crn
        else:
            raise ValueError('Required property \'crn\' not present in EndpointGatewayTargetProviderCloudServiceReference JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = 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.

    :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.
    """

    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 := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in EndpointGatewayTargetProviderInfrastructureServiceReference JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = 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.

    :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)
    :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`
          - a virtual network interface with `enable_infrastructure_nat` set to `true`.
    """

    def __init__(
        self,
        target: 'FloatingIPTargetPrototype',
        *,
        name: Optional[str] = None,
        resource_group: Optional['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`
               - a virtual 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 := _dict.get('name')) is not None:
            args['name'] = name
        if (resource_group := _dict.get('resource_group')) is not None:
            args['resource_group'] = resource_group
        if (target := _dict.get('target')) is not None:
            args['target'] = 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.

    :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)
    :param ZoneIdentity zone: The zone this floating IP will reside in.
    """

    def __init__(
        self,
        zone: 'ZoneIdentity',
        *,
        name: Optional[str] = None,
        resource_group: Optional['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 := _dict.get('name')) is not None:
            args['name'] = name
        if (resource_group := _dict.get('resource_group')) is not None:
            args['resource_group'] = resource_group
        if (zone := _dict.get('zone')) is not None:
            args['zone'] = 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 FloatingIPTargetPatchVirtualNetworkInterfaceIdentity(FloatingIPTargetPatch):
    """
    Identifies a virtual network interface by a unique property.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a FloatingIPTargetPatchVirtualNetworkInterfaceIdentity object.

        """
        # pylint: disable=super-init-not-called
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['FloatingIPTargetPatchVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityById', 'FloatingIPTargetPatchVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByHref', 'FloatingIPTargetPatchVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByCRN'])
        )
        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 FloatingIPTargetPrototypeVirtualNetworkInterfaceIdentity(FloatingIPTargetPrototype):
    """
    Identifies a virtual network interface by a unique property.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a FloatingIPTargetPrototypeVirtualNetworkInterfaceIdentity object.

        """
        # pylint: disable=super-init-not-called
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['FloatingIPTargetPrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityById', 'FloatingIPTargetPrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByHref', 'FloatingIPTargetPrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByCRN'])
        )
        raise Exception(msg)


class FloatingIPTargetBareMetalServerNetworkInterfaceReference(FloatingIPTarget):
    """
    FloatingIPTargetBareMetalServerNetworkInterfaceReference.

    :param Deleted deleted: (optional) If present, this property indicates the
          referenced resource has been deleted, and provides
          some supplementary information.
    :param str href: The URL for this bare metal server network interface.
          If this bare metal server has network attachments, this network interface is a
          [read-only
          representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
          of its corresponding network attachment.
    :param str id: The unique identifier for this bare metal server network
          interface.
          If this bare metal server has network attachments, this network interface is a
          [read-only
          representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
          of its corresponding network attachment and its attached virtual network
          interface, and the identifier is that of the corresponding network attachment.
    :param str name: The name for this bare metal server network interface.
    :param ReservedIPReference primary_ip:
    :param str resource_type: The resource type.
    """

    def __init__(
        self,
        href: str,
        id: str,
        name: str,
        primary_ip: 'ReservedIPReference',
        resource_type: str,
        *,
        deleted: Optional['Deleted'] = None,
    ) -> None:
        """
        Initialize a FloatingIPTargetBareMetalServerNetworkInterfaceReference object.

        :param str href: The URL for this bare metal server network interface.
               If this bare metal server has network attachments, this network interface
               is a
               [read-only
               representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
               of its corresponding network attachment.
        :param str id: The unique identifier for this bare metal server network
               interface.
               If this bare metal server has network attachments, this network interface
               is a
               [read-only
               representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
               of its corresponding network attachment and its attached virtual network
               interface, and the identifier is that of the corresponding network
               attachment.
        :param str name: The name for this bare metal server network interface.
        :param ReservedIPReference primary_ip:
        :param str resource_type: The resource type.
        :param Deleted 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 := _dict.get('deleted')) is not None:
            args['deleted'] = Deleted.from_dict(deleted)
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in FloatingIPTargetBareMetalServerNetworkInterfaceReference JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in FloatingIPTargetBareMetalServerNetworkInterfaceReference JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in FloatingIPTargetBareMetalServerNetworkInterfaceReference JSON')
        if (primary_ip := _dict.get('primary_ip')) is not None:
            args['primary_ip'] = ReservedIPReference.from_dict(primary_ip)
        else:
            raise ValueError('Required property \'primary_ip\' not present in FloatingIPTargetBareMetalServerNetworkInterfaceReference JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = 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.

    :param Deleted deleted: (optional) If present, this property indicates the
          referenced resource has been deleted, and provides
          some supplementary information.
    :param str href: The URL for this instance network interface.
          If this instance has network attachments, this network interface is a
          [read-only
          representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
          of its corresponding network attachment.
    :param str id: The unique identifier for this instance network interface.
          If this instance has network attachments, this network interface is a
          [read-only
          representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
          of its corresponding network attachment and its attached virtual network
          interface, and the identifier is that of the corresponding network attachment.
    :param str name: The name for this instance network interface.
    :param ReservedIPReference primary_ip:
    :param str resource_type: The resource type.
    """

    def __init__(
        self,
        href: str,
        id: str,
        name: str,
        primary_ip: 'ReservedIPReference',
        resource_type: str,
        *,
        deleted: Optional['Deleted'] = None,
    ) -> None:
        """
        Initialize a FloatingIPTargetNetworkInterfaceReference object.

        :param str href: The URL for this instance network interface.
               If this instance has network attachments, this network interface is a
               [read-only
               representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
               of its corresponding network attachment.
        :param str id: The unique identifier for this instance network interface.
               If this instance has network attachments, this network interface is a
               [read-only
               representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
               of its corresponding network attachment and its attached virtual network
               interface, and the identifier is that of the corresponding network
               attachment.
        :param str name: The name for this instance network interface.
        :param ReservedIPReference primary_ip:
        :param str resource_type: The resource type.
        :param Deleted 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 := _dict.get('deleted')) is not None:
            args['deleted'] = Deleted.from_dict(deleted)
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in FloatingIPTargetNetworkInterfaceReference JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in FloatingIPTargetNetworkInterfaceReference JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in FloatingIPTargetNetworkInterfaceReference JSON')
        if (primary_ip := _dict.get('primary_ip')) is not None:
            args['primary_ip'] = ReservedIPReference.from_dict(primary_ip)
        else:
            raise ValueError('Required property \'primary_ip\' not present in FloatingIPTargetNetworkInterfaceReference JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = 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.

    :param str crn: The CRN for this public gateway.
    :param Deleted deleted: (optional) If present, this property indicates the
          referenced resource has been deleted, and provides
          some supplementary information.
    :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.
    """

    def __init__(
        self,
        crn: str,
        href: str,
        id: str,
        name: str,
        resource_type: str,
        *,
        deleted: Optional['Deleted'] = 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 Deleted 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 := _dict.get('crn')) is not None:
            args['crn'] = crn
        else:
            raise ValueError('Required property \'crn\' not present in FloatingIPTargetPublicGatewayReference JSON')
        if (deleted := _dict.get('deleted')) is not None:
            args['deleted'] = Deleted.from_dict(deleted)
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in FloatingIPTargetPublicGatewayReference JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in FloatingIPTargetPublicGatewayReference JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in FloatingIPTargetPublicGatewayReference JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = 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 FloatingIPTargetVirtualNetworkInterfaceReference(FloatingIPTarget):
    """
    FloatingIPTargetVirtualNetworkInterfaceReference.

    :param str crn: The CRN for this virtual network interface.
    :param Deleted deleted: (optional) If present, this property indicates the
          referenced resource has been deleted, and provides
          some supplementary information.
    :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.
    """

    def __init__(
        self,
        crn: str,
        href: str,
        id: str,
        name: str,
        primary_ip: 'ReservedIPReference',
        resource_type: str,
        subnet: 'SubnetReference',
        *,
        deleted: Optional['Deleted'] = None,
    ) -> None:
        """
        Initialize a FloatingIPTargetVirtualNetworkInterfaceReference 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 Deleted 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) -> 'FloatingIPTargetVirtualNetworkInterfaceReference':
        """Initialize a FloatingIPTargetVirtualNetworkInterfaceReference object from a json dictionary."""
        args = {}
        if (crn := _dict.get('crn')) is not None:
            args['crn'] = crn
        else:
            raise ValueError('Required property \'crn\' not present in FloatingIPTargetVirtualNetworkInterfaceReference JSON')
        if (deleted := _dict.get('deleted')) is not None:
            args['deleted'] = Deleted.from_dict(deleted)
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in FloatingIPTargetVirtualNetworkInterfaceReference JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in FloatingIPTargetVirtualNetworkInterfaceReference JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in FloatingIPTargetVirtualNetworkInterfaceReference JSON')
        if (primary_ip := _dict.get('primary_ip')) is not None:
            args['primary_ip'] = ReservedIPReference.from_dict(primary_ip)
        else:
            raise ValueError('Required property \'primary_ip\' not present in FloatingIPTargetVirtualNetworkInterfaceReference JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = resource_type
        else:
            raise ValueError('Required property \'resource_type\' not present in FloatingIPTargetVirtualNetworkInterfaceReference JSON')
        if (subnet := _dict.get('subnet')) is not None:
            args['subnet'] = SubnetReference.from_dict(subnet)
        else:
            raise ValueError('Required property \'subnet\' not present in FloatingIPTargetVirtualNetworkInterfaceReference JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a FloatingIPTargetVirtualNetworkInterfaceReference object from 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 FloatingIPTargetVirtualNetworkInterfaceReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'FloatingIPTargetVirtualNetworkInterfaceReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'FloatingIPTargetVirtualNetworkInterfaceReference') -> 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 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 FlowLogCollectorTargetPrototypeInstanceNetworkAttachmentIdentity(FlowLogCollectorTargetPrototype):
    """
    Identifies an instance network attachment by a unique property.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a FlowLogCollectorTargetPrototypeInstanceNetworkAttachmentIdentity object.

        """
        # pylint: disable=super-init-not-called
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['FlowLogCollectorTargetPrototypeInstanceNetworkAttachmentIdentityInstanceNetworkAttachmentIdentityById', 'FlowLogCollectorTargetPrototypeInstanceNetworkAttachmentIdentityInstanceNetworkAttachmentIdentityByHref'])
        )
        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 FlowLogCollectorTargetPrototypeVirtualNetworkInterfaceIdentity(FlowLogCollectorTargetPrototype):
    """
    Identifies a virtual network interface by a unique property.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a FlowLogCollectorTargetPrototypeVirtualNetworkInterfaceIdentity object.

        """
        # pylint: disable=super-init-not-called
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['FlowLogCollectorTargetPrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityById', 'FlowLogCollectorTargetPrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByHref', 'FlowLogCollectorTargetPrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByCRN'])
        )
        raise Exception(msg)


class FlowLogCollectorTargetInstanceNetworkAttachmentReference(FlowLogCollectorTarget):
    """
    FlowLogCollectorTargetInstanceNetworkAttachmentReference.

    :param Deleted deleted: (optional) If present, this property indicates the
          referenced resource has been deleted, and provides
          some supplementary information.
    :param str href: The URL for this instance network attachment.
    :param str id: The unique identifier for this instance network attachment.
    :param str name: The name for this instance network attachment. The name is
          unique across all network attachments for the instance.
    :param ReservedIPReference primary_ip: The primary IP address of the virtual
          network interface for the instance network
          attachment.
    :param str resource_type: The resource type.
    :param SubnetReference subnet: The subnet of the virtual network interface for
          the instance network attachment.
    :param VirtualNetworkInterfaceReferenceAttachmentContext
          virtual_network_interface: The virtual network interface for this instance
          network attachment.
    """

    def __init__(
        self,
        href: str,
        id: str,
        name: str,
        primary_ip: 'ReservedIPReference',
        resource_type: str,
        subnet: 'SubnetReference',
        virtual_network_interface: 'VirtualNetworkInterfaceReferenceAttachmentContext',
        *,
        deleted: Optional['Deleted'] = None,
    ) -> None:
        """
        Initialize a FlowLogCollectorTargetInstanceNetworkAttachmentReference object.

        :param str href: The URL for this instance network attachment.
        :param str id: The unique identifier for this instance network attachment.
        :param str name: The name for this instance network attachment. The name is
               unique across all network attachments for the instance.
        :param ReservedIPReference primary_ip: The primary IP address of the
               virtual network interface for the instance network
               attachment.
        :param str resource_type: The resource type.
        :param SubnetReference subnet: The subnet of the virtual network interface
               for the instance network attachment.
        :param VirtualNetworkInterfaceReferenceAttachmentContext
               virtual_network_interface: The virtual network interface for this instance
               network attachment.
        :param Deleted 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
        self.subnet = subnet
        self.virtual_network_interface = virtual_network_interface

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'FlowLogCollectorTargetInstanceNetworkAttachmentReference':
        """Initialize a FlowLogCollectorTargetInstanceNetworkAttachmentReference object from a json dictionary."""
        args = {}
        if (deleted := _dict.get('deleted')) is not None:
            args['deleted'] = Deleted.from_dict(deleted)
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in FlowLogCollectorTargetInstanceNetworkAttachmentReference JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in FlowLogCollectorTargetInstanceNetworkAttachmentReference JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in FlowLogCollectorTargetInstanceNetworkAttachmentReference JSON')
        if (primary_ip := _dict.get('primary_ip')) is not None:
            args['primary_ip'] = ReservedIPReference.from_dict(primary_ip)
        else:
            raise ValueError('Required property \'primary_ip\' not present in FlowLogCollectorTargetInstanceNetworkAttachmentReference JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = resource_type
        else:
            raise ValueError('Required property \'resource_type\' not present in FlowLogCollectorTargetInstanceNetworkAttachmentReference JSON')
        if (subnet := _dict.get('subnet')) is not None:
            args['subnet'] = SubnetReference.from_dict(subnet)
        else:
            raise ValueError('Required property \'subnet\' not present in FlowLogCollectorTargetInstanceNetworkAttachmentReference JSON')
        if (virtual_network_interface := _dict.get('virtual_network_interface')) is not None:
            args['virtual_network_interface'] = VirtualNetworkInterfaceReferenceAttachmentContext.from_dict(virtual_network_interface)
        else:
            raise ValueError('Required property \'virtual_network_interface\' not present in FlowLogCollectorTargetInstanceNetworkAttachmentReference JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a FlowLogCollectorTargetInstanceNetworkAttachmentReference object from 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()
        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 FlowLogCollectorTargetInstanceNetworkAttachmentReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'FlowLogCollectorTargetInstanceNetworkAttachmentReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'FlowLogCollectorTargetInstanceNetworkAttachmentReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        INSTANCE_NETWORK_ATTACHMENT = 'instance_network_attachment'



class FlowLogCollectorTargetInstanceReference(FlowLogCollectorTarget):
    """
    FlowLogCollectorTargetInstanceReference.

    :param str crn: The CRN for this virtual server instance.
    :param Deleted deleted: (optional) If present, this property indicates the
          referenced resource has been deleted, and provides
          some supplementary information.
    :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.
    """

    def __init__(
        self,
        crn: str,
        href: str,
        id: str,
        name: str,
        *,
        deleted: Optional['Deleted'] = 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 Deleted 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 := _dict.get('crn')) is not None:
            args['crn'] = crn
        else:
            raise ValueError('Required property \'crn\' not present in FlowLogCollectorTargetInstanceReference JSON')
        if (deleted := _dict.get('deleted')) is not None:
            args['deleted'] = Deleted.from_dict(deleted)
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in FlowLogCollectorTargetInstanceReference JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in FlowLogCollectorTargetInstanceReference JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = 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.

    :param Deleted deleted: (optional) If present, this property indicates the
          referenced resource has been deleted, and provides
          some supplementary information.
    :param str href: The URL for this instance network interface.
          If this instance has network attachments, this network interface is a
          [read-only
          representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
          of its corresponding network attachment.
    :param str id: The unique identifier for this instance network interface.
          If this instance has network attachments, this network interface is a
          [read-only
          representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
          of its corresponding network attachment and its attached virtual network
          interface, and the identifier is that of the corresponding network attachment.
    :param str name: The name for this instance network interface.
    :param str resource_type: The resource type.
    """

    def __init__(
        self,
        href: str,
        id: str,
        name: str,
        resource_type: str,
        *,
        deleted: Optional['Deleted'] = None,
    ) -> None:
        """
        Initialize a FlowLogCollectorTargetNetworkInterfaceReferenceTargetContext object.

        :param str href: The URL for this instance network interface.
               If this instance has network attachments, this network interface is a
               [read-only
               representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
               of its corresponding network attachment.
        :param str id: The unique identifier for this instance network interface.
               If this instance has network attachments, this network interface is a
               [read-only
               representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
               of its corresponding network attachment and its attached virtual network
               interface, and the identifier is that of the corresponding network
               attachment.
        :param str name: The name for this instance network interface.
        :param str resource_type: The resource type.
        :param Deleted 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 := _dict.get('deleted')) is not None:
            args['deleted'] = Deleted.from_dict(deleted)
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in FlowLogCollectorTargetNetworkInterfaceReferenceTargetContext JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in FlowLogCollectorTargetNetworkInterfaceReferenceTargetContext JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in FlowLogCollectorTargetNetworkInterfaceReferenceTargetContext JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = 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.

    :param str crn: The CRN for this subnet.
    :param Deleted deleted: (optional) If present, this property indicates the
          referenced resource has been deleted, and provides
          some supplementary information.
    :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.
    """

    def __init__(
        self,
        crn: str,
        href: str,
        id: str,
        name: str,
        resource_type: str,
        *,
        deleted: Optional['Deleted'] = 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 Deleted 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 := _dict.get('crn')) is not None:
            args['crn'] = crn
        else:
            raise ValueError('Required property \'crn\' not present in FlowLogCollectorTargetSubnetReference JSON')
        if (deleted := _dict.get('deleted')) is not None:
            args['deleted'] = Deleted.from_dict(deleted)
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in FlowLogCollectorTargetSubnetReference JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in FlowLogCollectorTargetSubnetReference JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in FlowLogCollectorTargetSubnetReference JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = 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.

    :param str crn: The CRN for this VPC.
    :param Deleted deleted: (optional) If present, this property indicates the
          referenced resource has been deleted, and provides
          some supplementary information.
    :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.
    """

    def __init__(
        self,
        crn: str,
        href: str,
        id: str,
        name: str,
        resource_type: str,
        *,
        deleted: Optional['Deleted'] = 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 Deleted 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 := _dict.get('crn')) is not None:
            args['crn'] = crn
        else:
            raise ValueError('Required property \'crn\' not present in FlowLogCollectorTargetVPCReference JSON')
        if (deleted := _dict.get('deleted')) is not None:
            args['deleted'] = Deleted.from_dict(deleted)
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in FlowLogCollectorTargetVPCReference JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in FlowLogCollectorTargetVPCReference JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in FlowLogCollectorTargetVPCReference JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = 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 FlowLogCollectorTargetVirtualNetworkInterfaceReferenceAttachmentContext(FlowLogCollectorTarget):
    """
    FlowLogCollectorTargetVirtualNetworkInterfaceReferenceAttachmentContext.

    :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.
    """

    def __init__(
        self,
        crn: str,
        href: str,
        id: str,
        name: str,
        resource_type: str,
    ) -> None:
        """
        Initialize a FlowLogCollectorTargetVirtualNetworkInterfaceReferenceAttachmentContext 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) -> 'FlowLogCollectorTargetVirtualNetworkInterfaceReferenceAttachmentContext':
        """Initialize a FlowLogCollectorTargetVirtualNetworkInterfaceReferenceAttachmentContext object from a json dictionary."""
        args = {}
        if (crn := _dict.get('crn')) is not None:
            args['crn'] = crn
        else:
            raise ValueError('Required property \'crn\' not present in FlowLogCollectorTargetVirtualNetworkInterfaceReferenceAttachmentContext JSON')
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in FlowLogCollectorTargetVirtualNetworkInterfaceReferenceAttachmentContext JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in FlowLogCollectorTargetVirtualNetworkInterfaceReferenceAttachmentContext JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in FlowLogCollectorTargetVirtualNetworkInterfaceReferenceAttachmentContext JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = resource_type
        else:
            raise ValueError('Required property \'resource_type\' not present in FlowLogCollectorTargetVirtualNetworkInterfaceReferenceAttachmentContext JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a FlowLogCollectorTargetVirtualNetworkInterfaceReferenceAttachmentContext object from 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 FlowLogCollectorTargetVirtualNetworkInterfaceReferenceAttachmentContext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'FlowLogCollectorTargetVirtualNetworkInterfaceReferenceAttachmentContext') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'FlowLogCollectorTargetVirtualNetworkInterfaceReferenceAttachmentContext') -> 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 ImageIdentityByCRN(ImageIdentity):
    """
    ImageIdentityByCRN.

    :param 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 := _dict.get('crn')) is not None:
            args['crn'] = 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.

    :param 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 := _dict.get('href')) is not None:
            args['href'] = 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.

    :param 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 := _dict.get('id')) is not None:
            args['id'] = 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.

    :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.
    :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.
    """

    def __init__(
        self,
        file: 'ImageFilePrototype',
        operating_system: 'OperatingSystemIdentity',
        *,
        deprecation_at: Optional[datetime] = None,
        name: Optional[str] = None,
        obsolescence_at: Optional[datetime] = None,
        resource_group: Optional['ResourceGroupIdentity'] = None,
        encrypted_data_key: Optional[str] = None,
        encryption_key: Optional['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 := _dict.get('deprecation_at')) is not None:
            args['deprecation_at'] = string_to_datetime(deprecation_at)
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        if (obsolescence_at := _dict.get('obsolescence_at')) is not None:
            args['obsolescence_at'] = string_to_datetime(obsolescence_at)
        if (resource_group := _dict.get('resource_group')) is not None:
            args['resource_group'] = resource_group
        if (encrypted_data_key := _dict.get('encrypted_data_key')) is not None:
            args['encrypted_data_key'] = encrypted_data_key
        if (encryption_key := _dict.get('encryption_key')) is not None:
            args['encryption_key'] = encryption_key
        if (file := _dict.get('file')) is not None:
            args['file'] = ImageFilePrototype.from_dict(file)
        else:
            raise ValueError('Required property \'file\' not present in ImagePrototypeImageByFile JSON')
        if (operating_system := _dict.get('operating_system')) is not None:
            args['operating_system'] = 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.

    :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.
    :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`.
    """

    def __init__(
        self,
        source_volume: 'VolumeIdentity',
        *,
        deprecation_at: Optional[datetime] = None,
        name: Optional[str] = None,
        obsolescence_at: Optional[datetime] = None,
        resource_group: Optional['ResourceGroupIdentity'] = None,
        encryption_key: Optional['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 := _dict.get('deprecation_at')) is not None:
            args['deprecation_at'] = string_to_datetime(deprecation_at)
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        if (obsolescence_at := _dict.get('obsolescence_at')) is not None:
            args['obsolescence_at'] = string_to_datetime(obsolescence_at)
        if (resource_group := _dict.get('resource_group')) is not None:
            args['resource_group'] = resource_group
        if (encryption_key := _dict.get('encryption_key')) is not None:
            args['encryption_key'] = encryption_key
        if (source_volume := _dict.get('source_volume')) is not None:
            args['source_volume'] = 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.

    :param CatalogOfferingVersionPlanIdentity plan: (optional) The billing plan to
          use for the catalog offering version. If unspecified, no billing plan will be
          used (free). Must be specified for catalog offering versions that require a
          billing plan to be used.
    :param 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',
        *,
        plan: Optional['CatalogOfferingVersionPlanIdentity'] = None,
    ) -> 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.
        :param CatalogOfferingVersionPlanIdentity plan: (optional) The billing plan
               to use for the catalog offering version. If unspecified, no billing plan
               will be used (free). Must be specified for catalog offering versions that
               require a billing plan to be used.
        """
        # pylint: disable=super-init-not-called
        self.plan = plan
        self.offering = offering

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceCatalogOfferingPrototypeCatalogOfferingByOffering':
        """Initialize a InstanceCatalogOfferingPrototypeCatalogOfferingByOffering object from a json dictionary."""
        args = {}
        if (plan := _dict.get('plan')) is not None:
            args['plan'] = plan
        if (offering := _dict.get('offering')) is not None:
            args['offering'] = 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, 'plan') and self.plan is not None:
            if isinstance(self.plan, dict):
                _dict['plan'] = self.plan
            else:
                _dict['plan'] = self.plan.to_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.

    :param CatalogOfferingVersionPlanIdentity plan: (optional) The billing plan to
          use for the catalog offering version. If unspecified, no billing plan will be
          used (free). Must be specified for catalog offering versions that require a
          billing plan to be used.
    :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.
    """

    def __init__(
        self,
        version: 'CatalogOfferingVersionIdentity',
        *,
        plan: Optional['CatalogOfferingVersionPlanIdentity'] = None,
    ) -> 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.
        :param CatalogOfferingVersionPlanIdentity plan: (optional) The billing plan
               to use for the catalog offering version. If unspecified, no billing plan
               will be used (free). Must be specified for catalog offering versions that
               require a billing plan to be used.
        """
        # pylint: disable=super-init-not-called
        self.plan = plan
        self.version = version

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceCatalogOfferingPrototypeCatalogOfferingByVersion':
        """Initialize a InstanceCatalogOfferingPrototypeCatalogOfferingByVersion object from a json dictionary."""
        args = {}
        if (plan := _dict.get('plan')) is not None:
            args['plan'] = plan
        if (version := _dict.get('version')) is not None:
            args['version'] = 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, 'plan') and self.plan is not None:
            if isinstance(self.plan, dict):
                _dict['plan'] = self.plan
            else:
                _dict['plan'] = self.plan.to_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 InstanceClusterNetworkAttachmentBeforePrototypeInstanceClusterNetworkAttachmentIdentityByHref(InstanceClusterNetworkAttachmentBeforePrototype):
    """
    InstanceClusterNetworkAttachmentBeforePrototypeInstanceClusterNetworkAttachmentIdentityByHref.

    :param str href: The URL for this instance cluster network attachment.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a InstanceClusterNetworkAttachmentBeforePrototypeInstanceClusterNetworkAttachmentIdentityByHref object.

        :param str href: The URL for this instance cluster network attachment.
        """
        # pylint: disable=super-init-not-called
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceClusterNetworkAttachmentBeforePrototypeInstanceClusterNetworkAttachmentIdentityByHref':
        """Initialize a InstanceClusterNetworkAttachmentBeforePrototypeInstanceClusterNetworkAttachmentIdentityByHref object from a json dictionary."""
        args = {}
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in InstanceClusterNetworkAttachmentBeforePrototypeInstanceClusterNetworkAttachmentIdentityByHref JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceClusterNetworkAttachmentBeforePrototypeInstanceClusterNetworkAttachmentIdentityByHref object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceClusterNetworkAttachmentBeforePrototypeInstanceClusterNetworkAttachmentIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceClusterNetworkAttachmentBeforePrototypeInstanceClusterNetworkAttachmentIdentityByHref') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceClusterNetworkAttachmentBeforePrototypeInstanceClusterNetworkAttachmentIdentityByHref') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceClusterNetworkAttachmentBeforePrototypeInstanceClusterNetworkAttachmentIdentityById(InstanceClusterNetworkAttachmentBeforePrototype):
    """
    InstanceClusterNetworkAttachmentBeforePrototypeInstanceClusterNetworkAttachmentIdentityById.

    :param str id: The unique identifier for this instance cluster network
          attachment.
    """

    def __init__(
        self,
        id: str,
    ) -> None:
        """
        Initialize a InstanceClusterNetworkAttachmentBeforePrototypeInstanceClusterNetworkAttachmentIdentityById object.

        :param str id: The unique identifier for this instance cluster network
               attachment.
        """
        # pylint: disable=super-init-not-called
        self.id = id

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceClusterNetworkAttachmentBeforePrototypeInstanceClusterNetworkAttachmentIdentityById':
        """Initialize a InstanceClusterNetworkAttachmentBeforePrototypeInstanceClusterNetworkAttachmentIdentityById object from a json dictionary."""
        args = {}
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in InstanceClusterNetworkAttachmentBeforePrototypeInstanceClusterNetworkAttachmentIdentityById JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceClusterNetworkAttachmentBeforePrototypeInstanceClusterNetworkAttachmentIdentityById object from 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 InstanceClusterNetworkAttachmentBeforePrototypeInstanceClusterNetworkAttachmentIdentityById object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceClusterNetworkAttachmentBeforePrototypeInstanceClusterNetworkAttachmentIdentityById') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceClusterNetworkAttachmentBeforePrototypeInstanceClusterNetworkAttachmentIdentityById') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceClusterNetworkAttachmentPrototypeClusterNetworkInterfaceClusterNetworkInterfaceIdentity(InstanceClusterNetworkAttachmentPrototypeClusterNetworkInterface):
    """
    Identifies a cluster network interface by a unique property.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a InstanceClusterNetworkAttachmentPrototypeClusterNetworkInterfaceClusterNetworkInterfaceIdentity object.

        """
        # pylint: disable=super-init-not-called
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['InstanceClusterNetworkAttachmentPrototypeClusterNetworkInterfaceClusterNetworkInterfaceIdentityClusterNetworkInterfaceIdentityById', 'InstanceClusterNetworkAttachmentPrototypeClusterNetworkInterfaceClusterNetworkInterfaceIdentityClusterNetworkInterfaceIdentityByHref'])
        )
        raise Exception(msg)


class InstanceClusterNetworkAttachmentPrototypeClusterNetworkInterfaceInstanceClusterNetworkInterfacePrototypeInstanceClusterNetworkAttachment(InstanceClusterNetworkAttachmentPrototypeClusterNetworkInterface):
    """
    The cluster network interface for this target.

    :param bool auto_delete: (optional) Indicates whether this cluster network
          interface will be automatically deleted when `target` is deleted.
    :param str name: (optional) The name for this cluster network interface. The
          name must not be used by another interface in the cluster network. Names
          beginning 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 ClusterNetworkInterfacePrimaryIPPrototype primary_ip: (optional) The
          primary IP address to bind to the cluster network interface. May be either
          a cluster network subnet reserved IP identity, or a cluster network subnet
          reserved IP
          prototype object which will be used to create a new cluster network subnet
          reserved IP.
          If a cluster network subnet reserved IP identity is provided, the specified
          cluster
          network subnet reserved IP must be unbound.
          If a cluster network subnet reserved IP prototype object with an address is
          provided,
          the address must be available on the cluster network interface's cluster network
          subnet. If no address is specified, an available address on the cluster network
          subnet
          will be automatically selected and reserved.
    :param ClusterNetworkSubnetIdentity subnet: (optional) The associated cluster
          network subnet. Required if `primary_ip` does not specify a
          cluster network subnet reserved IP identity.
    """

    def __init__(
        self,
        *,
        auto_delete: Optional[bool] = None,
        name: Optional[str] = None,
        primary_ip: Optional['ClusterNetworkInterfacePrimaryIPPrototype'] = None,
        subnet: Optional['ClusterNetworkSubnetIdentity'] = None,
    ) -> None:
        """
        Initialize a InstanceClusterNetworkAttachmentPrototypeClusterNetworkInterfaceInstanceClusterNetworkInterfacePrototypeInstanceClusterNetworkAttachment object.

        :param bool auto_delete: (optional) Indicates whether this cluster network
               interface will be automatically deleted when `target` is deleted.
        :param str name: (optional) The name for this cluster network interface.
               The name must not be used by another interface in the cluster network.
               Names beginning 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 ClusterNetworkInterfacePrimaryIPPrototype primary_ip: (optional) The
               primary IP address to bind to the cluster network interface. May be either
               a cluster network subnet reserved IP identity, or a cluster network subnet
               reserved IP
               prototype object which will be used to create a new cluster network subnet
               reserved IP.
               If a cluster network subnet reserved IP identity is provided, the specified
               cluster
               network subnet reserved IP must be unbound.
               If a cluster network subnet reserved IP prototype object with an address is
               provided,
               the address must be available on the cluster network interface's cluster
               network
               subnet. If no address is specified, an available address on the cluster
               network subnet
               will be automatically selected and reserved.
        :param ClusterNetworkSubnetIdentity subnet: (optional) The associated
               cluster network subnet. Required if `primary_ip` does not specify a
               cluster network subnet reserved IP identity.
        """
        # pylint: disable=super-init-not-called
        self.auto_delete = auto_delete
        self.name = name
        self.primary_ip = primary_ip
        self.subnet = subnet

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceClusterNetworkAttachmentPrototypeClusterNetworkInterfaceInstanceClusterNetworkInterfacePrototypeInstanceClusterNetworkAttachment':
        """Initialize a InstanceClusterNetworkAttachmentPrototypeClusterNetworkInterfaceInstanceClusterNetworkInterfacePrototypeInstanceClusterNetworkAttachment object from a json dictionary."""
        args = {}
        if (auto_delete := _dict.get('auto_delete')) is not None:
            args['auto_delete'] = auto_delete
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        if (primary_ip := _dict.get('primary_ip')) is not None:
            args['primary_ip'] = primary_ip
        if (subnet := _dict.get('subnet')) is not None:
            args['subnet'] = subnet
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceClusterNetworkAttachmentPrototypeClusterNetworkInterfaceInstanceClusterNetworkInterfacePrototypeInstanceClusterNetworkAttachment object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'auto_delete') and self.auto_delete is not None:
            _dict['auto_delete'] = self.auto_delete
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, '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, '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 InstanceClusterNetworkAttachmentPrototypeClusterNetworkInterfaceInstanceClusterNetworkInterfacePrototypeInstanceClusterNetworkAttachment object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceClusterNetworkAttachmentPrototypeClusterNetworkInterfaceInstanceClusterNetworkInterfacePrototypeInstanceClusterNetworkAttachment') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceClusterNetworkAttachmentPrototypeClusterNetworkInterfaceInstanceClusterNetworkInterfacePrototypeInstanceClusterNetworkAttachment') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceGroupManagerActionPrototypeScheduledActionPrototype(InstanceGroupManagerActionPrototype):
    """
    InstanceGroupManagerActionPrototypeScheduledActionPrototype.

    :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.
    """

    def __init__(
        self,
        *,
        name: Optional[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.

    :param bool auto_delete: Indicates whether this scheduled action will be
          automatically deleted after it has completed and `auto_delete_timeout` hours
          have passed.
    :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.
    :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
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :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.
    """

    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: Optional[str] = None,
        last_applied_at: Optional[datetime] = None,
        next_run_at: Optional[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.
        :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.
        :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
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :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
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        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.

    :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.
    """

    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 := _dict.get('created_at')) is not None:
            args['created_at'] = string_to_datetime(created_at)
        else:
            raise ValueError('Required property \'created_at\' not present in InstanceGroupManagerAutoScale JSON')
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in InstanceGroupManagerAutoScale JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in InstanceGroupManagerAutoScale JSON')
        if (management_enabled := _dict.get('management_enabled')) is not None:
            args['management_enabled'] = management_enabled
        else:
            raise ValueError('Required property \'management_enabled\' not present in InstanceGroupManagerAutoScale JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in InstanceGroupManagerAutoScale JSON')
        if (updated_at := _dict.get('updated_at')) is not None:
            args['updated_at'] = string_to_datetime(updated_at)
        else:
            raise ValueError('Required property \'updated_at\' not present in InstanceGroupManagerAutoScale JSON')
        if (aggregation_window := _dict.get('aggregation_window')) is not None:
            args['aggregation_window'] = aggregation_window
        else:
            raise ValueError('Required property \'aggregation_window\' not present in InstanceGroupManagerAutoScale JSON')
        if (cooldown := _dict.get('cooldown')) is not None:
            args['cooldown'] = cooldown
        else:
            raise ValueError('Required property \'cooldown\' not present in InstanceGroupManagerAutoScale JSON')
        if (manager_type := _dict.get('manager_type')) is not None:
            args['manager_type'] = manager_type
        else:
            raise ValueError('Required property \'manager_type\' not present in InstanceGroupManagerAutoScale JSON')
        if (max_membership_count := _dict.get('max_membership_count')) is not None:
            args['max_membership_count'] = max_membership_count
        else:
            raise ValueError('Required property \'max_membership_count\' not present in InstanceGroupManagerAutoScale JSON')
        if (min_membership_count := _dict.get('min_membership_count')) is not None:
            args['min_membership_count'] = min_membership_count
        else:
            raise ValueError('Required property \'min_membership_count\' not present in InstanceGroupManagerAutoScale JSON')
        if (policies := _dict.get('policies')) is not None:
            args['policies'] = [InstanceGroupManagerPolicyReference.from_dict(v) for v in 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.

    :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.
    :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.
    """

    def __init__(
        self,
        metric_type: str,
        metric_value: int,
        policy_type: str,
        *,
        name: Optional[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 := _dict.get('name')) is not None:
            args['name'] = name
        if (metric_type := _dict.get('metric_type')) is not None:
            args['metric_type'] = metric_type
        else:
            raise ValueError('Required property \'metric_type\' not present in InstanceGroupManagerPolicyPrototypeInstanceGroupManagerTargetPolicyPrototype JSON')
        if (metric_value := _dict.get('metric_value')) is not None:
            args['metric_value'] = metric_value
        else:
            raise ValueError('Required property \'metric_value\' not present in InstanceGroupManagerPolicyPrototypeInstanceGroupManagerTargetPolicyPrototype JSON')
        if (policy_type := _dict.get('policy_type')) is not None:
            args['policy_type'] = 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.

    :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
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :param int metric_value: The metric value to be evaluated.
    :param str policy_type: The type of policy for the instance group
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    """

    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
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :param int metric_value: The metric value to be evaluated.
        :param str policy_type: The type of policy for the instance group
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        """
        # 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 := _dict.get('created_at')) is not None:
            args['created_at'] = string_to_datetime(created_at)
        else:
            raise ValueError('Required property \'created_at\' not present in InstanceGroupManagerPolicyInstanceGroupManagerTargetPolicy JSON')
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in InstanceGroupManagerPolicyInstanceGroupManagerTargetPolicy JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in InstanceGroupManagerPolicyInstanceGroupManagerTargetPolicy JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in InstanceGroupManagerPolicyInstanceGroupManagerTargetPolicy JSON')
        if (updated_at := _dict.get('updated_at')) is not None:
            args['updated_at'] = string_to_datetime(updated_at)
        else:
            raise ValueError('Required property \'updated_at\' not present in InstanceGroupManagerPolicyInstanceGroupManagerTargetPolicy JSON')
        if (metric_type := _dict.get('metric_type')) is not None:
            args['metric_type'] = metric_type
        else:
            raise ValueError('Required property \'metric_type\' not present in InstanceGroupManagerPolicyInstanceGroupManagerTargetPolicy JSON')
        if (metric_value := _dict.get('metric_value')) is not None:
            args['metric_value'] = metric_value
        else:
            raise ValueError('Required property \'metric_value\' not present in InstanceGroupManagerPolicyInstanceGroupManagerTargetPolicy JSON')
        if (policy_type := _dict.get('policy_type')) is not None:
            args['policy_type'] = 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
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        CPU = 'cpu'
        MEMORY = 'memory'
        NETWORK_IN = 'network_in'
        NETWORK_OUT = 'network_out'


    class PolicyTypeEnum(str, Enum):
        """
        The type of policy for the instance group
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        TARGET = 'target'



class InstanceGroupManagerPrototypeInstanceGroupManagerAutoScalePrototype(InstanceGroupManagerPrototype):
    """
    InstanceGroupManagerPrototypeInstanceGroupManagerAutoScalePrototype.

    :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 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: (optional) The minimum number of members in a
          managed instance group.
    """

    def __init__(
        self,
        manager_type: str,
        max_membership_count: int,
        *,
        management_enabled: Optional[bool] = None,
        name: Optional[str] = None,
        aggregation_window: Optional[int] = None,
        cooldown: Optional[int] = None,
        min_membership_count: Optional[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 := _dict.get('management_enabled')) is not None:
            args['management_enabled'] = management_enabled
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        if (aggregation_window := _dict.get('aggregation_window')) is not None:
            args['aggregation_window'] = aggregation_window
        if (cooldown := _dict.get('cooldown')) is not None:
            args['cooldown'] = cooldown
        if (manager_type := _dict.get('manager_type')) is not None:
            args['manager_type'] = manager_type
        else:
            raise ValueError('Required property \'manager_type\' not present in InstanceGroupManagerPrototypeInstanceGroupManagerAutoScalePrototype JSON')
        if (max_membership_count := _dict.get('max_membership_count')) is not None:
            args['max_membership_count'] = max_membership_count
        else:
            raise ValueError('Required property \'max_membership_count\' not present in InstanceGroupManagerPrototypeInstanceGroupManagerAutoScalePrototype JSON')
        if (min_membership_count := _dict.get('min_membership_count')) is not None:
            args['min_membership_count'] = 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.

    :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 str manager_type: The type of instance group manager.
    """

    def __init__(
        self,
        manager_type: str,
        *,
        management_enabled: Optional[bool] = None,
        name: Optional[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 := _dict.get('management_enabled')) is not None:
            args['management_enabled'] = management_enabled
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        if (manager_type := _dict.get('manager_type')) is not None:
            args['manager_type'] = 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.

    :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.
    """

    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 := _dict.get('created_at')) is not None:
            args['created_at'] = string_to_datetime(created_at)
        else:
            raise ValueError('Required property \'created_at\' not present in InstanceGroupManagerScheduled JSON')
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in InstanceGroupManagerScheduled JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in InstanceGroupManagerScheduled JSON')
        if (management_enabled := _dict.get('management_enabled')) is not None:
            args['management_enabled'] = management_enabled
        else:
            raise ValueError('Required property \'management_enabled\' not present in InstanceGroupManagerScheduled JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in InstanceGroupManagerScheduled JSON')
        if (updated_at := _dict.get('updated_at')) is not None:
            args['updated_at'] = string_to_datetime(updated_at)
        else:
            raise ValueError('Required property \'updated_at\' not present in InstanceGroupManagerScheduled JSON')
        if (actions := _dict.get('actions')) is not None:
            args['actions'] = [InstanceGroupManagerActionReference.from_dict(v) for v in actions]
        else:
            raise ValueError('Required property \'actions\' not present in InstanceGroupManagerScheduled JSON')
        if (manager_type := _dict.get('manager_type')) is not None:
            args['manager_type'] = 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.

    :param Deleted deleted: (optional) If present, this property indicates the
          referenced resource has been deleted, and provides
          some supplementary information.
    :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 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.
    """

    def __init__(
        self,
        href: str,
        id: str,
        name: str,
        *,
        deleted: Optional['Deleted'] = None,
        max_membership_count: Optional[int] = None,
        min_membership_count: Optional[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 Deleted 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 := _dict.get('deleted')) is not None:
            args['deleted'] = Deleted.from_dict(deleted)
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in InstanceGroupManagerScheduledActionManagerAutoScale JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in InstanceGroupManagerScheduledActionManagerAutoScale JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in InstanceGroupManagerScheduledActionManagerAutoScale JSON')
        if (max_membership_count := _dict.get('max_membership_count')) is not None:
            args['max_membership_count'] = max_membership_count
        if (min_membership_count := _dict.get('min_membership_count')) is not None:
            args['min_membership_count'] = 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`.

    :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.
    """

    def __init__(
        self,
        *,
        max_membership_count: Optional[int] = None,
        min_membership_count: Optional[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 InstanceNetworkAttachmentPrototypeVirtualNetworkInterfaceVirtualNetworkInterfaceIdentity(InstanceNetworkAttachmentPrototypeVirtualNetworkInterface):
    """
    Identifies a virtual network interface by a unique property.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a InstanceNetworkAttachmentPrototypeVirtualNetworkInterfaceVirtualNetworkInterfaceIdentity object.

        """
        # pylint: disable=super-init-not-called
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['InstanceNetworkAttachmentPrototypeVirtualNetworkInterfaceVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityById', 'InstanceNetworkAttachmentPrototypeVirtualNetworkInterfaceVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByHref', 'InstanceNetworkAttachmentPrototypeVirtualNetworkInterfaceVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByCRN'])
        )
        raise Exception(msg)


class InstanceNetworkAttachmentPrototypeVirtualNetworkInterfaceVirtualNetworkInterfacePrototypeInstanceNetworkAttachmentContext(InstanceNetworkAttachmentPrototypeVirtualNetworkInterface):
    """
    The virtual network interface for this target.

    :param bool allow_ip_spoofing: (optional) Indicates whether source IP spoofing
          is allowed on this interface. If `false`, source IP spoofing is prevented on
          this interface. If `true`, source IP spoofing is allowed on this interface.
    :param bool auto_delete: (optional) Indicates whether this virtual network
          interface will be automatically deleted when
          `target` is deleted.
    :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 virtual network interface,
            allowing the workload to perform any needed NAT operations.
          - `allow_ip_spoofing` must be `false`.
          - Can only be attached to a `target` with a `resource_type` of
            `bare_metal_server_network_attachment`.
    :param List[VirtualNetworkInterfaceIPPrototype] ips: (optional) Additional IP
          addresses to bind to the virtual network interface. Each item may be either a
          reserved IP identity, or a reserved IP prototype object which will be used to
          create a new reserved IP. All IP addresses must be in the primary IP's subnet.
          If reserved IP identities are provided, the specified reserved IPs must be
          unbound.
          If reserved IP prototype objects with addresses are provided, the addresses must
          be available on the virtual network interface's subnet. For any prototype
          objects that do not specify an address, an available address on the subnet will
          be automatically selected and reserved.
    :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 str protocol_state_filtering_mode: (optional) The protocol state
          filtering mode to use for this virtual network interface. If
          `auto`, protocol state packet filtering is enabled or disabled based on the
          virtual network interface's `target` resource type:
          - `bare_metal_server_network_attachment`: disabled
          - `instance_network_attachment`: enabled
          - `share_mount_target`: enabled
          Protocol state filtering monitors each network connection flowing over this
          virtual network interface, and drops any packets that are invalid based on the
          current connection state and protocol. See [Protocol state filtering
          mode](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#protocol-state-filtering)
          for more information.
    :param ResourceGroupIdentity resource_group: (optional) The resource group to
          use for this virtual network interface. If unspecified, the
          virtual server instance'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.
    """

    def __init__(
        self,
        *,
        allow_ip_spoofing: Optional[bool] = None,
        auto_delete: Optional[bool] = None,
        enable_infrastructure_nat: Optional[bool] = None,
        ips: Optional[List['VirtualNetworkInterfaceIPPrototype']] = None,
        name: Optional[str] = None,
        primary_ip: Optional['VirtualNetworkInterfacePrimaryIPPrototype'] = None,
        protocol_state_filtering_mode: Optional[str] = None,
        resource_group: Optional['ResourceGroupIdentity'] = None,
        security_groups: Optional[List['SecurityGroupIdentity']] = None,
        subnet: Optional['SubnetIdentity'] = None,
    ) -> None:
        """
        Initialize a InstanceNetworkAttachmentPrototypeVirtualNetworkInterfaceVirtualNetworkInterfacePrototypeInstanceNetworkAttachmentContext object.

        :param bool allow_ip_spoofing: (optional) Indicates whether source IP
               spoofing is allowed on this interface. If `false`, source IP spoofing is
               prevented on this interface. If `true`, source IP spoofing is allowed on
               this interface.
        :param bool auto_delete: (optional) Indicates whether this virtual network
               interface will be automatically deleted when
               `target` is deleted.
        :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 virtual network interface,
                 allowing the workload to perform any needed NAT operations.
               - `allow_ip_spoofing` must be `false`.
               - Can only be attached to a `target` with a `resource_type` of
                 `bare_metal_server_network_attachment`.
        :param List[VirtualNetworkInterfaceIPPrototype] ips: (optional) Additional
               IP addresses to bind to the virtual network interface. Each item may be
               either a reserved IP identity, or a reserved IP prototype object which will
               be used to create a new reserved IP. All IP addresses must be in the
               primary IP's subnet.
               If reserved IP identities are provided, the specified reserved IPs must be
               unbound.
               If reserved IP prototype objects with addresses are provided, the addresses
               must be available on the virtual network interface's subnet. For any
               prototype objects that do not specify an address, an available address on
               the subnet will be automatically selected and reserved.
        :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 str protocol_state_filtering_mode: (optional) The protocol state
               filtering mode to use for this virtual network interface. If
               `auto`, protocol state packet filtering is enabled or disabled based on the
               virtual network interface's `target` resource type:
               - `bare_metal_server_network_attachment`: disabled
               - `instance_network_attachment`: enabled
               - `share_mount_target`: enabled
               Protocol state filtering monitors each network connection flowing over this
               virtual network interface, and drops any packets that are invalid based on
               the current connection state and protocol. See [Protocol state filtering
               mode](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#protocol-state-filtering)
               for more information.
        :param ResourceGroupIdentity resource_group: (optional) The resource group
               to use for this virtual network interface. If unspecified, the
               virtual server instance'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.allow_ip_spoofing = allow_ip_spoofing
        self.auto_delete = auto_delete
        self.enable_infrastructure_nat = enable_infrastructure_nat
        self.ips = ips
        self.name = name
        self.primary_ip = primary_ip
        self.protocol_state_filtering_mode = protocol_state_filtering_mode
        self.resource_group = resource_group
        self.security_groups = security_groups
        self.subnet = subnet

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceNetworkAttachmentPrototypeVirtualNetworkInterfaceVirtualNetworkInterfacePrototypeInstanceNetworkAttachmentContext':
        """Initialize a InstanceNetworkAttachmentPrototypeVirtualNetworkInterfaceVirtualNetworkInterfacePrototypeInstanceNetworkAttachmentContext object from a json dictionary."""
        args = {}
        if (allow_ip_spoofing := _dict.get('allow_ip_spoofing')) is not None:
            args['allow_ip_spoofing'] = allow_ip_spoofing
        if (auto_delete := _dict.get('auto_delete')) is not None:
            args['auto_delete'] = auto_delete
        if (enable_infrastructure_nat := _dict.get('enable_infrastructure_nat')) is not None:
            args['enable_infrastructure_nat'] = enable_infrastructure_nat
        if (ips := _dict.get('ips')) is not None:
            args['ips'] = ips
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        if (primary_ip := _dict.get('primary_ip')) is not None:
            args['primary_ip'] = primary_ip
        if (protocol_state_filtering_mode := _dict.get('protocol_state_filtering_mode')) is not None:
            args['protocol_state_filtering_mode'] = protocol_state_filtering_mode
        if (resource_group := _dict.get('resource_group')) is not None:
            args['resource_group'] = resource_group
        if (security_groups := _dict.get('security_groups')) is not None:
            args['security_groups'] = security_groups
        if (subnet := _dict.get('subnet')) is not None:
            args['subnet'] = subnet
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceNetworkAttachmentPrototypeVirtualNetworkInterfaceVirtualNetworkInterfacePrototypeInstanceNetworkAttachmentContext object from 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, 'auto_delete') and self.auto_delete is not None:
            _dict['auto_delete'] = self.auto_delete
        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, '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, '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, 'protocol_state_filtering_mode') and self.protocol_state_filtering_mode is not None:
            _dict['protocol_state_filtering_mode'] = self.protocol_state_filtering_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, '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 InstanceNetworkAttachmentPrototypeVirtualNetworkInterfaceVirtualNetworkInterfacePrototypeInstanceNetworkAttachmentContext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceNetworkAttachmentPrototypeVirtualNetworkInterfaceVirtualNetworkInterfacePrototypeInstanceNetworkAttachmentContext') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceNetworkAttachmentPrototypeVirtualNetworkInterfaceVirtualNetworkInterfacePrototypeInstanceNetworkAttachmentContext') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ProtocolStateFilteringModeEnum(str, Enum):
        """
        The protocol state filtering mode to use for this virtual network interface. If
        `auto`, protocol state packet filtering is enabled or disabled based on the
        virtual network interface's `target` resource type:
        - `bare_metal_server_network_attachment`: disabled
        - `instance_network_attachment`: enabled
        - `share_mount_target`: enabled
        Protocol state filtering monitors each network connection flowing over this
        virtual network interface, and drops any packets that are invalid based on the
        current connection state and protocol. See [Protocol state filtering
        mode](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#protocol-state-filtering)
        for more information.
        """

        AUTO = 'auto'
        DISABLED = 'disabled'
        ENABLED = 'enabled'



class InstancePatchProfileInstanceProfileIdentityByHref(InstancePatchProfile):
    """
    InstancePatchProfileInstanceProfileIdentityByHref.

    :param 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 := _dict.get('href')) is not None:
            args['href'] = 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.

    :param 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 := _dict.get('name')) is not None:
            args['name'] = 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.

    :param str crn: The CRN for this dedicated host group.
    :param Deleted deleted: (optional) If present, this property indicates the
          referenced resource has been deleted, and provides
          some supplementary information.
    :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.
    """

    def __init__(
        self,
        crn: str,
        href: str,
        id: str,
        name: str,
        resource_type: str,
        *,
        deleted: Optional['Deleted'] = 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 Deleted 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 := _dict.get('crn')) is not None:
            args['crn'] = crn
        else:
            raise ValueError('Required property \'crn\' not present in InstancePlacementTargetDedicatedHostGroupReference JSON')
        if (deleted := _dict.get('deleted')) is not None:
            args['deleted'] = Deleted.from_dict(deleted)
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in InstancePlacementTargetDedicatedHostGroupReference JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in InstancePlacementTargetDedicatedHostGroupReference JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in InstancePlacementTargetDedicatedHostGroupReference JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = 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.

    :param str crn: The CRN for this dedicated host.
    :param Deleted deleted: (optional) If present, this property indicates the
          referenced resource has been deleted, and provides
          some supplementary information.
    :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.
    """

    def __init__(
        self,
        crn: str,
        href: str,
        id: str,
        name: str,
        resource_type: str,
        *,
        deleted: Optional['Deleted'] = 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 Deleted 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 := _dict.get('crn')) is not None:
            args['crn'] = crn
        else:
            raise ValueError('Required property \'crn\' not present in InstancePlacementTargetDedicatedHostReference JSON')
        if (deleted := _dict.get('deleted')) is not None:
            args['deleted'] = Deleted.from_dict(deleted)
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in InstancePlacementTargetDedicatedHostReference JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in InstancePlacementTargetDedicatedHostReference JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in InstancePlacementTargetDedicatedHostReference JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = 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.

    :param str crn: The CRN for this placement group.
    :param Deleted deleted: (optional) If present, this property indicates the
          referenced resource has been deleted, and provides
          some supplementary information.
    :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.
    """

    def __init__(
        self,
        crn: str,
        href: str,
        id: str,
        name: str,
        resource_type: str,
        *,
        deleted: Optional['Deleted'] = 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 Deleted 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 := _dict.get('crn')) is not None:
            args['crn'] = crn
        else:
            raise ValueError('Required property \'crn\' not present in InstancePlacementTargetPlacementGroupReference JSON')
        if (deleted := _dict.get('deleted')) is not None:
            args['deleted'] = Deleted.from_dict(deleted)
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in InstancePlacementTargetPlacementGroupReference JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in InstancePlacementTargetPlacementGroupReference JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in InstancePlacementTargetPlacementGroupReference JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = 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 attachments or network interfaces and
    storage volumes of an instance with this profile depends on its configuration.

    :param 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 := _dict.get('type')) is not None:
            args['type'] = 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 attachments or network interfaces and storage volumes of an instance with this
    profile.

    :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.
    """

    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 := _dict.get('default')) is not None:
            args['default'] = default
        else:
            raise ValueError('Required property \'default\' not present in InstanceProfileBandwidthEnum JSON')
        if (type := _dict.get('type')) is not None:
            args['type'] = type
        else:
            raise ValueError('Required property \'type\' not present in InstanceProfileBandwidthEnum JSON')
        if (values := _dict.get('values')) is not None:
            args['values'] = 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 attachments or
    network interfaces and storage volumes of an instance with this profile.

    :param str type: The type for this profile field.
    :param 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 := _dict.get('type')) is not None:
            args['type'] = type
        else:
            raise ValueError('Required property \'type\' not present in InstanceProfileBandwidthFixed JSON')
        if (value := _dict.get('value')) is not None:
            args['value'] = 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
    attachments or network interfaces and storage volumes of an instance with this
    profile.

    :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.
    """

    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 := _dict.get('default')) is not None:
            args['default'] = default
        else:
            raise ValueError('Required property \'default\' not present in InstanceProfileBandwidthRange JSON')
        if (max := _dict.get('max')) is not None:
            args['max'] = max
        else:
            raise ValueError('Required property \'max\' not present in InstanceProfileBandwidthRange JSON')
        if (min := _dict.get('min')) is not None:
            args['min'] = min
        else:
            raise ValueError('Required property \'min\' not present in InstanceProfileBandwidthRange JSON')
        if (step := _dict.get('step')) is not None:
            args['step'] = step
        else:
            raise ValueError('Required property \'step\' not present in InstanceProfileBandwidthRange JSON')
        if (type := _dict.get('type')) is not None:
            args['type'] = 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 InstanceProfileClusterNetworkAttachmentCountDependent(InstanceProfileClusterNetworkAttachmentCount):
    """
    The number of cluster network attachments supported on an instance with this profile
    is dependent on its configuration.

    :param str type: The type for this profile field.
    """

    def __init__(
        self,
        type: str,
    ) -> None:
        """
        Initialize a InstanceProfileClusterNetworkAttachmentCountDependent 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) -> 'InstanceProfileClusterNetworkAttachmentCountDependent':
        """Initialize a InstanceProfileClusterNetworkAttachmentCountDependent object from a json dictionary."""
        args = {}
        if (type := _dict.get('type')) is not None:
            args['type'] = type
        else:
            raise ValueError('Required property \'type\' not present in InstanceProfileClusterNetworkAttachmentCountDependent JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceProfileClusterNetworkAttachmentCountDependent object from 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 InstanceProfileClusterNetworkAttachmentCountDependent object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceProfileClusterNetworkAttachmentCountDependent') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceProfileClusterNetworkAttachmentCountDependent') -> 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 InstanceProfileClusterNetworkAttachmentCountEnum(InstanceProfileClusterNetworkAttachmentCount):
    """
    The permitted values for cluster network attachment count for an instance with this
    profile.

    :param int default: (optional)
    :param str type: The type for this profile field.
    :param List[int] values: The permitted values for this profile field.
    """

    def __init__(
        self,
        type: str,
        values: List[int],
        *,
        default: Optional[int] = None,
    ) -> None:
        """
        Initialize a InstanceProfileClusterNetworkAttachmentCountEnum object.

        :param str type: The type for this profile field.
        :param List[int] values: The permitted values for this profile field.
        :param int default: (optional)
        """
        # pylint: disable=super-init-not-called
        self.default = default
        self.type = type
        self.values = values

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceProfileClusterNetworkAttachmentCountEnum':
        """Initialize a InstanceProfileClusterNetworkAttachmentCountEnum object from a json dictionary."""
        args = {}
        if (default := _dict.get('default')) is not None:
            args['default'] = default
        if (type := _dict.get('type')) is not None:
            args['type'] = type
        else:
            raise ValueError('Required property \'type\' not present in InstanceProfileClusterNetworkAttachmentCountEnum JSON')
        if (values := _dict.get('values')) is not None:
            args['values'] = values
        else:
            raise ValueError('Required property \'values\' not present in InstanceProfileClusterNetworkAttachmentCountEnum JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceProfileClusterNetworkAttachmentCountEnum object from 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 InstanceProfileClusterNetworkAttachmentCountEnum object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceProfileClusterNetworkAttachmentCountEnum') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceProfileClusterNetworkAttachmentCountEnum') -> 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 InstanceProfileClusterNetworkAttachmentCountRange(InstanceProfileClusterNetworkAttachmentCount):
    """
    The number of network attachments supported on an instance with this profile.

    :param int max: (optional) The maximum value for this profile field.
    :param int min: (optional) The minimum value for this profile field.
    :param int step: (optional)
    :param str type: The type for this profile field.
    """

    def __init__(
        self,
        type: str,
        *,
        max: Optional[int] = None,
        min: Optional[int] = None,
        step: Optional[int] = None,
    ) -> None:
        """
        Initialize a InstanceProfileClusterNetworkAttachmentCountRange 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.
        :param int step: (optional)
        """
        # 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) -> 'InstanceProfileClusterNetworkAttachmentCountRange':
        """Initialize a InstanceProfileClusterNetworkAttachmentCountRange object from a json dictionary."""
        args = {}
        if (max := _dict.get('max')) is not None:
            args['max'] = max
        if (min := _dict.get('min')) is not None:
            args['min'] = min
        if (step := _dict.get('step')) is not None:
            args['step'] = step
        if (type := _dict.get('type')) is not None:
            args['type'] = type
        else:
            raise ValueError('Required property \'type\' not present in InstanceProfileClusterNetworkAttachmentCountRange JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceProfileClusterNetworkAttachmentCountRange object from 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 InstanceProfileClusterNetworkAttachmentCountRange object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceProfileClusterNetworkAttachmentCountRange') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceProfileClusterNetworkAttachmentCountRange') -> 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.

    :param 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 := _dict.get('type')) is not None:
            args['type'] = 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.

    :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.
    """

    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 := _dict.get('default')) is not None:
            args['default'] = default
        else:
            raise ValueError('Required property \'default\' not present in InstanceProfileDiskQuantityEnum JSON')
        if (type := _dict.get('type')) is not None:
            args['type'] = type
        else:
            raise ValueError('Required property \'type\' not present in InstanceProfileDiskQuantityEnum JSON')
        if (values := _dict.get('values')) is not None:
            args['values'] = 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.

    :param str type: The type for this profile field.
    :param 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 := _dict.get('type')) is not None:
            args['type'] = type
        else:
            raise ValueError('Required property \'type\' not present in InstanceProfileDiskQuantityFixed JSON')
        if (value := _dict.get('value')) is not None:
            args['value'] = 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.

    :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.
    """

    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 := _dict.get('default')) is not None:
            args['default'] = default
        else:
            raise ValueError('Required property \'default\' not present in InstanceProfileDiskQuantityRange JSON')
        if (max := _dict.get('max')) is not None:
            args['max'] = max
        else:
            raise ValueError('Required property \'max\' not present in InstanceProfileDiskQuantityRange JSON')
        if (min := _dict.get('min')) is not None:
            args['min'] = min
        else:
            raise ValueError('Required property \'min\' not present in InstanceProfileDiskQuantityRange JSON')
        if (step := _dict.get('step')) is not None:
            args['step'] = step
        else:
            raise ValueError('Required property \'step\' not present in InstanceProfileDiskQuantityRange JSON')
        if (type := _dict.get('type')) is not None:
            args['type'] = 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.

    :param 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 := _dict.get('type')) is not None:
            args['type'] = 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.

    :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.
    """

    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 := _dict.get('default')) is not None:
            args['default'] = default
        else:
            raise ValueError('Required property \'default\' not present in InstanceProfileDiskSizeEnum JSON')
        if (type := _dict.get('type')) is not None:
            args['type'] = type
        else:
            raise ValueError('Required property \'type\' not present in InstanceProfileDiskSizeEnum JSON')
        if (values := _dict.get('values')) is not None:
            args['values'] = 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).

    :param str type: The type for this profile field.
    :param 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 := _dict.get('type')) is not None:
            args['type'] = type
        else:
            raise ValueError('Required property \'type\' not present in InstanceProfileDiskSizeFixed JSON')
        if (value := _dict.get('value')) is not None:
            args['value'] = 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.

    :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.
    """

    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 := _dict.get('default')) is not None:
            args['default'] = default
        else:
            raise ValueError('Required property \'default\' not present in InstanceProfileDiskSizeRange JSON')
        if (max := _dict.get('max')) is not None:
            args['max'] = max
        else:
            raise ValueError('Required property \'max\' not present in InstanceProfileDiskSizeRange JSON')
        if (min := _dict.get('min')) is not None:
            args['min'] = min
        else:
            raise ValueError('Required property \'min\' not present in InstanceProfileDiskSizeRange JSON')
        if (step := _dict.get('step')) is not None:
            args['step'] = step
        else:
            raise ValueError('Required property \'step\' not present in InstanceProfileDiskSizeRange JSON')
        if (type := _dict.get('type')) is not None:
            args['type'] = 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.

    :param 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 := _dict.get('type')) is not None:
            args['type'] = 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.

    :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.
    """

    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 := _dict.get('default')) is not None:
            args['default'] = default
        else:
            raise ValueError('Required property \'default\' not present in InstanceProfileGPUEnum JSON')
        if (type := _dict.get('type')) is not None:
            args['type'] = type
        else:
            raise ValueError('Required property \'type\' not present in InstanceProfileGPUEnum JSON')
        if (values := _dict.get('values')) is not None:
            args['values'] = 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.

    :param str type: The type for this profile field.
    :param 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 := _dict.get('type')) is not None:
            args['type'] = type
        else:
            raise ValueError('Required property \'type\' not present in InstanceProfileGPUFixed JSON')
        if (value := _dict.get('value')) is not None:
            args['value'] = 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.

    :param 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 := _dict.get('type')) is not None:
            args['type'] = 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.

    :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.
    """

    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 := _dict.get('default')) is not None:
            args['default'] = default
        else:
            raise ValueError('Required property \'default\' not present in InstanceProfileGPUMemoryEnum JSON')
        if (type := _dict.get('type')) is not None:
            args['type'] = type
        else:
            raise ValueError('Required property \'type\' not present in InstanceProfileGPUMemoryEnum JSON')
        if (values := _dict.get('values')) is not None:
            args['values'] = 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.

    :param str type: The type for this profile field.
    :param 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 := _dict.get('type')) is not None:
            args['type'] = type
        else:
            raise ValueError('Required property \'type\' not present in InstanceProfileGPUMemoryFixed JSON')
        if (value := _dict.get('value')) is not None:
            args['value'] = 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.

    :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.
    """

    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 := _dict.get('default')) is not None:
            args['default'] = default
        else:
            raise ValueError('Required property \'default\' not present in InstanceProfileGPUMemoryRange JSON')
        if (max := _dict.get('max')) is not None:
            args['max'] = max
        else:
            raise ValueError('Required property \'max\' not present in InstanceProfileGPUMemoryRange JSON')
        if (min := _dict.get('min')) is not None:
            args['min'] = min
        else:
            raise ValueError('Required property \'min\' not present in InstanceProfileGPUMemoryRange JSON')
        if (step := _dict.get('step')) is not None:
            args['step'] = step
        else:
            raise ValueError('Required property \'step\' not present in InstanceProfileGPUMemoryRange JSON')
        if (type := _dict.get('type')) is not None:
            args['type'] = 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.

    :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.
    """

    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 := _dict.get('default')) is not None:
            args['default'] = default
        else:
            raise ValueError('Required property \'default\' not present in InstanceProfileGPURange JSON')
        if (max := _dict.get('max')) is not None:
            args['max'] = max
        else:
            raise ValueError('Required property \'max\' not present in InstanceProfileGPURange JSON')
        if (min := _dict.get('min')) is not None:
            args['min'] = min
        else:
            raise ValueError('Required property \'min\' not present in InstanceProfileGPURange JSON')
        if (step := _dict.get('step')) is not None:
            args['step'] = step
        else:
            raise ValueError('Required property \'step\' not present in InstanceProfileGPURange JSON')
        if (type := _dict.get('type')) is not None:
            args['type'] = 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.

    :param 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 := _dict.get('href')) is not None:
            args['href'] = 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.

    :param 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 := _dict.get('name')) is not None:
            args['name'] = 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.

    :param 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 := _dict.get('type')) is not None:
            args['type'] = 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.

    :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.
    """

    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 := _dict.get('default')) is not None:
            args['default'] = default
        else:
            raise ValueError('Required property \'default\' not present in InstanceProfileMemoryEnum JSON')
        if (type := _dict.get('type')) is not None:
            args['type'] = type
        else:
            raise ValueError('Required property \'type\' not present in InstanceProfileMemoryEnum JSON')
        if (values := _dict.get('values')) is not None:
            args['values'] = 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.

    :param str type: The type for this profile field.
    :param 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 := _dict.get('type')) is not None:
            args['type'] = type
        else:
            raise ValueError('Required property \'type\' not present in InstanceProfileMemoryFixed JSON')
        if (value := _dict.get('value')) is not None:
            args['value'] = 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.

    :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.
    """

    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 := _dict.get('default')) is not None:
            args['default'] = default
        else:
            raise ValueError('Required property \'default\' not present in InstanceProfileMemoryRange JSON')
        if (max := _dict.get('max')) is not None:
            args['max'] = max
        else:
            raise ValueError('Required property \'max\' not present in InstanceProfileMemoryRange JSON')
        if (min := _dict.get('min')) is not None:
            args['min'] = min
        else:
            raise ValueError('Required property \'min\' not present in InstanceProfileMemoryRange JSON')
        if (step := _dict.get('step')) is not None:
            args['step'] = step
        else:
            raise ValueError('Required property \'step\' not present in InstanceProfileMemoryRange JSON')
        if (type := _dict.get('type')) is not None:
            args['type'] = 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.

    :param 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 := _dict.get('type')) is not None:
            args['type'] = 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.

    :param str type: The type for this profile field.
    :param 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 := _dict.get('type')) is not None:
            args['type'] = type
        else:
            raise ValueError('Required property \'type\' not present in InstanceProfileNUMACountFixed JSON')
        if (value := _dict.get('value')) is not None:
            args['value'] = 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 InstanceProfileNetworkAttachmentCountDependent(InstanceProfileNetworkAttachmentCount):
    """
    The number of network attachments supported on an instance with this profile is
    dependent on its configuration.

    :param str type: The type for this profile field.
    """

    def __init__(
        self,
        type: str,
    ) -> None:
        """
        Initialize a InstanceProfileNetworkAttachmentCountDependent 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) -> 'InstanceProfileNetworkAttachmentCountDependent':
        """Initialize a InstanceProfileNetworkAttachmentCountDependent object from a json dictionary."""
        args = {}
        if (type := _dict.get('type')) is not None:
            args['type'] = type
        else:
            raise ValueError('Required property \'type\' not present in InstanceProfileNetworkAttachmentCountDependent JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceProfileNetworkAttachmentCountDependent object from 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 InstanceProfileNetworkAttachmentCountDependent object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceProfileNetworkAttachmentCountDependent') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceProfileNetworkAttachmentCountDependent') -> 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 InstanceProfileNetworkAttachmentCountRange(InstanceProfileNetworkAttachmentCount):
    """
    The number of network attachments supported on an instance with this profile.

    :param int max: (optional) The maximum value for this profile field.
    :param int min: (optional) The minimum value for this profile field.
    :param str type: The type for this profile field.
    """

    def __init__(
        self,
        type: str,
        *,
        max: Optional[int] = None,
        min: Optional[int] = None,
    ) -> None:
        """
        Initialize a InstanceProfileNetworkAttachmentCountRange 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) -> 'InstanceProfileNetworkAttachmentCountRange':
        """Initialize a InstanceProfileNetworkAttachmentCountRange object from a json dictionary."""
        args = {}
        if (max := _dict.get('max')) is not None:
            args['max'] = max
        if (min := _dict.get('min')) is not None:
            args['min'] = min
        if (type := _dict.get('type')) is not None:
            args['type'] = type
        else:
            raise ValueError('Required property \'type\' not present in InstanceProfileNetworkAttachmentCountRange JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceProfileNetworkAttachmentCountRange object from 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 InstanceProfileNetworkAttachmentCountRange object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceProfileNetworkAttachmentCountRange') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceProfileNetworkAttachmentCountRange') -> 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 InstanceProfileNetworkInterfaceCountDependent(InstanceProfileNetworkInterfaceCount):
    """
    The number of network interfaces supported on an instance with this profile is
    dependent on its configuration.

    :param 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 := _dict.get('type')) is not None:
            args['type'] = 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.

    :param int max: (optional) The maximum value for this profile field.
    :param int min: (optional) The minimum value for this profile field.
    :param str type: The type for this profile field.
    """

    def __init__(
        self,
        type: str,
        *,
        max: Optional[int] = None,
        min: Optional[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 := _dict.get('max')) is not None:
            args['max'] = max
        if (min := _dict.get('min')) is not None:
            args['min'] = min
        if (type := _dict.get('type')) is not None:
            args['type'] = 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.

    :param 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 := _dict.get('type')) is not None:
            args['type'] = 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.

    :param str type: The type for this profile field.
    :param 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 := _dict.get('type')) is not None:
            args['type'] = type
        else:
            raise ValueError('Required property \'type\' not present in InstanceProfilePortSpeedFixed JSON')
        if (value := _dict.get('value')) is not None:
            args['value'] = 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.

    :param 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 := _dict.get('type')) is not None:
            args['type'] = 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.

    :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.
    """

    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 := _dict.get('default')) is not None:
            args['default'] = default
        else:
            raise ValueError('Required property \'default\' not present in InstanceProfileVCPUEnum JSON')
        if (type := _dict.get('type')) is not None:
            args['type'] = type
        else:
            raise ValueError('Required property \'type\' not present in InstanceProfileVCPUEnum JSON')
        if (values := _dict.get('values')) is not None:
            args['values'] = 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.

    :param str type: The type for this profile field.
    :param 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 := _dict.get('type')) is not None:
            args['type'] = type
        else:
            raise ValueError('Required property \'type\' not present in InstanceProfileVCPUFixed JSON')
        if (value := _dict.get('value')) is not None:
            args['value'] = 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.

    :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.
    """

    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 := _dict.get('default')) is not None:
            args['default'] = default
        else:
            raise ValueError('Required property \'default\' not present in InstanceProfileVCPURange JSON')
        if (max := _dict.get('max')) is not None:
            args['max'] = max
        else:
            raise ValueError('Required property \'max\' not present in InstanceProfileVCPURange JSON')
        if (min := _dict.get('min')) is not None:
            args['min'] = min
        else:
            raise ValueError('Required property \'min\' not present in InstanceProfileVCPURange JSON')
        if (step := _dict.get('step')) is not None:
            args['step'] = step
        else:
            raise ValueError('Required property \'step\' not present in InstanceProfileVCPURange JSON')
        if (type := _dict.get('type')) is not None:
            args['type'] = 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.

    :param 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 := _dict.get('type')) is not None:
            args['type'] = 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.

    :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.
    """

    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 := _dict.get('default')) is not None:
            args['default'] = default
        else:
            raise ValueError('Required property \'default\' not present in InstanceProfileVolumeBandwidthEnum JSON')
        if (type := _dict.get('type')) is not None:
            args['type'] = type
        else:
            raise ValueError('Required property \'type\' not present in InstanceProfileVolumeBandwidthEnum JSON')
        if (values := _dict.get('values')) is not None:
            args['values'] = 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.

    :param str type: The type for this profile field.
    :param 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 := _dict.get('type')) is not None:
            args['type'] = type
        else:
            raise ValueError('Required property \'type\' not present in InstanceProfileVolumeBandwidthFixed JSON')
        if (value := _dict.get('value')) is not None:
            args['value'] = 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.

    :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.
    """

    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 := _dict.get('default')) is not None:
            args['default'] = default
        else:
            raise ValueError('Required property \'default\' not present in InstanceProfileVolumeBandwidthRange JSON')
        if (max := _dict.get('max')) is not None:
            args['max'] = max
        else:
            raise ValueError('Required property \'max\' not present in InstanceProfileVolumeBandwidthRange JSON')
        if (min := _dict.get('min')) is not None:
            args['min'] = min
        else:
            raise ValueError('Required property \'min\' not present in InstanceProfileVolumeBandwidthRange JSON')
        if (step := _dict.get('step')) is not None:
            args['step'] = step
        else:
            raise ValueError('Required property \'step\' not present in InstanceProfileVolumeBandwidthRange JSON')
        if (type := _dict.get('type')) is not None:
            args['type'] = 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.

    :param InstanceAvailabilityPolicyPrototype availability_policy: (optional) The
          availability policy to use for this virtual server instance.
    :param List[InstanceClusterNetworkAttachmentPrototypeInstanceContext]
          cluster_network_attachments: (optional) The cluster network attachments to
          create for this virtual server instance. A cluster network attachment represents
          a device that is connected to a cluster network. The number of network
          attachments must match one of the values from the instance profile's
          `cluster_network_attachment_count` before the instance can be started.
    :param str confidential_compute_mode: (optional) The confidential compute mode
          to use for this virtual server instance.
          If unspecified, the default confidential compute mode from the profile will be
          used.
    :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 bool enable_secure_boot: (optional) Indicates whether secure boot is
          enabled for this virtual server instance.
          If unspecified, the default secure boot mode from the profile will be used.
    :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.
          If specified, `reservation_affinity.policy` must be `disabled`.
    :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 InstanceReservationAffinityPrototype reservation_affinity: (optional)
    :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
          attachments or instance network interfaces.
    :param VolumeAttachmentPrototypeInstanceByImageContext boot_volume_attachment:
          (optional) The boot volume attachment to create for the virtual server instance.
    :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,
          subject
          to IAM policies.
    :param ZoneIdentity zone: The zone this virtual server instance will reside in.
    """

    def __init__(
        self,
        catalog_offering: 'InstanceCatalogOfferingPrototype',
        zone: 'ZoneIdentity',
        *,
        availability_policy: Optional['InstanceAvailabilityPolicyPrototype'] = None,
        cluster_network_attachments: Optional[List['InstanceClusterNetworkAttachmentPrototypeInstanceContext']] = None,
        confidential_compute_mode: Optional[str] = None,
        default_trusted_profile: Optional['InstanceDefaultTrustedProfilePrototype'] = None,
        enable_secure_boot: Optional[bool] = None,
        keys: Optional[List['KeyIdentity']] = None,
        metadata_service: Optional['InstanceMetadataServicePrototype'] = None,
        name: Optional[str] = None,
        placement_target: Optional['InstancePlacementTargetPrototype'] = None,
        profile: Optional['InstanceProfileIdentity'] = None,
        reservation_affinity: Optional['InstanceReservationAffinityPrototype'] = None,
        resource_group: Optional['ResourceGroupIdentity'] = None,
        total_volume_bandwidth: Optional[int] = None,
        user_data: Optional[str] = None,
        volume_attachments: Optional[List['VolumeAttachmentPrototype']] = None,
        vpc: Optional['VPCIdentity'] = None,
        boot_volume_attachment: Optional['VolumeAttachmentPrototypeInstanceByImageContext'] = 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,
               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 List[InstanceClusterNetworkAttachmentPrototypeInstanceContext]
               cluster_network_attachments: (optional) The cluster network attachments to
               create for this virtual server instance. A cluster network attachment
               represents a device that is connected to a cluster network. The number of
               network attachments must match one of the values from the instance
               profile's `cluster_network_attachment_count` before the instance can be
               started.
        :param str confidential_compute_mode: (optional) The confidential compute
               mode to use for this virtual server instance.
               If unspecified, the default confidential compute mode from the profile will
               be used.
        :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 bool enable_secure_boot: (optional) Indicates whether secure boot is
               enabled for this virtual server instance.
               If unspecified, the default secure boot mode from the profile will be used.
        :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.
               If specified, `reservation_affinity.policy` must be `disabled`.
        :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 InstanceReservationAffinityPrototype reservation_affinity:
               (optional)
        :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
               attachments or instance network interfaces.
        :param VolumeAttachmentPrototypeInstanceByImageContext
               boot_volume_attachment: (optional) The boot volume attachment to create for
               the virtual server instance.
        """
        # pylint: disable=super-init-not-called
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['InstancePrototypeInstanceByCatalogOfferingInstanceByCatalogOfferingInstanceByNetworkAttachment', 'InstancePrototypeInstanceByCatalogOfferingInstanceByCatalogOfferingInstanceByNetworkInterface'])
        )
        raise Exception(msg)

    class ConfidentialComputeModeEnum(str, Enum):
        """
        The confidential compute mode to use for this virtual server instance.
        If unspecified, the default confidential compute mode from the profile will be
        used.
        """

        DISABLED = 'disabled'
        SGX = 'sgx'



class InstancePrototypeInstanceByImage(InstancePrototype):
    """
    Create an instance by using an image.
    The image's `user_data_format` must be `cloud_init`.

    :param InstanceAvailabilityPolicyPrototype availability_policy: (optional) The
          availability policy to use for this virtual server instance.
    :param List[InstanceClusterNetworkAttachmentPrototypeInstanceContext]
          cluster_network_attachments: (optional) The cluster network attachments to
          create for this virtual server instance. A cluster network attachment represents
          a device that is connected to a cluster network. The number of network
          attachments must match one of the values from the instance profile's
          `cluster_network_attachment_count` before the instance can be started.
    :param str confidential_compute_mode: (optional) The confidential compute mode
          to use for this virtual server instance.
          If unspecified, the default confidential compute mode from the profile will be
          used.
    :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 bool enable_secure_boot: (optional) Indicates whether secure boot is
          enabled for this virtual server instance.
          If unspecified, the default secure boot mode from the profile will be used.
    :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.
          If specified, `reservation_affinity.policy` must be `disabled`.
    :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 InstanceReservationAffinityPrototype reservation_affinity: (optional)
    :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
          attachments or instance network interfaces.
    :param VolumeAttachmentPrototypeInstanceByImageContext boot_volume_attachment:
          (optional) The boot volume attachment to create for the virtual server instance.
    :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.
    """

    def __init__(
        self,
        image: 'ImageIdentity',
        zone: 'ZoneIdentity',
        *,
        availability_policy: Optional['InstanceAvailabilityPolicyPrototype'] = None,
        cluster_network_attachments: Optional[List['InstanceClusterNetworkAttachmentPrototypeInstanceContext']] = None,
        confidential_compute_mode: Optional[str] = None,
        default_trusted_profile: Optional['InstanceDefaultTrustedProfilePrototype'] = None,
        enable_secure_boot: Optional[bool] = None,
        keys: Optional[List['KeyIdentity']] = None,
        metadata_service: Optional['InstanceMetadataServicePrototype'] = None,
        name: Optional[str] = None,
        placement_target: Optional['InstancePlacementTargetPrototype'] = None,
        profile: Optional['InstanceProfileIdentity'] = None,
        reservation_affinity: Optional['InstanceReservationAffinityPrototype'] = None,
        resource_group: Optional['ResourceGroupIdentity'] = None,
        total_volume_bandwidth: Optional[int] = None,
        user_data: Optional[str] = None,
        volume_attachments: Optional[List['VolumeAttachmentPrototype']] = None,
        vpc: Optional['VPCIdentity'] = None,
        boot_volume_attachment: Optional['VolumeAttachmentPrototypeInstanceByImageContext'] = None,
    ) -> None:
        """
        Initialize a InstancePrototypeInstanceByImage object.

        :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 List[InstanceClusterNetworkAttachmentPrototypeInstanceContext]
               cluster_network_attachments: (optional) The cluster network attachments to
               create for this virtual server instance. A cluster network attachment
               represents a device that is connected to a cluster network. The number of
               network attachments must match one of the values from the instance
               profile's `cluster_network_attachment_count` before the instance can be
               started.
        :param str confidential_compute_mode: (optional) The confidential compute
               mode to use for this virtual server instance.
               If unspecified, the default confidential compute mode from the profile will
               be used.
        :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 bool enable_secure_boot: (optional) Indicates whether secure boot is
               enabled for this virtual server instance.
               If unspecified, the default secure boot mode from the profile will be used.
        :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.
               If specified, `reservation_affinity.policy` must be `disabled`.
        :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 InstanceReservationAffinityPrototype reservation_affinity:
               (optional)
        :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
               attachments or instance network interfaces.
        :param VolumeAttachmentPrototypeInstanceByImageContext
               boot_volume_attachment: (optional) The boot volume attachment to create for
               the virtual server instance.
        """
        # pylint: disable=super-init-not-called
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['InstancePrototypeInstanceByImageInstanceByImageInstanceByNetworkAttachment', 'InstancePrototypeInstanceByImageInstanceByImageInstanceByNetworkInterface'])
        )
        raise Exception(msg)

    class ConfidentialComputeModeEnum(str, Enum):
        """
        The confidential compute mode to use for this virtual server instance.
        If unspecified, the default confidential compute mode from the profile will be
        used.
        """

        DISABLED = 'disabled'
        SGX = 'sgx'



class InstancePrototypeInstanceBySourceSnapshot(InstancePrototype):
    """
    Create an instance by using a snapshot.

    :param InstanceAvailabilityPolicyPrototype availability_policy: (optional) The
          availability policy to use for this virtual server instance.
    :param List[InstanceClusterNetworkAttachmentPrototypeInstanceContext]
          cluster_network_attachments: (optional) The cluster network attachments to
          create for this virtual server instance. A cluster network attachment represents
          a device that is connected to a cluster network. The number of network
          attachments must match one of the values from the instance profile's
          `cluster_network_attachment_count` before the instance can be started.
    :param str confidential_compute_mode: (optional) The confidential compute mode
          to use for this virtual server instance.
          If unspecified, the default confidential compute mode from the profile will be
          used.
    :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 bool enable_secure_boot: (optional) Indicates whether secure boot is
          enabled for this virtual server instance.
          If unspecified, the default secure boot mode from the profile will be used.
    :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.
          If specified, `reservation_affinity.policy` must be `disabled`.
    :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 InstanceReservationAffinityPrototype reservation_affinity: (optional)
    :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
          attachments or instance network interfaces.
    :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.
    """

    def __init__(
        self,
        boot_volume_attachment: 'VolumeAttachmentPrototypeInstanceBySourceSnapshotContext',
        zone: 'ZoneIdentity',
        *,
        availability_policy: Optional['InstanceAvailabilityPolicyPrototype'] = None,
        cluster_network_attachments: Optional[List['InstanceClusterNetworkAttachmentPrototypeInstanceContext']] = None,
        confidential_compute_mode: Optional[str] = None,
        default_trusted_profile: Optional['InstanceDefaultTrustedProfilePrototype'] = None,
        enable_secure_boot: Optional[bool] = None,
        keys: Optional[List['KeyIdentity']] = None,
        metadata_service: Optional['InstanceMetadataServicePrototype'] = None,
        name: Optional[str] = None,
        placement_target: Optional['InstancePlacementTargetPrototype'] = None,
        profile: Optional['InstanceProfileIdentity'] = None,
        reservation_affinity: Optional['InstanceReservationAffinityPrototype'] = None,
        resource_group: Optional['ResourceGroupIdentity'] = None,
        total_volume_bandwidth: Optional[int] = None,
        user_data: Optional[str] = None,
        volume_attachments: Optional[List['VolumeAttachmentPrototype']] = None,
        vpc: Optional['VPCIdentity'] = None,
    ) -> None:
        """
        Initialize a InstancePrototypeInstanceBySourceSnapshot object.

        :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 List[InstanceClusterNetworkAttachmentPrototypeInstanceContext]
               cluster_network_attachments: (optional) The cluster network attachments to
               create for this virtual server instance. A cluster network attachment
               represents a device that is connected to a cluster network. The number of
               network attachments must match one of the values from the instance
               profile's `cluster_network_attachment_count` before the instance can be
               started.
        :param str confidential_compute_mode: (optional) The confidential compute
               mode to use for this virtual server instance.
               If unspecified, the default confidential compute mode from the profile will
               be used.
        :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 bool enable_secure_boot: (optional) Indicates whether secure boot is
               enabled for this virtual server instance.
               If unspecified, the default secure boot mode from the profile will be used.
        :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.
               If specified, `reservation_affinity.policy` must be `disabled`.
        :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 InstanceReservationAffinityPrototype reservation_affinity:
               (optional)
        :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
               attachments or instance network interfaces.
        """
        # pylint: disable=super-init-not-called
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['InstancePrototypeInstanceBySourceSnapshotInstanceBySourceSnapshotInstanceByNetworkAttachment', 'InstancePrototypeInstanceBySourceSnapshotInstanceBySourceSnapshotInstanceByNetworkInterface'])
        )
        raise Exception(msg)

    class ConfidentialComputeModeEnum(str, Enum):
        """
        The confidential compute mode to use for this virtual server instance.
        If unspecified, the default confidential compute mode from the profile will be
        used.
        """

        DISABLED = 'disabled'
        SGX = 'sgx'



class InstancePrototypeInstanceBySourceTemplate(InstancePrototype):
    """
    Create an instance by using an instance template.
    The `primary_network_attachment` and `network_attachments` properties may only be
    specified if `primary_network_attachment` is specified in the source template.
    The `primary_network_interface` and `network_interfaces` properties may only be
    specified if `primary_network_interface` is specified in the source template.

    :param InstanceAvailabilityPolicyPrototype availability_policy: (optional) The
          availability policy to use for this virtual server instance.
    :param List[InstanceClusterNetworkAttachmentPrototypeInstanceContext]
          cluster_network_attachments: (optional) The cluster network attachments to
          create for this virtual server instance. A cluster network attachment represents
          a device that is connected to a cluster network. The number of network
          attachments must match one of the values from the instance profile's
          `cluster_network_attachment_count` before the instance can be started.
    :param str confidential_compute_mode: (optional) The confidential compute mode
          to use for this virtual server instance.
          If unspecified, the default confidential compute mode from the profile will be
          used.
    :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 bool enable_secure_boot: (optional) Indicates whether secure boot is
          enabled for this virtual server instance.
          If unspecified, the default secure boot mode from the profile will be used.
    :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.
          If specified, `reservation_affinity.policy` must be `disabled`.
    :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 InstanceReservationAffinityPrototype reservation_affinity: (optional)
    :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
          attachments or 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[InstanceNetworkAttachmentPrototype] network_attachments: (optional)
          The additional network attachments to create for the virtual server instance.
    :param List[NetworkInterfacePrototype] network_interfaces: (optional) The
          additional instance network interfaces to create.
    :param InstanceNetworkAttachmentPrototype primary_network_attachment: (optional)
          The primary network attachment to create for the virtual server instance.
    :param NetworkInterfacePrototype primary_network_interface: (optional) The
          primary instance network interface to create.
    :param InstanceTemplateIdentity source_template: The template to create this
          virtual server instance from.
    :param ZoneIdentity zone: (optional) The zone this virtual server instance will
          reside in.
    """

    def __init__(
        self,
        source_template: 'InstanceTemplateIdentity',
        *,
        availability_policy: Optional['InstanceAvailabilityPolicyPrototype'] = None,
        cluster_network_attachments: Optional[List['InstanceClusterNetworkAttachmentPrototypeInstanceContext']] = None,
        confidential_compute_mode: Optional[str] = None,
        default_trusted_profile: Optional['InstanceDefaultTrustedProfilePrototype'] = None,
        enable_secure_boot: Optional[bool] = None,
        keys: Optional[List['KeyIdentity']] = None,
        metadata_service: Optional['InstanceMetadataServicePrototype'] = None,
        name: Optional[str] = None,
        placement_target: Optional['InstancePlacementTargetPrototype'] = None,
        profile: Optional['InstanceProfileIdentity'] = None,
        reservation_affinity: Optional['InstanceReservationAffinityPrototype'] = None,
        resource_group: Optional['ResourceGroupIdentity'] = None,
        total_volume_bandwidth: Optional[int] = None,
        user_data: Optional[str] = None,
        volume_attachments: Optional[List['VolumeAttachmentPrototype']] = None,
        vpc: Optional['VPCIdentity'] = None,
        boot_volume_attachment: Optional['VolumeAttachmentPrototypeInstanceByImageContext'] = None,
        catalog_offering: Optional['InstanceCatalogOfferingPrototype'] = None,
        image: Optional['ImageIdentity'] = None,
        network_attachments: Optional[List['InstanceNetworkAttachmentPrototype']] = None,
        network_interfaces: Optional[List['NetworkInterfacePrototype']] = None,
        primary_network_attachment: Optional['InstanceNetworkAttachmentPrototype'] = None,
        primary_network_interface: Optional['NetworkInterfacePrototype'] = None,
        zone: Optional['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 List[InstanceClusterNetworkAttachmentPrototypeInstanceContext]
               cluster_network_attachments: (optional) The cluster network attachments to
               create for this virtual server instance. A cluster network attachment
               represents a device that is connected to a cluster network. The number of
               network attachments must match one of the values from the instance
               profile's `cluster_network_attachment_count` before the instance can be
               started.
        :param str confidential_compute_mode: (optional) The confidential compute
               mode to use for this virtual server instance.
               If unspecified, the default confidential compute mode from the profile will
               be used.
        :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 bool enable_secure_boot: (optional) Indicates whether secure boot is
               enabled for this virtual server instance.
               If unspecified, the default secure boot mode from the profile will be used.
        :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.
               If specified, `reservation_affinity.policy` must be `disabled`.
        :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 InstanceReservationAffinityPrototype reservation_affinity:
               (optional)
        :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
               attachments or 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[InstanceNetworkAttachmentPrototype] network_attachments:
               (optional) The additional network attachments to create for the virtual
               server instance.
        :param List[NetworkInterfacePrototype] network_interfaces: (optional) The
               additional instance network interfaces to create.
        :param InstanceNetworkAttachmentPrototype primary_network_attachment:
               (optional) The primary network attachment to create for the virtual server
               instance.
        :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.cluster_network_attachments = cluster_network_attachments
        self.confidential_compute_mode = confidential_compute_mode
        self.default_trusted_profile = default_trusted_profile
        self.enable_secure_boot = enable_secure_boot
        self.keys = keys
        self.metadata_service = metadata_service
        self.name = name
        self.placement_target = placement_target
        self.profile = profile
        self.reservation_affinity = reservation_affinity
        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_attachments = network_attachments
        self.network_interfaces = network_interfaces
        self.primary_network_attachment = primary_network_attachment
        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 := _dict.get('availability_policy')) is not None:
            args['availability_policy'] = InstanceAvailabilityPolicyPrototype.from_dict(availability_policy)
        if (cluster_network_attachments := _dict.get('cluster_network_attachments')) is not None:
            args['cluster_network_attachments'] = [InstanceClusterNetworkAttachmentPrototypeInstanceContext.from_dict(v) for v in cluster_network_attachments]
        if (confidential_compute_mode := _dict.get('confidential_compute_mode')) is not None:
            args['confidential_compute_mode'] = confidential_compute_mode
        if (default_trusted_profile := _dict.get('default_trusted_profile')) is not None:
            args['default_trusted_profile'] = InstanceDefaultTrustedProfilePrototype.from_dict(default_trusted_profile)
        if (enable_secure_boot := _dict.get('enable_secure_boot')) is not None:
            args['enable_secure_boot'] = enable_secure_boot
        if (keys := _dict.get('keys')) is not None:
            args['keys'] = keys
        if (metadata_service := _dict.get('metadata_service')) is not None:
            args['metadata_service'] = InstanceMetadataServicePrototype.from_dict(metadata_service)
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        if (placement_target := _dict.get('placement_target')) is not None:
            args['placement_target'] = placement_target
        if (profile := _dict.get('profile')) is not None:
            args['profile'] = profile
        if (reservation_affinity := _dict.get('reservation_affinity')) is not None:
            args['reservation_affinity'] = InstanceReservationAffinityPrototype.from_dict(reservation_affinity)
        if (resource_group := _dict.get('resource_group')) is not None:
            args['resource_group'] = resource_group
        if (total_volume_bandwidth := _dict.get('total_volume_bandwidth')) is not None:
            args['total_volume_bandwidth'] = total_volume_bandwidth
        if (user_data := _dict.get('user_data')) is not None:
            args['user_data'] = user_data
        if (volume_attachments := _dict.get('volume_attachments')) is not None:
            args['volume_attachments'] = [VolumeAttachmentPrototype.from_dict(v) for v in volume_attachments]
        if (vpc := _dict.get('vpc')) is not None:
            args['vpc'] = vpc
        if (boot_volume_attachment := _dict.get('boot_volume_attachment')) is not None:
            args['boot_volume_attachment'] = VolumeAttachmentPrototypeInstanceByImageContext.from_dict(boot_volume_attachment)
        if (catalog_offering := _dict.get('catalog_offering')) is not None:
            args['catalog_offering'] = catalog_offering
        if (image := _dict.get('image')) is not None:
            args['image'] = image
        if (network_attachments := _dict.get('network_attachments')) is not None:
            args['network_attachments'] = [InstanceNetworkAttachmentPrototype.from_dict(v) for v in network_attachments]
        if (network_interfaces := _dict.get('network_interfaces')) is not None:
            args['network_interfaces'] = [NetworkInterfacePrototype.from_dict(v) for v in network_interfaces]
        if (primary_network_attachment := _dict.get('primary_network_attachment')) is not None:
            args['primary_network_attachment'] = InstanceNetworkAttachmentPrototype.from_dict(primary_network_attachment)
        if (primary_network_interface := _dict.get('primary_network_interface')) is not None:
            args['primary_network_interface'] = NetworkInterfacePrototype.from_dict(primary_network_interface)
        if (source_template := _dict.get('source_template')) is not None:
            args['source_template'] = source_template
        else:
            raise ValueError('Required property \'source_template\' not present in InstancePrototypeInstanceBySourceTemplate JSON')
        if (zone := _dict.get('zone')) is not None:
            args['zone'] = 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, 'cluster_network_attachments') and self.cluster_network_attachments is not None:
            cluster_network_attachments_list = []
            for v in self.cluster_network_attachments:
                if isinstance(v, dict):
                    cluster_network_attachments_list.append(v)
                else:
                    cluster_network_attachments_list.append(v.to_dict())
            _dict['cluster_network_attachments'] = cluster_network_attachments_list
        if hasattr(self, 'confidential_compute_mode') and self.confidential_compute_mode is not None:
            _dict['confidential_compute_mode'] = self.confidential_compute_mode
        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, 'enable_secure_boot') and self.enable_secure_boot is not None:
            _dict['enable_secure_boot'] = self.enable_secure_boot
        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, 'reservation_affinity') and self.reservation_affinity is not None:
            if isinstance(self.reservation_affinity, dict):
                _dict['reservation_affinity'] = self.reservation_affinity
            else:
                _dict['reservation_affinity'] = self.reservation_affinity.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_attachments') and self.network_attachments is not None:
            network_attachments_list = []
            for v in self.network_attachments:
                if isinstance(v, dict):
                    network_attachments_list.append(v)
                else:
                    network_attachments_list.append(v.to_dict())
            _dict['network_attachments'] = network_attachments_list
        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_attachment') and self.primary_network_attachment is not None:
            if isinstance(self.primary_network_attachment, dict):
                _dict['primary_network_attachment'] = self.primary_network_attachment
            else:
                _dict['primary_network_attachment'] = self.primary_network_attachment.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, '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 ConfidentialComputeModeEnum(str, Enum):
        """
        The confidential compute mode to use for this virtual server instance.
        If unspecified, the default confidential compute mode from the profile will be
        used.
        """

        DISABLED = 'disabled'
        SGX = 'sgx'



class InstancePrototypeInstanceByVolume(InstancePrototype):
    """
    Create an instance by using a boot volume.

    :param InstanceAvailabilityPolicyPrototype availability_policy: (optional) The
          availability policy to use for this virtual server instance.
    :param List[InstanceClusterNetworkAttachmentPrototypeInstanceContext]
          cluster_network_attachments: (optional) The cluster network attachments to
          create for this virtual server instance. A cluster network attachment represents
          a device that is connected to a cluster network. The number of network
          attachments must match one of the values from the instance profile's
          `cluster_network_attachment_count` before the instance can be started.
    :param str confidential_compute_mode: (optional) The confidential compute mode
          to use for this virtual server instance.
          If unspecified, the default confidential compute mode from the profile will be
          used.
    :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 bool enable_secure_boot: (optional) Indicates whether secure boot is
          enabled for this virtual server instance.
          If unspecified, the default secure boot mode from the profile will be used.
    :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.
          If specified, `reservation_affinity.policy` must be `disabled`.
    :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 InstanceReservationAffinityPrototype reservation_affinity: (optional)
    :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
          attachments or instance network interfaces.
    :param VolumeAttachmentPrototypeInstanceByVolumeContext boot_volume_attachment:
          The boot volume attachment for the virtual server instance.
    :param ZoneIdentity zone: The zone this virtual server instance will reside in.
    """

    def __init__(
        self,
        boot_volume_attachment: 'VolumeAttachmentPrototypeInstanceByVolumeContext',
        zone: 'ZoneIdentity',
        *,
        availability_policy: Optional['InstanceAvailabilityPolicyPrototype'] = None,
        cluster_network_attachments: Optional[List['InstanceClusterNetworkAttachmentPrototypeInstanceContext']] = None,
        confidential_compute_mode: Optional[str] = None,
        default_trusted_profile: Optional['InstanceDefaultTrustedProfilePrototype'] = None,
        enable_secure_boot: Optional[bool] = None,
        keys: Optional[List['KeyIdentity']] = None,
        metadata_service: Optional['InstanceMetadataServicePrototype'] = None,
        name: Optional[str] = None,
        placement_target: Optional['InstancePlacementTargetPrototype'] = None,
        profile: Optional['InstanceProfileIdentity'] = None,
        reservation_affinity: Optional['InstanceReservationAffinityPrototype'] = None,
        resource_group: Optional['ResourceGroupIdentity'] = None,
        total_volume_bandwidth: Optional[int] = None,
        user_data: Optional[str] = None,
        volume_attachments: Optional[List['VolumeAttachmentPrototype']] = None,
        vpc: Optional['VPCIdentity'] = None,
    ) -> None:
        """
        Initialize a InstancePrototypeInstanceByVolume object.

        :param VolumeAttachmentPrototypeInstanceByVolumeContext
               boot_volume_attachment: The boot volume attachment 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 List[InstanceClusterNetworkAttachmentPrototypeInstanceContext]
               cluster_network_attachments: (optional) The cluster network attachments to
               create for this virtual server instance. A cluster network attachment
               represents a device that is connected to a cluster network. The number of
               network attachments must match one of the values from the instance
               profile's `cluster_network_attachment_count` before the instance can be
               started.
        :param str confidential_compute_mode: (optional) The confidential compute
               mode to use for this virtual server instance.
               If unspecified, the default confidential compute mode from the profile will
               be used.
        :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 bool enable_secure_boot: (optional) Indicates whether secure boot is
               enabled for this virtual server instance.
               If unspecified, the default secure boot mode from the profile will be used.
        :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.
               If specified, `reservation_affinity.policy` must be `disabled`.
        :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 InstanceReservationAffinityPrototype reservation_affinity:
               (optional)
        :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
               attachments or instance network interfaces.
        """
        # pylint: disable=super-init-not-called
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['InstancePrototypeInstanceByVolumeInstanceByVolumeInstanceByNetworkAttachment', 'InstancePrototypeInstanceByVolumeInstanceByVolumeInstanceByNetworkInterface'])
        )
        raise Exception(msg)

    class ConfidentialComputeModeEnum(str, Enum):
        """
        The confidential compute mode to use for this virtual server instance.
        If unspecified, the default confidential compute mode from the profile will be
        used.
        """

        DISABLED = 'disabled'
        SGX = 'sgx'



class InstanceTemplateIdentityByCRN(InstanceTemplateIdentity):
    """
    InstanceTemplateIdentityByCRN.

    :param 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 := _dict.get('crn')) is not None:
            args['crn'] = 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.

    :param 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 := _dict.get('href')) is not None:
            args['href'] = 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.

    :param 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 := _dict.get('id')) is not None:
            args['id'] = 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.

    :param InstanceAvailabilityPolicyPrototype availability_policy: (optional) The
          availability policy to use for this virtual server instance.
    :param List[InstanceClusterNetworkAttachmentPrototypeInstanceContext]
          cluster_network_attachments: (optional) The cluster network attachments to
          create for this virtual server instance. A cluster network attachment represents
          a device that is connected to a cluster network. The number of network
          attachments must match one of the values from the instance profile's
          `cluster_network_attachment_count` before the instance can be started.
    :param str confidential_compute_mode: (optional) The confidential compute mode
          to use for this virtual server instance.
          If unspecified, the default confidential compute mode from the profile will be
          used.
    :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 bool enable_secure_boot: (optional) Indicates whether secure boot is
          enabled for this virtual server instance.
          If unspecified, the default secure boot mode from the profile will be used.
    :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.
          If specified, `reservation_affinity.policy` must be `disabled`.
    :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 InstanceReservationAffinityPrototype reservation_affinity: (optional)
    :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
          attachments or instance network interfaces.
    :param VolumeAttachmentPrototypeInstanceByImageContext boot_volume_attachment:
          (optional) The boot volume attachment to create for the virtual server instance.
    :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,
          subject
          to IAM policies.
    :param ZoneIdentity zone: The zone this virtual server instance will reside in.
    """

    def __init__(
        self,
        catalog_offering: 'InstanceCatalogOfferingPrototype',
        zone: 'ZoneIdentity',
        *,
        availability_policy: Optional['InstanceAvailabilityPolicyPrototype'] = None,
        cluster_network_attachments: Optional[List['InstanceClusterNetworkAttachmentPrototypeInstanceContext']] = None,
        confidential_compute_mode: Optional[str] = None,
        default_trusted_profile: Optional['InstanceDefaultTrustedProfilePrototype'] = None,
        enable_secure_boot: Optional[bool] = None,
        keys: Optional[List['KeyIdentity']] = None,
        metadata_service: Optional['InstanceMetadataServicePrototype'] = None,
        name: Optional[str] = None,
        placement_target: Optional['InstancePlacementTargetPrototype'] = None,
        profile: Optional['InstanceProfileIdentity'] = None,
        reservation_affinity: Optional['InstanceReservationAffinityPrototype'] = None,
        resource_group: Optional['ResourceGroupIdentity'] = None,
        total_volume_bandwidth: Optional[int] = None,
        user_data: Optional[str] = None,
        volume_attachments: Optional[List['VolumeAttachmentPrototype']] = None,
        vpc: Optional['VPCIdentity'] = None,
        boot_volume_attachment: Optional['VolumeAttachmentPrototypeInstanceByImageContext'] = 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,
               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 List[InstanceClusterNetworkAttachmentPrototypeInstanceContext]
               cluster_network_attachments: (optional) The cluster network attachments to
               create for this virtual server instance. A cluster network attachment
               represents a device that is connected to a cluster network. The number of
               network attachments must match one of the values from the instance
               profile's `cluster_network_attachment_count` before the instance can be
               started.
        :param str confidential_compute_mode: (optional) The confidential compute
               mode to use for this virtual server instance.
               If unspecified, the default confidential compute mode from the profile will
               be used.
        :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 bool enable_secure_boot: (optional) Indicates whether secure boot is
               enabled for this virtual server instance.
               If unspecified, the default secure boot mode from the profile will be used.
        :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.
               If specified, `reservation_affinity.policy` must be `disabled`.
        :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 InstanceReservationAffinityPrototype reservation_affinity:
               (optional)
        :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
               attachments or instance network interfaces.
        :param VolumeAttachmentPrototypeInstanceByImageContext
               boot_volume_attachment: (optional) The boot volume attachment to create for
               the virtual server instance.
        """
        # pylint: disable=super-init-not-called
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['InstanceTemplatePrototypeInstanceTemplateByCatalogOfferingInstanceTemplateByCatalogOfferingInstanceByNetworkAttachment', 'InstanceTemplatePrototypeInstanceTemplateByCatalogOfferingInstanceTemplateByCatalogOfferingInstanceByNetworkInterface'])
        )
        raise Exception(msg)

    class ConfidentialComputeModeEnum(str, Enum):
        """
        The confidential compute mode to use for this virtual server instance.
        If unspecified, the default confidential compute mode from the profile will be
        used.
        """

        DISABLED = 'disabled'
        SGX = 'sgx'



class InstanceTemplatePrototypeInstanceTemplateByImage(InstanceTemplatePrototype):
    """
    Create an instance template that creates instances by using an image.
    The image's `user_data_format` must be `cloud_init`.

    :param InstanceAvailabilityPolicyPrototype availability_policy: (optional) The
          availability policy to use for this virtual server instance.
    :param List[InstanceClusterNetworkAttachmentPrototypeInstanceContext]
          cluster_network_attachments: (optional) The cluster network attachments to
          create for this virtual server instance. A cluster network attachment represents
          a device that is connected to a cluster network. The number of network
          attachments must match one of the values from the instance profile's
          `cluster_network_attachment_count` before the instance can be started.
    :param str confidential_compute_mode: (optional) The confidential compute mode
          to use for this virtual server instance.
          If unspecified, the default confidential compute mode from the profile will be
          used.
    :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 bool enable_secure_boot: (optional) Indicates whether secure boot is
          enabled for this virtual server instance.
          If unspecified, the default secure boot mode from the profile will be used.
    :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.
          If specified, `reservation_affinity.policy` must be `disabled`.
    :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 InstanceReservationAffinityPrototype reservation_affinity: (optional)
    :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
          attachments or instance network interfaces.
    :param VolumeAttachmentPrototypeInstanceByImageContext boot_volume_attachment:
          (optional) The boot volume attachment to create for the virtual server instance.
    :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.
    """

    def __init__(
        self,
        image: 'ImageIdentity',
        zone: 'ZoneIdentity',
        *,
        availability_policy: Optional['InstanceAvailabilityPolicyPrototype'] = None,
        cluster_network_attachments: Optional[List['InstanceClusterNetworkAttachmentPrototypeInstanceContext']] = None,
        confidential_compute_mode: Optional[str] = None,
        default_trusted_profile: Optional['InstanceDefaultTrustedProfilePrototype'] = None,
        enable_secure_boot: Optional[bool] = None,
        keys: Optional[List['KeyIdentity']] = None,
        metadata_service: Optional['InstanceMetadataServicePrototype'] = None,
        name: Optional[str] = None,
        placement_target: Optional['InstancePlacementTargetPrototype'] = None,
        profile: Optional['InstanceProfileIdentity'] = None,
        reservation_affinity: Optional['InstanceReservationAffinityPrototype'] = None,
        resource_group: Optional['ResourceGroupIdentity'] = None,
        total_volume_bandwidth: Optional[int] = None,
        user_data: Optional[str] = None,
        volume_attachments: Optional[List['VolumeAttachmentPrototype']] = None,
        vpc: Optional['VPCIdentity'] = None,
        boot_volume_attachment: Optional['VolumeAttachmentPrototypeInstanceByImageContext'] = None,
    ) -> None:
        """
        Initialize a InstanceTemplatePrototypeInstanceTemplateByImage object.

        :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 List[InstanceClusterNetworkAttachmentPrototypeInstanceContext]
               cluster_network_attachments: (optional) The cluster network attachments to
               create for this virtual server instance. A cluster network attachment
               represents a device that is connected to a cluster network. The number of
               network attachments must match one of the values from the instance
               profile's `cluster_network_attachment_count` before the instance can be
               started.
        :param str confidential_compute_mode: (optional) The confidential compute
               mode to use for this virtual server instance.
               If unspecified, the default confidential compute mode from the profile will
               be used.
        :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 bool enable_secure_boot: (optional) Indicates whether secure boot is
               enabled for this virtual server instance.
               If unspecified, the default secure boot mode from the profile will be used.
        :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.
               If specified, `reservation_affinity.policy` must be `disabled`.
        :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 InstanceReservationAffinityPrototype reservation_affinity:
               (optional)
        :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
               attachments or instance network interfaces.
        :param VolumeAttachmentPrototypeInstanceByImageContext
               boot_volume_attachment: (optional) The boot volume attachment to create for
               the virtual server instance.
        """
        # pylint: disable=super-init-not-called
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['InstanceTemplatePrototypeInstanceTemplateByImageInstanceTemplateByImageInstanceByNetworkAttachment', 'InstanceTemplatePrototypeInstanceTemplateByImageInstanceTemplateByImageInstanceByNetworkInterface'])
        )
        raise Exception(msg)

    class ConfidentialComputeModeEnum(str, Enum):
        """
        The confidential compute mode to use for this virtual server instance.
        If unspecified, the default confidential compute mode from the profile will be
        used.
        """

        DISABLED = 'disabled'
        SGX = 'sgx'



class InstanceTemplatePrototypeInstanceTemplateBySourceSnapshot(InstanceTemplatePrototype):
    """
    Create an instance template that creates instances by using a snapshot.

    :param InstanceAvailabilityPolicyPrototype availability_policy: (optional) The
          availability policy to use for this virtual server instance.
    :param List[InstanceClusterNetworkAttachmentPrototypeInstanceContext]
          cluster_network_attachments: (optional) The cluster network attachments to
          create for this virtual server instance. A cluster network attachment represents
          a device that is connected to a cluster network. The number of network
          attachments must match one of the values from the instance profile's
          `cluster_network_attachment_count` before the instance can be started.
    :param str confidential_compute_mode: (optional) The confidential compute mode
          to use for this virtual server instance.
          If unspecified, the default confidential compute mode from the profile will be
          used.
    :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 bool enable_secure_boot: (optional) Indicates whether secure boot is
          enabled for this virtual server instance.
          If unspecified, the default secure boot mode from the profile will be used.
    :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.
          If specified, `reservation_affinity.policy` must be `disabled`.
    :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 InstanceReservationAffinityPrototype reservation_affinity: (optional)
    :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
          attachments or instance network interfaces.
    :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.
    """

    def __init__(
        self,
        boot_volume_attachment: 'VolumeAttachmentPrototypeInstanceBySourceSnapshotContext',
        zone: 'ZoneIdentity',
        *,
        availability_policy: Optional['InstanceAvailabilityPolicyPrototype'] = None,
        cluster_network_attachments: Optional[List['InstanceClusterNetworkAttachmentPrototypeInstanceContext']] = None,
        confidential_compute_mode: Optional[str] = None,
        default_trusted_profile: Optional['InstanceDefaultTrustedProfilePrototype'] = None,
        enable_secure_boot: Optional[bool] = None,
        keys: Optional[List['KeyIdentity']] = None,
        metadata_service: Optional['InstanceMetadataServicePrototype'] = None,
        name: Optional[str] = None,
        placement_target: Optional['InstancePlacementTargetPrototype'] = None,
        profile: Optional['InstanceProfileIdentity'] = None,
        reservation_affinity: Optional['InstanceReservationAffinityPrototype'] = None,
        resource_group: Optional['ResourceGroupIdentity'] = None,
        total_volume_bandwidth: Optional[int] = None,
        user_data: Optional[str] = None,
        volume_attachments: Optional[List['VolumeAttachmentPrototype']] = None,
        vpc: Optional['VPCIdentity'] = None,
    ) -> None:
        """
        Initialize a InstanceTemplatePrototypeInstanceTemplateBySourceSnapshot object.

        :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 List[InstanceClusterNetworkAttachmentPrototypeInstanceContext]
               cluster_network_attachments: (optional) The cluster network attachments to
               create for this virtual server instance. A cluster network attachment
               represents a device that is connected to a cluster network. The number of
               network attachments must match one of the values from the instance
               profile's `cluster_network_attachment_count` before the instance can be
               started.
        :param str confidential_compute_mode: (optional) The confidential compute
               mode to use for this virtual server instance.
               If unspecified, the default confidential compute mode from the profile will
               be used.
        :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 bool enable_secure_boot: (optional) Indicates whether secure boot is
               enabled for this virtual server instance.
               If unspecified, the default secure boot mode from the profile will be used.
        :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.
               If specified, `reservation_affinity.policy` must be `disabled`.
        :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 InstanceReservationAffinityPrototype reservation_affinity:
               (optional)
        :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
               attachments or instance network interfaces.
        """
        # pylint: disable=super-init-not-called
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['InstanceTemplatePrototypeInstanceTemplateBySourceSnapshotInstanceTemplateBySourceSnapshotInstanceByNetworkAttachment', 'InstanceTemplatePrototypeInstanceTemplateBySourceSnapshotInstanceTemplateBySourceSnapshotInstanceByNetworkInterface'])
        )
        raise Exception(msg)

    class ConfidentialComputeModeEnum(str, Enum):
        """
        The confidential compute mode to use for this virtual server instance.
        If unspecified, the default confidential compute mode from the profile will be
        used.
        """

        DISABLED = 'disabled'
        SGX = 'sgx'



class InstanceTemplatePrototypeInstanceTemplateBySourceTemplate(InstanceTemplatePrototype):
    """
    Create an instance template from an existing source instance template.
    The `primary_network_attachment` and `network_attachments` properties may only be
    specified if `primary_network_attachment` is specified in the source template.
    The `primary_network_interface` and `network_interfaces` properties may only be
    specified if `primary_network_interface` is specified in the source template.

    :param InstanceAvailabilityPolicyPrototype availability_policy: (optional) The
          availability policy to use for this virtual server instance.
    :param List[InstanceClusterNetworkAttachmentPrototypeInstanceContext]
          cluster_network_attachments: (optional) The cluster network attachments to
          create for this virtual server instance. A cluster network attachment represents
          a device that is connected to a cluster network. The number of network
          attachments must match one of the values from the instance profile's
          `cluster_network_attachment_count` before the instance can be started.
    :param str confidential_compute_mode: (optional) The confidential compute mode
          to use for this virtual server instance.
          If unspecified, the default confidential compute mode from the profile will be
          used.
    :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 bool enable_secure_boot: (optional) Indicates whether secure boot is
          enabled for this virtual server instance.
          If unspecified, the default secure boot mode from the profile will be used.
    :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.
          If specified, `reservation_affinity.policy` must be `disabled`.
    :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 InstanceReservationAffinityPrototype reservation_affinity: (optional)
    :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
          attachments or 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[InstanceNetworkAttachmentPrototype] network_attachments: (optional)
          The additional network attachments to create for the virtual server instance.
    :param List[NetworkInterfacePrototype] network_interfaces: (optional) The
          additional instance network interfaces to create.
    :param InstanceNetworkAttachmentPrototype primary_network_attachment: (optional)
          The primary network attachment to create for the virtual server instance.
    :param NetworkInterfacePrototype primary_network_interface: (optional) The
          primary instance network interface to create.
    :param InstanceTemplateIdentity source_template: The template to create this
          virtual server instance from.
    :param ZoneIdentity zone: (optional) The zone this virtual server instance will
          reside in.
    """

    def __init__(
        self,
        source_template: 'InstanceTemplateIdentity',
        *,
        availability_policy: Optional['InstanceAvailabilityPolicyPrototype'] = None,
        cluster_network_attachments: Optional[List['InstanceClusterNetworkAttachmentPrototypeInstanceContext']] = None,
        confidential_compute_mode: Optional[str] = None,
        default_trusted_profile: Optional['InstanceDefaultTrustedProfilePrototype'] = None,
        enable_secure_boot: Optional[bool] = None,
        keys: Optional[List['KeyIdentity']] = None,
        metadata_service: Optional['InstanceMetadataServicePrototype'] = None,
        name: Optional[str] = None,
        placement_target: Optional['InstancePlacementTargetPrototype'] = None,
        profile: Optional['InstanceProfileIdentity'] = None,
        reservation_affinity: Optional['InstanceReservationAffinityPrototype'] = None,
        resource_group: Optional['ResourceGroupIdentity'] = None,
        total_volume_bandwidth: Optional[int] = None,
        user_data: Optional[str] = None,
        volume_attachments: Optional[List['VolumeAttachmentPrototype']] = None,
        vpc: Optional['VPCIdentity'] = None,
        boot_volume_attachment: Optional['VolumeAttachmentPrototypeInstanceByImageContext'] = None,
        catalog_offering: Optional['InstanceCatalogOfferingPrototype'] = None,
        image: Optional['ImageIdentity'] = None,
        network_attachments: Optional[List['InstanceNetworkAttachmentPrototype']] = None,
        network_interfaces: Optional[List['NetworkInterfacePrototype']] = None,
        primary_network_attachment: Optional['InstanceNetworkAttachmentPrototype'] = None,
        primary_network_interface: Optional['NetworkInterfacePrototype'] = None,
        zone: Optional['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 List[InstanceClusterNetworkAttachmentPrototypeInstanceContext]
               cluster_network_attachments: (optional) The cluster network attachments to
               create for this virtual server instance. A cluster network attachment
               represents a device that is connected to a cluster network. The number of
               network attachments must match one of the values from the instance
               profile's `cluster_network_attachment_count` before the instance can be
               started.
        :param str confidential_compute_mode: (optional) The confidential compute
               mode to use for this virtual server instance.
               If unspecified, the default confidential compute mode from the profile will
               be used.
        :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 bool enable_secure_boot: (optional) Indicates whether secure boot is
               enabled for this virtual server instance.
               If unspecified, the default secure boot mode from the profile will be used.
        :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.
               If specified, `reservation_affinity.policy` must be `disabled`.
        :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 InstanceReservationAffinityPrototype reservation_affinity:
               (optional)
        :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
               attachments or 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[InstanceNetworkAttachmentPrototype] network_attachments:
               (optional) The additional network attachments to create for the virtual
               server instance.
        :param List[NetworkInterfacePrototype] network_interfaces: (optional) The
               additional instance network interfaces to create.
        :param InstanceNetworkAttachmentPrototype primary_network_attachment:
               (optional) The primary network attachment to create for the virtual server
               instance.
        :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.cluster_network_attachments = cluster_network_attachments
        self.confidential_compute_mode = confidential_compute_mode
        self.default_trusted_profile = default_trusted_profile
        self.enable_secure_boot = enable_secure_boot
        self.keys = keys
        self.metadata_service = metadata_service
        self.name = name
        self.placement_target = placement_target
        self.profile = profile
        self.reservation_affinity = reservation_affinity
        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_attachments = network_attachments
        self.network_interfaces = network_interfaces
        self.primary_network_attachment = primary_network_attachment
        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 := _dict.get('availability_policy')) is not None:
            args['availability_policy'] = InstanceAvailabilityPolicyPrototype.from_dict(availability_policy)
        if (cluster_network_attachments := _dict.get('cluster_network_attachments')) is not None:
            args['cluster_network_attachments'] = [InstanceClusterNetworkAttachmentPrototypeInstanceContext.from_dict(v) for v in cluster_network_attachments]
        if (confidential_compute_mode := _dict.get('confidential_compute_mode')) is not None:
            args['confidential_compute_mode'] = confidential_compute_mode
        if (default_trusted_profile := _dict.get('default_trusted_profile')) is not None:
            args['default_trusted_profile'] = InstanceDefaultTrustedProfilePrototype.from_dict(default_trusted_profile)
        if (enable_secure_boot := _dict.get('enable_secure_boot')) is not None:
            args['enable_secure_boot'] = enable_secure_boot
        if (keys := _dict.get('keys')) is not None:
            args['keys'] = keys
        if (metadata_service := _dict.get('metadata_service')) is not None:
            args['metadata_service'] = InstanceMetadataServicePrototype.from_dict(metadata_service)
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        if (placement_target := _dict.get('placement_target')) is not None:
            args['placement_target'] = placement_target
        if (profile := _dict.get('profile')) is not None:
            args['profile'] = profile
        if (reservation_affinity := _dict.get('reservation_affinity')) is not None:
            args['reservation_affinity'] = InstanceReservationAffinityPrototype.from_dict(reservation_affinity)
        if (resource_group := _dict.get('resource_group')) is not None:
            args['resource_group'] = resource_group
        if (total_volume_bandwidth := _dict.get('total_volume_bandwidth')) is not None:
            args['total_volume_bandwidth'] = total_volume_bandwidth
        if (user_data := _dict.get('user_data')) is not None:
            args['user_data'] = user_data
        if (volume_attachments := _dict.get('volume_attachments')) is not None:
            args['volume_attachments'] = [VolumeAttachmentPrototype.from_dict(v) for v in volume_attachments]
        if (vpc := _dict.get('vpc')) is not None:
            args['vpc'] = vpc
        if (boot_volume_attachment := _dict.get('boot_volume_attachment')) is not None:
            args['boot_volume_attachment'] = VolumeAttachmentPrototypeInstanceByImageContext.from_dict(boot_volume_attachment)
        if (catalog_offering := _dict.get('catalog_offering')) is not None:
            args['catalog_offering'] = catalog_offering
        if (image := _dict.get('image')) is not None:
            args['image'] = image
        if (network_attachments := _dict.get('network_attachments')) is not None:
            args['network_attachments'] = [InstanceNetworkAttachmentPrototype.from_dict(v) for v in network_attachments]
        if (network_interfaces := _dict.get('network_interfaces')) is not None:
            args['network_interfaces'] = [NetworkInterfacePrototype.from_dict(v) for v in network_interfaces]
        if (primary_network_attachment := _dict.get('primary_network_attachment')) is not None:
            args['primary_network_attachment'] = InstanceNetworkAttachmentPrototype.from_dict(primary_network_attachment)
        if (primary_network_interface := _dict.get('primary_network_interface')) is not None:
            args['primary_network_interface'] = NetworkInterfacePrototype.from_dict(primary_network_interface)
        if (source_template := _dict.get('source_template')) is not None:
            args['source_template'] = source_template
        else:
            raise ValueError('Required property \'source_template\' not present in InstanceTemplatePrototypeInstanceTemplateBySourceTemplate JSON')
        if (zone := _dict.get('zone')) is not None:
            args['zone'] = 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, 'cluster_network_attachments') and self.cluster_network_attachments is not None:
            cluster_network_attachments_list = []
            for v in self.cluster_network_attachments:
                if isinstance(v, dict):
                    cluster_network_attachments_list.append(v)
                else:
                    cluster_network_attachments_list.append(v.to_dict())
            _dict['cluster_network_attachments'] = cluster_network_attachments_list
        if hasattr(self, 'confidential_compute_mode') and self.confidential_compute_mode is not None:
            _dict['confidential_compute_mode'] = self.confidential_compute_mode
        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, 'enable_secure_boot') and self.enable_secure_boot is not None:
            _dict['enable_secure_boot'] = self.enable_secure_boot
        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, 'reservation_affinity') and self.reservation_affinity is not None:
            if isinstance(self.reservation_affinity, dict):
                _dict['reservation_affinity'] = self.reservation_affinity
            else:
                _dict['reservation_affinity'] = self.reservation_affinity.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_attachments') and self.network_attachments is not None:
            network_attachments_list = []
            for v in self.network_attachments:
                if isinstance(v, dict):
                    network_attachments_list.append(v)
                else:
                    network_attachments_list.append(v.to_dict())
            _dict['network_attachments'] = network_attachments_list
        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_attachment') and self.primary_network_attachment is not None:
            if isinstance(self.primary_network_attachment, dict):
                _dict['primary_network_attachment'] = self.primary_network_attachment
            else:
                _dict['primary_network_attachment'] = self.primary_network_attachment.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, '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 ConfidentialComputeModeEnum(str, Enum):
        """
        The confidential compute mode to use for this virtual server instance.
        If unspecified, the default confidential compute mode from the profile will be
        used.
        """

        DISABLED = 'disabled'
        SGX = 'sgx'



class InstanceTemplateInstanceByCatalogOfferingInstanceTemplateContext(InstanceTemplate):
    """
    Create an instance by using a catalog offering.

    :param InstanceAvailabilityPolicyPrototype availability_policy: (optional) The
          availability policy to use for this virtual server instance.
    :param List[InstanceClusterNetworkAttachmentPrototypeInstanceContext]
          cluster_network_attachments: (optional) The cluster network attachments to
          create for this virtual server instance. A cluster network attachment represents
          a device that is connected to a cluster network. The number of network
          attachments must match one of the values from the instance profile's
          `cluster_network_attachment_count` before the instance can be started.
    :param str confidential_compute_mode: (optional) The confidential compute mode
          to use for this virtual server instance.
          If unspecified, the default confidential compute mode from the profile will be
          used.
    :param datetime created_at: The date and time that the instance template was
          created.
    :param str crn: The CRN for this instance template.
    :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 bool enable_secure_boot: (optional) Indicates whether secure boot is
          enabled for this virtual server instance.
          If unspecified, the default secure boot mode from the profile will be used.
    :param str href: The URL for this instance template.
    :param str id: The unique identifier for this instance template.
    :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: The name for this instance template. The name is unique across
          all instance templates in the region.
    :param InstancePlacementTargetPrototype placement_target: (optional) The
          placement restrictions to use for the virtual server instance.
          If specified, `reservation_affinity.policy` must be `disabled`.
    :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 InstanceReservationAffinityPrototype reservation_affinity: (optional)
    :param ResourceGroupReference resource_group: The resource group for this
          instance template.
    :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
          attachments or instance network interfaces.
    :param VolumeAttachmentPrototypeInstanceByImageContext boot_volume_attachment:
          (optional) The boot volume attachment to create for the virtual server instance.
    :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,
          subject
          to IAM policies.
    :param 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: Optional['InstanceAvailabilityPolicyPrototype'] = None,
        cluster_network_attachments: Optional[List['InstanceClusterNetworkAttachmentPrototypeInstanceContext']] = None,
        confidential_compute_mode: Optional[str] = None,
        default_trusted_profile: Optional['InstanceDefaultTrustedProfilePrototype'] = None,
        enable_secure_boot: Optional[bool] = None,
        keys: Optional[List['KeyIdentity']] = None,
        metadata_service: Optional['InstanceMetadataServicePrototype'] = None,
        placement_target: Optional['InstancePlacementTargetPrototype'] = None,
        profile: Optional['InstanceProfileIdentity'] = None,
        reservation_affinity: Optional['InstanceReservationAffinityPrototype'] = None,
        total_volume_bandwidth: Optional[int] = None,
        user_data: Optional[str] = None,
        volume_attachments: Optional[List['VolumeAttachmentPrototype']] = None,
        vpc: Optional['VPCIdentity'] = None,
        boot_volume_attachment: Optional['VolumeAttachmentPrototypeInstanceByImageContext'] = 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,
               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 List[InstanceClusterNetworkAttachmentPrototypeInstanceContext]
               cluster_network_attachments: (optional) The cluster network attachments to
               create for this virtual server instance. A cluster network attachment
               represents a device that is connected to a cluster network. The number of
               network attachments must match one of the values from the instance
               profile's `cluster_network_attachment_count` before the instance can be
               started.
        :param str confidential_compute_mode: (optional) The confidential compute
               mode to use for this virtual server instance.
               If unspecified, the default confidential compute mode from the profile will
               be used.
        :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 bool enable_secure_boot: (optional) Indicates whether secure boot is
               enabled for this virtual server instance.
               If unspecified, the default secure boot mode from the profile will be used.
        :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.
               If specified, `reservation_affinity.policy` must be `disabled`.
        :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 InstanceReservationAffinityPrototype reservation_affinity:
               (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
               attachments or instance network interfaces.
        :param VolumeAttachmentPrototypeInstanceByImageContext
               boot_volume_attachment: (optional) The boot volume attachment to create for
               the virtual server instance.
        """
        # pylint: disable=super-init-not-called
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['InstanceTemplateInstanceByCatalogOfferingInstanceTemplateContextInstanceByCatalogOfferingInstanceTemplateContextInstanceByNetworkAttachment', 'InstanceTemplateInstanceByCatalogOfferingInstanceTemplateContextInstanceByCatalogOfferingInstanceTemplateContextInstanceByNetworkInterface'])
        )
        raise Exception(msg)

    class ConfidentialComputeModeEnum(str, Enum):
        """
        The confidential compute mode to use for this virtual server instance.
        If unspecified, the default confidential compute mode from the profile will be
        used.
        """

        DISABLED = 'disabled'
        SGX = 'sgx'



class InstanceTemplateInstanceByImageInstanceTemplateContext(InstanceTemplate):
    """
    Create an instance by using an image.

    :param InstanceAvailabilityPolicyPrototype availability_policy: (optional) The
          availability policy to use for this virtual server instance.
    :param List[InstanceClusterNetworkAttachmentPrototypeInstanceContext]
          cluster_network_attachments: (optional) The cluster network attachments to
          create for this virtual server instance. A cluster network attachment represents
          a device that is connected to a cluster network. The number of network
          attachments must match one of the values from the instance profile's
          `cluster_network_attachment_count` before the instance can be started.
    :param str confidential_compute_mode: (optional) The confidential compute mode
          to use for this virtual server instance.
          If unspecified, the default confidential compute mode from the profile will be
          used.
    :param datetime created_at: The date and time that the instance template was
          created.
    :param str crn: The CRN for this instance template.
    :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 bool enable_secure_boot: (optional) Indicates whether secure boot is
          enabled for this virtual server instance.
          If unspecified, the default secure boot mode from the profile will be used.
    :param str href: The URL for this instance template.
    :param str id: The unique identifier for this instance template.
    :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: The name for this instance template. The name is unique across
          all instance templates in the region.
    :param InstancePlacementTargetPrototype placement_target: (optional) The
          placement restrictions to use for the virtual server instance.
          If specified, `reservation_affinity.policy` must be `disabled`.
    :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 InstanceReservationAffinityPrototype reservation_affinity: (optional)
    :param ResourceGroupReference resource_group: The resource group for this
          instance template.
    :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
          attachments or instance network interfaces.
    :param VolumeAttachmentPrototypeInstanceByImageContext boot_volume_attachment:
          (optional) The boot volume attachment to create for the virtual server instance.
    :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.
    """

    def __init__(
        self,
        created_at: datetime,
        crn: str,
        href: str,
        id: str,
        name: str,
        resource_group: 'ResourceGroupReference',
        image: 'ImageIdentity',
        zone: 'ZoneIdentity',
        *,
        availability_policy: Optional['InstanceAvailabilityPolicyPrototype'] = None,
        cluster_network_attachments: Optional[List['InstanceClusterNetworkAttachmentPrototypeInstanceContext']] = None,
        confidential_compute_mode: Optional[str] = None,
        default_trusted_profile: Optional['InstanceDefaultTrustedProfilePrototype'] = None,
        enable_secure_boot: Optional[bool] = None,
        keys: Optional[List['KeyIdentity']] = None,
        metadata_service: Optional['InstanceMetadataServicePrototype'] = None,
        placement_target: Optional['InstancePlacementTargetPrototype'] = None,
        profile: Optional['InstanceProfileIdentity'] = None,
        reservation_affinity: Optional['InstanceReservationAffinityPrototype'] = None,
        total_volume_bandwidth: Optional[int] = None,
        user_data: Optional[str] = None,
        volume_attachments: Optional[List['VolumeAttachmentPrototype']] = None,
        vpc: Optional['VPCIdentity'] = None,
        boot_volume_attachment: Optional['VolumeAttachmentPrototypeInstanceByImageContext'] = 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 List[InstanceClusterNetworkAttachmentPrototypeInstanceContext]
               cluster_network_attachments: (optional) The cluster network attachments to
               create for this virtual server instance. A cluster network attachment
               represents a device that is connected to a cluster network. The number of
               network attachments must match one of the values from the instance
               profile's `cluster_network_attachment_count` before the instance can be
               started.
        :param str confidential_compute_mode: (optional) The confidential compute
               mode to use for this virtual server instance.
               If unspecified, the default confidential compute mode from the profile will
               be used.
        :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 bool enable_secure_boot: (optional) Indicates whether secure boot is
               enabled for this virtual server instance.
               If unspecified, the default secure boot mode from the profile will be used.
        :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.
               If specified, `reservation_affinity.policy` must be `disabled`.
        :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 InstanceReservationAffinityPrototype reservation_affinity:
               (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
               attachments or instance network interfaces.
        :param VolumeAttachmentPrototypeInstanceByImageContext
               boot_volume_attachment: (optional) The boot volume attachment to create for
               the virtual server instance.
        """
        # pylint: disable=super-init-not-called
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['InstanceTemplateInstanceByImageInstanceTemplateContextInstanceByImageInstanceTemplateContextInstanceByNetworkAttachment', 'InstanceTemplateInstanceByImageInstanceTemplateContextInstanceByImageInstanceTemplateContextInstanceByNetworkInterface'])
        )
        raise Exception(msg)

    class ConfidentialComputeModeEnum(str, Enum):
        """
        The confidential compute mode to use for this virtual server instance.
        If unspecified, the default confidential compute mode from the profile will be
        used.
        """

        DISABLED = 'disabled'
        SGX = 'sgx'



class InstanceTemplateInstanceBySourceSnapshotInstanceTemplateContext(InstanceTemplate):
    """
    Create an instance by using a snapshot.

    :param InstanceAvailabilityPolicyPrototype availability_policy: (optional) The
          availability policy to use for this virtual server instance.
    :param List[InstanceClusterNetworkAttachmentPrototypeInstanceContext]
          cluster_network_attachments: (optional) The cluster network attachments to
          create for this virtual server instance. A cluster network attachment represents
          a device that is connected to a cluster network. The number of network
          attachments must match one of the values from the instance profile's
          `cluster_network_attachment_count` before the instance can be started.
    :param str confidential_compute_mode: (optional) The confidential compute mode
          to use for this virtual server instance.
          If unspecified, the default confidential compute mode from the profile will be
          used.
    :param datetime created_at: The date and time that the instance template was
          created.
    :param str crn: The CRN for this instance template.
    :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 bool enable_secure_boot: (optional) Indicates whether secure boot is
          enabled for this virtual server instance.
          If unspecified, the default secure boot mode from the profile will be used.
    :param str href: The URL for this instance template.
    :param str id: The unique identifier for this instance template.
    :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: The name for this instance template. The name is unique across
          all instance templates in the region.
    :param InstancePlacementTargetPrototype placement_target: (optional) The
          placement restrictions to use for the virtual server instance.
          If specified, `reservation_affinity.policy` must be `disabled`.
    :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 InstanceReservationAffinityPrototype reservation_affinity: (optional)
    :param ResourceGroupReference resource_group: The resource group for this
          instance template.
    :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
          attachments or instance network interfaces.
    :param VolumeAttachmentPrototypeInstanceBySourceSnapshotContext
          boot_volume_attachment: The boot volume attachment to create for the virtual
          server instance.
    :param List[InstanceNetworkAttachmentPrototype] network_attachments: (optional)
          The additional network attachments to create for the virtual server instance.
    :param List[NetworkInterfacePrototype] network_interfaces: (optional) The
          additional instance network interfaces to create.
    :param InstanceNetworkAttachmentPrototype primary_network_attachment: (optional)
          The primary network attachment to create for the virtual server instance.
    :param 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: Optional['InstanceAvailabilityPolicyPrototype'] = None,
        cluster_network_attachments: Optional[List['InstanceClusterNetworkAttachmentPrototypeInstanceContext']] = None,
        confidential_compute_mode: Optional[str] = None,
        default_trusted_profile: Optional['InstanceDefaultTrustedProfilePrototype'] = None,
        enable_secure_boot: Optional[bool] = None,
        keys: Optional[List['KeyIdentity']] = None,
        metadata_service: Optional['InstanceMetadataServicePrototype'] = None,
        placement_target: Optional['InstancePlacementTargetPrototype'] = None,
        profile: Optional['InstanceProfileIdentity'] = None,
        reservation_affinity: Optional['InstanceReservationAffinityPrototype'] = None,
        total_volume_bandwidth: Optional[int] = None,
        user_data: Optional[str] = None,
        volume_attachments: Optional[List['VolumeAttachmentPrototype']] = None,
        vpc: Optional['VPCIdentity'] = None,
        network_attachments: Optional[List['InstanceNetworkAttachmentPrototype']] = None,
        network_interfaces: Optional[List['NetworkInterfacePrototype']] = None,
        primary_network_attachment: Optional['InstanceNetworkAttachmentPrototype'] = 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 List[InstanceClusterNetworkAttachmentPrototypeInstanceContext]
               cluster_network_attachments: (optional) The cluster network attachments to
               create for this virtual server instance. A cluster network attachment
               represents a device that is connected to a cluster network. The number of
               network attachments must match one of the values from the instance
               profile's `cluster_network_attachment_count` before the instance can be
               started.
        :param str confidential_compute_mode: (optional) The confidential compute
               mode to use for this virtual server instance.
               If unspecified, the default confidential compute mode from the profile will
               be used.
        :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 bool enable_secure_boot: (optional) Indicates whether secure boot is
               enabled for this virtual server instance.
               If unspecified, the default secure boot mode from the profile will be used.
        :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.
               If specified, `reservation_affinity.policy` must be `disabled`.
        :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 InstanceReservationAffinityPrototype reservation_affinity:
               (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
               attachments or instance network interfaces.
        :param List[InstanceNetworkAttachmentPrototype] network_attachments:
               (optional) The additional network attachments to create for the virtual
               server instance.
        :param List[NetworkInterfacePrototype] network_interfaces: (optional) The
               additional instance network interfaces to create.
        :param InstanceNetworkAttachmentPrototype primary_network_attachment:
               (optional) The primary network attachment to create for the virtual server
               instance.
        """
        # pylint: disable=super-init-not-called
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['InstanceTemplateInstanceBySourceSnapshotInstanceTemplateContextInstanceBySourceSnapshotInstanceTemplateContextInstanceByNetworkAttachment', 'InstanceTemplateInstanceBySourceSnapshotInstanceTemplateContextInstanceBySourceSnapshotInstanceTemplateContextInstanceByNetworkInterface'])
        )
        raise Exception(msg)

    class ConfidentialComputeModeEnum(str, Enum):
        """
        The confidential compute mode to use for this virtual server instance.
        If unspecified, the default confidential compute mode from the profile will be
        used.
        """

        DISABLED = 'disabled'
        SGX = 'sgx'



class KeyIdentityByCRN(KeyIdentity):
    """
    KeyIdentityByCRN.

    :param 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 := _dict.get('crn')) is not None:
            args['crn'] = 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.

    :param 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 := _dict.get('fingerprint')) is not None:
            args['fingerprint'] = 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.

    :param 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 := _dict.get('href')) is not None:
            args['href'] = 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.

    :param 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 := _dict.get('id')) is not None:
            args['id'] = 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.

    :param 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 := _dict.get('name')) is not None:
            args['name'] = 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.

    :param str crn: The CRN for this load balancer.
    """

    def __init__(
        self,
        crn: str,
    ) -> None:
        """
        Initialize a LoadBalancerIdentityByCRN object.

        :param str crn: The CRN for this load balancer.
        """
        # 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 := _dict.get('crn')) is not None:
            args['crn'] = 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.

    :param str href: The URL for this load balancer.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a LoadBalancerIdentityByHref object.

        :param str href: The URL for this load balancer.
        """
        # 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 := _dict.get('href')) is not None:
            args['href'] = 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.

    :param 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 := _dict.get('id')) is not None:
            args['id'] = 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 LoadBalancerListenerDefaultPoolPatchLoadBalancerPoolIdentityByHref(LoadBalancerListenerDefaultPoolPatch):
    """
    LoadBalancerListenerDefaultPoolPatchLoadBalancerPoolIdentityByHref.

    :param str href: The URL for this load balancer pool.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a LoadBalancerListenerDefaultPoolPatchLoadBalancerPoolIdentityByHref object.

        :param str href: The URL for this load balancer pool.
        """
        # pylint: disable=super-init-not-called
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerListenerDefaultPoolPatchLoadBalancerPoolIdentityByHref':
        """Initialize a LoadBalancerListenerDefaultPoolPatchLoadBalancerPoolIdentityByHref object from a json dictionary."""
        args = {}
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in LoadBalancerListenerDefaultPoolPatchLoadBalancerPoolIdentityByHref JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerListenerDefaultPoolPatchLoadBalancerPoolIdentityByHref object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancerListenerDefaultPoolPatchLoadBalancerPoolIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerListenerDefaultPoolPatchLoadBalancerPoolIdentityByHref') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerListenerDefaultPoolPatchLoadBalancerPoolIdentityByHref') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class LoadBalancerListenerDefaultPoolPatchLoadBalancerPoolIdentityById(LoadBalancerListenerDefaultPoolPatch):
    """
    LoadBalancerListenerDefaultPoolPatchLoadBalancerPoolIdentityById.

    :param str id: The unique identifier for this load balancer pool.
    """

    def __init__(
        self,
        id: str,
    ) -> None:
        """
        Initialize a LoadBalancerListenerDefaultPoolPatchLoadBalancerPoolIdentityById 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) -> 'LoadBalancerListenerDefaultPoolPatchLoadBalancerPoolIdentityById':
        """Initialize a LoadBalancerListenerDefaultPoolPatchLoadBalancerPoolIdentityById object from a json dictionary."""
        args = {}
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in LoadBalancerListenerDefaultPoolPatchLoadBalancerPoolIdentityById JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerListenerDefaultPoolPatchLoadBalancerPoolIdentityById object from 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 LoadBalancerListenerDefaultPoolPatchLoadBalancerPoolIdentityById object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerListenerDefaultPoolPatchLoadBalancerPoolIdentityById') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerListenerDefaultPoolPatchLoadBalancerPoolIdentityById') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class LoadBalancerListenerIdentityByHref(LoadBalancerListenerIdentity):
    """
    LoadBalancerListenerIdentityByHref.

    :param str href: The URL for this load balancer listener.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a LoadBalancerListenerIdentityByHref object.

        :param str href: The URL for this load balancer listener.
        """
        # 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 := _dict.get('href')) is not None:
            args['href'] = 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.

    :param 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 := _dict.get('id')) is not None:
            args['id'] = 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 LoadBalancerListenerPolicyTargetPatchLoadBalancerListenerPolicyHTTPSRedirectPatch(LoadBalancerListenerPolicyTargetPatch):
    """
    LoadBalancerListenerPolicyTargetPatchLoadBalancerListenerPolicyHTTPSRedirectPatch.

    :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.
    """

    def __init__(
        self,
        *,
        http_status_code: Optional[int] = None,
        listener: Optional['LoadBalancerListenerIdentity'] = None,
        uri: Optional[str] = None,
    ) -> None:
        """
        Initialize a LoadBalancerListenerPolicyTargetPatchLoadBalancerListenerPolicyHTTPSRedirectPatch 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) -> 'LoadBalancerListenerPolicyTargetPatchLoadBalancerListenerPolicyHTTPSRedirectPatch':
        """Initialize a LoadBalancerListenerPolicyTargetPatchLoadBalancerListenerPolicyHTTPSRedirectPatch object from a json dictionary."""
        args = {}
        if (http_status_code := _dict.get('http_status_code')) is not None:
            args['http_status_code'] = http_status_code
        if (listener := _dict.get('listener')) is not None:
            args['listener'] = listener
        if (uri := _dict.get('uri')) is not None:
            args['uri'] = uri
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerListenerPolicyTargetPatchLoadBalancerListenerPolicyHTTPSRedirectPatch object from 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 LoadBalancerListenerPolicyTargetPatchLoadBalancerListenerPolicyHTTPSRedirectPatch object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerListenerPolicyTargetPatchLoadBalancerListenerPolicyHTTPSRedirectPatch') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerListenerPolicyTargetPatchLoadBalancerListenerPolicyHTTPSRedirectPatch') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class LoadBalancerListenerPolicyTargetPatchLoadBalancerListenerPolicyRedirectURLPatch(LoadBalancerListenerPolicyTargetPatch):
    """
    LoadBalancerListenerPolicyTargetPatchLoadBalancerListenerPolicyRedirectURLPatch.

    :param int http_status_code: (optional) The HTTP status code for this redirect.
    :param str url: (optional) The redirect target URL. The URL supports [RFC 6570
          level 1 expressions](https://datatracker.ietf.org/doc/html/rfc6570#section-1.2)
          for the following variables which expand to values from the originally requested
          URL (or the indicated defaults if the request did not include them):
          - `protocol`
          - `host`
          - `port`  (default: `80` for HTTP requests, `443` for HTTPS requests)
          - `path`  (default: '/')
          - `query` (default: '')
          The protocol, host, and port segments of the URL, must only contain at most one
          instance of the `protocol`, `host`, and `port` variables, respectively. The path
          and query segments of the URL may contain any combination of variables. If the
          substitution of `path` results in consecutive leading slashes, the leading slash
          from the substitution will be removed. Additional examples:
          - `https://{host}:8080/{port}/{host}/{path}`
          - `https://www.example.com`
          - `{protocol}://test.{host}:80/{path}`.
    """

    def __init__(
        self,
        *,
        http_status_code: Optional[int] = None,
        url: Optional[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. The URL supports [RFC
               6570 level 1
               expressions](https://datatracker.ietf.org/doc/html/rfc6570#section-1.2) for
               the following variables which expand to values from the originally
               requested URL (or the indicated defaults if the request did not include
               them):
               - `protocol`
               - `host`
               - `port`  (default: `80` for HTTP requests, `443` for HTTPS requests)
               - `path`  (default: '/')
               - `query` (default: '')
               The protocol, host, and port segments of the URL, must only contain at most
               one instance of the `protocol`, `host`, and `port` variables, respectively.
               The path and query segments of the URL may contain any combination of
               variables. If the substitution of `path` results in consecutive leading
               slashes, the leading slash from the substitution will be removed.
               Additional examples:
               - `https://{host}:8080/{port}/{host}/{path}`
               - `https://www.example.com`
               - `{protocol}://test.{host}:80/{path}`.
        """
        # 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 := _dict.get('http_status_code')) is not None:
            args['http_status_code'] = http_status_code
        if (url := _dict.get('url')) is not None:
            args['url'] = 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(['LoadBalancerListenerPolicyTargetPatchLoadBalancerPoolIdentityLoadBalancerPoolIdentityLoadBalancerPoolIdentityById', 'LoadBalancerListenerPolicyTargetPatchLoadBalancerPoolIdentityLoadBalancerPoolIdentityLoadBalancerPoolIdentityByHref'])
        )
        raise Exception(msg)


class LoadBalancerListenerPolicyTargetPrototypeLoadBalancerListenerPolicyHTTPSRedirectPrototype(LoadBalancerListenerPolicyTargetPrototype):
    """
    LoadBalancerListenerPolicyTargetPrototypeLoadBalancerListenerPolicyHTTPSRedirectPrototype.

    :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.
    """

    def __init__(
        self,
        http_status_code: int,
        listener: 'LoadBalancerListenerIdentity',
        *,
        uri: Optional[str] = None,
    ) -> None:
        """
        Initialize a LoadBalancerListenerPolicyTargetPrototypeLoadBalancerListenerPolicyHTTPSRedirectPrototype 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) -> 'LoadBalancerListenerPolicyTargetPrototypeLoadBalancerListenerPolicyHTTPSRedirectPrototype':
        """Initialize a LoadBalancerListenerPolicyTargetPrototypeLoadBalancerListenerPolicyHTTPSRedirectPrototype object from a json dictionary."""
        args = {}
        if (http_status_code := _dict.get('http_status_code')) is not None:
            args['http_status_code'] = http_status_code
        else:
            raise ValueError('Required property \'http_status_code\' not present in LoadBalancerListenerPolicyTargetPrototypeLoadBalancerListenerPolicyHTTPSRedirectPrototype JSON')
        if (listener := _dict.get('listener')) is not None:
            args['listener'] = listener
        else:
            raise ValueError('Required property \'listener\' not present in LoadBalancerListenerPolicyTargetPrototypeLoadBalancerListenerPolicyHTTPSRedirectPrototype JSON')
        if (uri := _dict.get('uri')) is not None:
            args['uri'] = uri
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerListenerPolicyTargetPrototypeLoadBalancerListenerPolicyHTTPSRedirectPrototype object from 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 LoadBalancerListenerPolicyTargetPrototypeLoadBalancerListenerPolicyHTTPSRedirectPrototype object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerListenerPolicyTargetPrototypeLoadBalancerListenerPolicyHTTPSRedirectPrototype') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerListenerPolicyTargetPrototypeLoadBalancerListenerPolicyHTTPSRedirectPrototype') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class LoadBalancerListenerPolicyTargetPrototypeLoadBalancerListenerPolicyRedirectURLPrototype(LoadBalancerListenerPolicyTargetPrototype):
    """
    LoadBalancerListenerPolicyTargetPrototypeLoadBalancerListenerPolicyRedirectURLPrototype.

    :param int http_status_code: The HTTP status code for this redirect.
    :param str url: The redirect target URL. The URL supports [RFC 6570 level 1
          expressions](https://datatracker.ietf.org/doc/html/rfc6570#section-1.2) for the
          following variables which expand to values from the originally requested URL (or
          the indicated defaults if the request did not include them):
          - `protocol`
          - `host`
          - `port`  (default: `80` for HTTP requests, `443` for HTTPS requests)
          - `path`  (default: '/')
          - `query` (default: '')
          The protocol, host, and port segments of the URL, must only contain at most one
          instance of the `protocol`, `host`, and `port` variables, respectively. The path
          and query segments of the URL may contain any combination of variables. If the
          substitution of `path` results in consecutive leading slashes, the leading slash
          from the substitution will be removed. Additional examples:
          - `https://{host}:8080/{port}/{host}/{path}`
          - `https://www.example.com`
          - `{protocol}://test.{host}:80/{path}`.
    """

    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. The URL supports [RFC 6570 level 1
               expressions](https://datatracker.ietf.org/doc/html/rfc6570#section-1.2) for
               the following variables which expand to values from the originally
               requested URL (or the indicated defaults if the request did not include
               them):
               - `protocol`
               - `host`
               - `port`  (default: `80` for HTTP requests, `443` for HTTPS requests)
               - `path`  (default: '/')
               - `query` (default: '')
               The protocol, host, and port segments of the URL, must only contain at most
               one instance of the `protocol`, `host`, and `port` variables, respectively.
               The path and query segments of the URL may contain any combination of
               variables. If the substitution of `path` results in consecutive leading
               slashes, the leading slash from the substitution will be removed.
               Additional examples:
               - `https://{host}:8080/{port}/{host}/{path}`
               - `https://www.example.com`
               - `{protocol}://test.{host}:80/{path}`.
        """
        # 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 := _dict.get('http_status_code')) is not None:
            args['http_status_code'] = http_status_code
        else:
            raise ValueError('Required property \'http_status_code\' not present in LoadBalancerListenerPolicyTargetPrototypeLoadBalancerListenerPolicyRedirectURLPrototype JSON')
        if (url := _dict.get('url')) is not None:
            args['url'] = 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(['LoadBalancerListenerPolicyTargetPrototypeLoadBalancerPoolIdentityLoadBalancerPoolIdentityLoadBalancerPoolIdentityById', 'LoadBalancerListenerPolicyTargetPrototypeLoadBalancerPoolIdentityLoadBalancerPoolIdentityLoadBalancerPoolIdentityByHref'])
        )
        raise Exception(msg)


class LoadBalancerListenerPolicyTargetLoadBalancerListenerPolicyHTTPSRedirect(LoadBalancerListenerPolicyTarget):
    """
    LoadBalancerListenerPolicyTargetLoadBalancerListenerPolicyHTTPSRedirect.

    :param int http_status_code: The HTTP status code for this redirect.
    :param LoadBalancerListenerReference listener:
    :param str uri: (optional) The redirect relative target URI.
    """

    def __init__(
        self,
        http_status_code: int,
        listener: 'LoadBalancerListenerReference',
        *,
        uri: Optional[str] = None,
    ) -> None:
        """
        Initialize a LoadBalancerListenerPolicyTargetLoadBalancerListenerPolicyHTTPSRedirect 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) -> 'LoadBalancerListenerPolicyTargetLoadBalancerListenerPolicyHTTPSRedirect':
        """Initialize a LoadBalancerListenerPolicyTargetLoadBalancerListenerPolicyHTTPSRedirect object from a json dictionary."""
        args = {}
        if (http_status_code := _dict.get('http_status_code')) is not None:
            args['http_status_code'] = http_status_code
        else:
            raise ValueError('Required property \'http_status_code\' not present in LoadBalancerListenerPolicyTargetLoadBalancerListenerPolicyHTTPSRedirect JSON')
        if (listener := _dict.get('listener')) is not None:
            args['listener'] = LoadBalancerListenerReference.from_dict(listener)
        else:
            raise ValueError('Required property \'listener\' not present in LoadBalancerListenerPolicyTargetLoadBalancerListenerPolicyHTTPSRedirect JSON')
        if (uri := _dict.get('uri')) is not None:
            args['uri'] = uri
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerListenerPolicyTargetLoadBalancerListenerPolicyHTTPSRedirect object from 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 LoadBalancerListenerPolicyTargetLoadBalancerListenerPolicyHTTPSRedirect object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerListenerPolicyTargetLoadBalancerListenerPolicyHTTPSRedirect') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerListenerPolicyTargetLoadBalancerListenerPolicyHTTPSRedirect') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class LoadBalancerListenerPolicyTargetLoadBalancerListenerPolicyRedirectURL(LoadBalancerListenerPolicyTarget):
    """
    LoadBalancerListenerPolicyTargetLoadBalancerListenerPolicyRedirectURL.

    :param int http_status_code: The HTTP status code for this redirect.
    :param str url: The redirect target URL. The URL supports [RFC 6570 level 1
          expressions](https://datatracker.ietf.org/doc/html/rfc6570#section-1.2) for the
          following variables which expand to values from the originally requested URL (or
          the indicated defaults if the request did not include them):
          - `protocol`
          - `host`
          - `port`  (default: `80` for HTTP requests, `443` for HTTPS requests)
          - `path`  (default: '/')
          - `query` (default: '')
          The protocol, host, and port segments of the URL, must only contain at most one
          instance of the `protocol`, `host`, and `port` variables, respectively. The path
          and query segments of the URL may contain any combination of variables. If the
          substitution of `path` results in consecutive leading slashes, the leading slash
          from the substitution will be removed. Additional examples:
          - `https://{host}:8080/{port}/{host}/{path}`
          - `https://www.example.com`
          - `{protocol}://test.{host}:80/{path}`.
    """

    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. The URL supports [RFC 6570 level 1
               expressions](https://datatracker.ietf.org/doc/html/rfc6570#section-1.2) for
               the following variables which expand to values from the originally
               requested URL (or the indicated defaults if the request did not include
               them):
               - `protocol`
               - `host`
               - `port`  (default: `80` for HTTP requests, `443` for HTTPS requests)
               - `path`  (default: '/')
               - `query` (default: '')
               The protocol, host, and port segments of the URL, must only contain at most
               one instance of the `protocol`, `host`, and `port` variables, respectively.
               The path and query segments of the URL may contain any combination of
               variables. If the substitution of `path` results in consecutive leading
               slashes, the leading slash from the substitution will be removed.
               Additional examples:
               - `https://{host}:8080/{port}/{host}/{path}`
               - `https://www.example.com`
               - `{protocol}://test.{host}:80/{path}`.
        """
        # 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 := _dict.get('http_status_code')) is not None:
            args['http_status_code'] = http_status_code
        else:
            raise ValueError('Required property \'http_status_code\' not present in LoadBalancerListenerPolicyTargetLoadBalancerListenerPolicyRedirectURL JSON')
        if (url := _dict.get('url')) is not None:
            args['url'] = 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.

    :param Deleted deleted: (optional) If present, this property indicates the
          referenced resource has been deleted, and provides
          some supplementary information.
    :param str href: The URL for this load balancer pool.
    :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.
    """

    def __init__(
        self,
        href: str,
        id: str,
        name: str,
        *,
        deleted: Optional['Deleted'] = None,
    ) -> None:
        """
        Initialize a LoadBalancerListenerPolicyTargetLoadBalancerPoolReference object.

        :param str href: The URL for this load balancer pool.
        :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 Deleted 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 := _dict.get('deleted')) is not None:
            args['deleted'] = Deleted.from_dict(deleted)
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in LoadBalancerListenerPolicyTargetLoadBalancerPoolReference JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in LoadBalancerListenerPolicyTargetLoadBalancerPoolReference JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = 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 LoadBalancerPoolIdentityLoadBalancerPoolIdentityByHref(LoadBalancerPoolIdentity):
    """
    LoadBalancerPoolIdentityLoadBalancerPoolIdentityByHref.

    :param str href: The URL for this load balancer pool.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a LoadBalancerPoolIdentityLoadBalancerPoolIdentityByHref object.

        :param str href: The URL for this load balancer pool.
        """
        # pylint: disable=super-init-not-called
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerPoolIdentityLoadBalancerPoolIdentityByHref':
        """Initialize a LoadBalancerPoolIdentityLoadBalancerPoolIdentityByHref object from a json dictionary."""
        args = {}
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in LoadBalancerPoolIdentityLoadBalancerPoolIdentityByHref JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerPoolIdentityLoadBalancerPoolIdentityByHref object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancerPoolIdentityLoadBalancerPoolIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerPoolIdentityLoadBalancerPoolIdentityByHref') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerPoolIdentityLoadBalancerPoolIdentityByHref') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class LoadBalancerPoolIdentityLoadBalancerPoolIdentityById(LoadBalancerPoolIdentity):
    """
    LoadBalancerPoolIdentityLoadBalancerPoolIdentityById.

    :param str id: The unique identifier for this load balancer pool.
    """

    def __init__(
        self,
        id: str,
    ) -> None:
        """
        Initialize a LoadBalancerPoolIdentityLoadBalancerPoolIdentityById 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) -> 'LoadBalancerPoolIdentityLoadBalancerPoolIdentityById':
        """Initialize a LoadBalancerPoolIdentityLoadBalancerPoolIdentityById object from a json dictionary."""
        args = {}
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in LoadBalancerPoolIdentityLoadBalancerPoolIdentityById JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerPoolIdentityLoadBalancerPoolIdentityById object from 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 LoadBalancerPoolIdentityLoadBalancerPoolIdentityById object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerPoolIdentityLoadBalancerPoolIdentityById') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerPoolIdentityLoadBalancerPoolIdentityById') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class LoadBalancerPoolMemberTargetPrototypeIP(LoadBalancerPoolMemberTargetPrototype):
    """
    LoadBalancerPoolMemberTargetPrototypeIP.

    :param str address: The IP address.
          This property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) to support
          IPv6 addresses in the future.
    """

    def __init__(
        self,
        address: str,
    ) -> None:
        """
        Initialize a LoadBalancerPoolMemberTargetPrototypeIP object.

        :param str address: The IP address.
               This property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) to
               support IPv6 addresses in the future.
        """
        # 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 := _dict.get('address')) is not None:
            args['address'] = 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.

    :param str address: The IP address.
          This property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) to support
          IPv6 addresses in the future.
    """

    def __init__(
        self,
        address: str,
    ) -> None:
        """
        Initialize a LoadBalancerPoolMemberTargetIP object.

        :param str address: The IP address.
               This property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) to
               support IPv6 addresses in the future.
        """
        # 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 := _dict.get('address')) is not None:
            args['address'] = 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.

    :param str crn: The CRN for this virtual server instance.
    :param Deleted deleted: (optional) If present, this property indicates the
          referenced resource has been deleted, and provides
          some supplementary information.
    :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.
    """

    def __init__(
        self,
        crn: str,
        href: str,
        id: str,
        name: str,
        *,
        deleted: Optional['Deleted'] = 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 Deleted 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 := _dict.get('crn')) is not None:
            args['crn'] = crn
        else:
            raise ValueError('Required property \'crn\' not present in LoadBalancerPoolMemberTargetInstanceReference JSON')
        if (deleted := _dict.get('deleted')) is not None:
            args['deleted'] = Deleted.from_dict(deleted)
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in LoadBalancerPoolMemberTargetInstanceReference JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in LoadBalancerPoolMemberTargetInstanceReference JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = 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 LoadBalancerProfileAvailabilityDependent(LoadBalancerProfileAvailability):
    """
    The availability mode for a load balancer with this profile depends on its
    configuration.

    :param str type: The type for this profile field.
    """

    def __init__(
        self,
        type: str,
    ) -> None:
        """
        Initialize a LoadBalancerProfileAvailabilityDependent 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) -> 'LoadBalancerProfileAvailabilityDependent':
        """Initialize a LoadBalancerProfileAvailabilityDependent object from a json dictionary."""
        args = {}
        if (type := _dict.get('type')) is not None:
            args['type'] = type
        else:
            raise ValueError('Required property \'type\' not present in LoadBalancerProfileAvailabilityDependent JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerProfileAvailabilityDependent object from 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 LoadBalancerProfileAvailabilityDependent object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerProfileAvailabilityDependent') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerProfileAvailabilityDependent') -> 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 LoadBalancerProfileAvailabilityFixed(LoadBalancerProfileAvailability):
    """
    The availability mode for a load balancer with this profile.

    :param str type: The type for this profile field.
    :param str value: The availability of this load balancer:
          - `subnet`: remains available if at least one zone that the load balancer's
          subnets reside
            in is available
          - `region`: remains available if at least one zone in the region is available.
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    """

    def __init__(
        self,
        type: str,
        value: str,
    ) -> None:
        """
        Initialize a LoadBalancerProfileAvailabilityFixed object.

        :param str type: The type for this profile field.
        :param str value: The availability of this load balancer:
               - `subnet`: remains available if at least one zone that the load balancer's
               subnets reside
                 in is available
               - `region`: remains available if at least one zone in the region is
               available.
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        """
        # pylint: disable=super-init-not-called
        self.type = type
        self.value = value

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerProfileAvailabilityFixed':
        """Initialize a LoadBalancerProfileAvailabilityFixed object from a json dictionary."""
        args = {}
        if (type := _dict.get('type')) is not None:
            args['type'] = type
        else:
            raise ValueError('Required property \'type\' not present in LoadBalancerProfileAvailabilityFixed JSON')
        if (value := _dict.get('value')) is not None:
            args['value'] = value
        else:
            raise ValueError('Required property \'value\' not present in LoadBalancerProfileAvailabilityFixed JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerProfileAvailabilityFixed object from 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 LoadBalancerProfileAvailabilityFixed object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerProfileAvailabilityFixed') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerProfileAvailabilityFixed') -> 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 availability of this load balancer:
        - `subnet`: remains available if at least one zone that the load balancer's
        subnets reside
          in is available
        - `region`: remains available if at least one zone in the region is available.
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        REGION = 'region'
        SUBNET = 'subnet'



class LoadBalancerProfileIdentityByHref(LoadBalancerProfileIdentity):
    """
    LoadBalancerProfileIdentityByHref.

    :param 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 := _dict.get('href')) is not None:
            args['href'] = 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.

    :param 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 := _dict.get('name')) is not None:
            args['name'] = 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.

    :param 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 := _dict.get('type')) is not None:
            args['type'] = 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.

    :param str type: The type for this profile field.
    :param 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 := _dict.get('type')) is not None:
            args['type'] = type
        else:
            raise ValueError('Required property \'type\' not present in LoadBalancerProfileInstanceGroupsSupportedFixed JSON')
        if (value := _dict.get('value')) is not None:
            args['value'] = 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.

    :param 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 := _dict.get('type')) is not None:
            args['type'] = 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.

    :param str type: The type for this profile field.
    :param 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 := _dict.get('type')) is not None:
            args['type'] = type
        else:
            raise ValueError('Required property \'type\' not present in LoadBalancerProfileRouteModeSupportedFixed JSON')
        if (value := _dict.get('value')) is not None:
            args['value'] = 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.

    :param 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 := _dict.get('type')) is not None:
            args['type'] = 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.

    :param str type: The type for this profile field.
    :param 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 := _dict.get('type')) is not None:
            args['type'] = type
        else:
            raise ValueError('Required property \'type\' not present in LoadBalancerProfileSecurityGroupsSupportedFixed JSON')
        if (value := _dict.get('value')) is not None:
            args['value'] = 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 LoadBalancerProfileSourceIPSessionPersistenceSupportedDependent(LoadBalancerProfileSourceIPSessionPersistenceSupported):
    """
    The source IP session persistence support for a load balancer with this profile
    depends on its configuration.

    :param str type: The type for this profile field.
    """

    def __init__(
        self,
        type: str,
    ) -> None:
        """
        Initialize a LoadBalancerProfileSourceIPSessionPersistenceSupportedDependent 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) -> 'LoadBalancerProfileSourceIPSessionPersistenceSupportedDependent':
        """Initialize a LoadBalancerProfileSourceIPSessionPersistenceSupportedDependent object from a json dictionary."""
        args = {}
        if (type := _dict.get('type')) is not None:
            args['type'] = type
        else:
            raise ValueError('Required property \'type\' not present in LoadBalancerProfileSourceIPSessionPersistenceSupportedDependent JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerProfileSourceIPSessionPersistenceSupportedDependent object from 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 LoadBalancerProfileSourceIPSessionPersistenceSupportedDependent object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerProfileSourceIPSessionPersistenceSupportedDependent') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerProfileSourceIPSessionPersistenceSupportedDependent') -> 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 LoadBalancerProfileSourceIPSessionPersistenceSupportedFixed(LoadBalancerProfileSourceIPSessionPersistenceSupported):
    """
    The source IP session persistence support for a load balancer with this profile.

    :param str type: The type for this profile field.
    :param bool value: The value for this profile field.
    """

    def __init__(
        self,
        type: str,
        value: bool,
    ) -> None:
        """
        Initialize a LoadBalancerProfileSourceIPSessionPersistenceSupportedFixed 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) -> 'LoadBalancerProfileSourceIPSessionPersistenceSupportedFixed':
        """Initialize a LoadBalancerProfileSourceIPSessionPersistenceSupportedFixed object from a json dictionary."""
        args = {}
        if (type := _dict.get('type')) is not None:
            args['type'] = type
        else:
            raise ValueError('Required property \'type\' not present in LoadBalancerProfileSourceIPSessionPersistenceSupportedFixed JSON')
        if (value := _dict.get('value')) is not None:
            args['value'] = value
        else:
            raise ValueError('Required property \'value\' not present in LoadBalancerProfileSourceIPSessionPersistenceSupportedFixed JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerProfileSourceIPSessionPersistenceSupportedFixed object from 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 LoadBalancerProfileSourceIPSessionPersistenceSupportedFixed object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerProfileSourceIPSessionPersistenceSupportedFixed') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerProfileSourceIPSessionPersistenceSupportedFixed') -> 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.

    :param 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 := _dict.get('type')) is not None:
            args['type'] = 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.

    :param str type: The type for this profile field.
    :param 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 := _dict.get('type')) is not None:
            args['type'] = type
        else:
            raise ValueError('Required property \'type\' not present in LoadBalancerProfileUDPSupportedFixed JSON')
        if (value := _dict.get('value')) is not None:
            args['value'] = 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.

    :param 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 := _dict.get('crn')) is not None:
            args['crn'] = 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.

    :param 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 := _dict.get('href')) is not None:
            args['href'] = 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.

    :param 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 := _dict.get('id')) is not None:
            args['id'] = 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.

    :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 VPCIdentity vpc: The VPC this network ACL will reside in.
    :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.
    """

    def __init__(
        self,
        vpc: 'VPCIdentity',
        *,
        name: Optional[str] = None,
        resource_group: Optional['ResourceGroupIdentity'] = None,
        rules: Optional[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 := _dict.get('name')) is not None:
            args['name'] = name
        if (resource_group := _dict.get('resource_group')) is not None:
            args['resource_group'] = resource_group
        if (vpc := _dict.get('vpc')) is not None:
            args['vpc'] = vpc
        else:
            raise ValueError('Required property \'vpc\' not present in NetworkACLPrototypeNetworkACLByRules JSON')
        if (rules := _dict.get('rules')) is not None:
            args['rules'] = [NetworkACLRulePrototypeNetworkACLContext.from_dict(v) for v in 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.

    :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 VPCIdentity vpc: The VPC this network ACL will reside in.
    :param NetworkACLIdentity source_network_acl: Network ACL to copy rules from.
    """

    def __init__(
        self,
        vpc: 'VPCIdentity',
        source_network_acl: 'NetworkACLIdentity',
        *,
        name: Optional[str] = None,
        resource_group: Optional['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 := _dict.get('name')) is not None:
            args['name'] = name
        if (resource_group := _dict.get('resource_group')) is not None:
            args['resource_group'] = resource_group
        if (vpc := _dict.get('vpc')) is not None:
            args['vpc'] = vpc
        else:
            raise ValueError('Required property \'vpc\' not present in NetworkACLPrototypeNetworkACLBySourceNetworkACL JSON')
        if (source_network_acl := _dict.get('source_network_acl')) is not None:
            args['source_network_acl'] = 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.

    :param 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 := _dict.get('href')) is not None:
            args['href'] = 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.

    :param 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 := _dict.get('id')) is not None:
            args['id'] = 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.

    :param 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 := _dict.get('href')) is not None:
            args['href'] = 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.

    :param 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 := _dict.get('id')) is not None:
            args['id'] = 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.

    :param str action: The action to perform for a packet matching the rule.
    :param NetworkACLRuleReference before: (optional) The rule that this rule is
          immediately before. In a rule collection, this always refers to the next item in
          the collection. If absent, this is the last rule.
    :param 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 network protocol.
    """

    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: Optional['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 network protocol.
        :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 := _dict.get('action')) is not None:
            args['action'] = action
        else:
            raise ValueError('Required property \'action\' not present in NetworkACLRuleItemNetworkACLRuleProtocolAll JSON')
        if (before := _dict.get('before')) is not None:
            args['before'] = NetworkACLRuleReference.from_dict(before)
        if (created_at := _dict.get('created_at')) is not None:
            args['created_at'] = string_to_datetime(created_at)
        else:
            raise ValueError('Required property \'created_at\' not present in NetworkACLRuleItemNetworkACLRuleProtocolAll JSON')
        if (destination := _dict.get('destination')) is not None:
            args['destination'] = destination
        else:
            raise ValueError('Required property \'destination\' not present in NetworkACLRuleItemNetworkACLRuleProtocolAll JSON')
        if (direction := _dict.get('direction')) is not None:
            args['direction'] = direction
        else:
            raise ValueError('Required property \'direction\' not present in NetworkACLRuleItemNetworkACLRuleProtocolAll JSON')
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in NetworkACLRuleItemNetworkACLRuleProtocolAll JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in NetworkACLRuleItemNetworkACLRuleProtocolAll JSON')
        if (ip_version := _dict.get('ip_version')) is not None:
            args['ip_version'] = ip_version
        else:
            raise ValueError('Required property \'ip_version\' not present in NetworkACLRuleItemNetworkACLRuleProtocolAll JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in NetworkACLRuleItemNetworkACLRuleProtocolAll JSON')
        if (source := _dict.get('source')) is not None:
            args['source'] = source
        else:
            raise ValueError('Required property \'source\' not present in NetworkACLRuleItemNetworkACLRuleProtocolAll JSON')
        if (protocol := _dict.get('protocol')) is not None:
            args['protocol'] = 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 network protocol.
        """

        ALL = 'all'



class NetworkACLRuleItemNetworkACLRuleProtocolICMP(NetworkACLRuleItem):
    """
    NetworkACLRuleItemNetworkACLRuleProtocolICMP.

    :param str action: The action to perform for a packet matching the rule.
    :param NetworkACLRuleReference before: (optional) The rule that this rule is
          immediately before. In a rule collection, this always refers to the next item in
          the collection. If absent, this is the last rule.
    :param 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 code: (optional) The ICMP traffic code to match.
          If absent, all codes are matched.
    :param str protocol: The network protocol.
    :param 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: Optional['NetworkACLRuleReference'] = None,
        code: Optional[int] = None,
        type: Optional[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 network protocol.
        :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 := _dict.get('action')) is not None:
            args['action'] = action
        else:
            raise ValueError('Required property \'action\' not present in NetworkACLRuleItemNetworkACLRuleProtocolICMP JSON')
        if (before := _dict.get('before')) is not None:
            args['before'] = NetworkACLRuleReference.from_dict(before)
        if (created_at := _dict.get('created_at')) is not None:
            args['created_at'] = string_to_datetime(created_at)
        else:
            raise ValueError('Required property \'created_at\' not present in NetworkACLRuleItemNetworkACLRuleProtocolICMP JSON')
        if (destination := _dict.get('destination')) is not None:
            args['destination'] = destination
        else:
            raise ValueError('Required property \'destination\' not present in NetworkACLRuleItemNetworkACLRuleProtocolICMP JSON')
        if (direction := _dict.get('direction')) is not None:
            args['direction'] = direction
        else:
            raise ValueError('Required property \'direction\' not present in NetworkACLRuleItemNetworkACLRuleProtocolICMP JSON')
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in NetworkACLRuleItemNetworkACLRuleProtocolICMP JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in NetworkACLRuleItemNetworkACLRuleProtocolICMP JSON')
        if (ip_version := _dict.get('ip_version')) is not None:
            args['ip_version'] = ip_version
        else:
            raise ValueError('Required property \'ip_version\' not present in NetworkACLRuleItemNetworkACLRuleProtocolICMP JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in NetworkACLRuleItemNetworkACLRuleProtocolICMP JSON')
        if (source := _dict.get('source')) is not None:
            args['source'] = source
        else:
            raise ValueError('Required property \'source\' not present in NetworkACLRuleItemNetworkACLRuleProtocolICMP JSON')
        if (code := _dict.get('code')) is not None:
            args['code'] = code
        if (protocol := _dict.get('protocol')) is not None:
            args['protocol'] = protocol
        else:
            raise ValueError('Required property \'protocol\' not present in NetworkACLRuleItemNetworkACLRuleProtocolICMP JSON')
        if (type := _dict.get('type')) is not None:
            args['type'] = 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 network protocol.
        """

        ICMP = 'icmp'



class NetworkACLRuleItemNetworkACLRuleProtocolTCPUDP(NetworkACLRuleItem):
    """
    NetworkACLRuleItemNetworkACLRuleProtocolTCPUDP.

    :param str action: The action to perform for a packet matching the rule.
    :param NetworkACLRuleReference before: (optional) The rule that this rule is
          immediately before. In a rule collection, this always refers to the next item in
          the collection. If absent, this is the last rule.
    :param 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 network protocol.
    :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.
    """

    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: Optional['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 network protocol.
        :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 := _dict.get('action')) is not None:
            args['action'] = action
        else:
            raise ValueError('Required property \'action\' not present in NetworkACLRuleItemNetworkACLRuleProtocolTCPUDP JSON')
        if (before := _dict.get('before')) is not None:
            args['before'] = NetworkACLRuleReference.from_dict(before)
        if (created_at := _dict.get('created_at')) is not None:
            args['created_at'] = string_to_datetime(created_at)
        else:
            raise ValueError('Required property \'created_at\' not present in NetworkACLRuleItemNetworkACLRuleProtocolTCPUDP JSON')
        if (destination := _dict.get('destination')) is not None:
            args['destination'] = destination
        else:
            raise ValueError('Required property \'destination\' not present in NetworkACLRuleItemNetworkACLRuleProtocolTCPUDP JSON')
        if (direction := _dict.get('direction')) is not None:
            args['direction'] = direction
        else:
            raise ValueError('Required property \'direction\' not present in NetworkACLRuleItemNetworkACLRuleProtocolTCPUDP JSON')
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in NetworkACLRuleItemNetworkACLRuleProtocolTCPUDP JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in NetworkACLRuleItemNetworkACLRuleProtocolTCPUDP JSON')
        if (ip_version := _dict.get('ip_version')) is not None:
            args['ip_version'] = ip_version
        else:
            raise ValueError('Required property \'ip_version\' not present in NetworkACLRuleItemNetworkACLRuleProtocolTCPUDP JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in NetworkACLRuleItemNetworkACLRuleProtocolTCPUDP JSON')
        if (source := _dict.get('source')) is not None:
            args['source'] = source
        else:
            raise ValueError('Required property \'source\' not present in NetworkACLRuleItemNetworkACLRuleProtocolTCPUDP JSON')
        if (destination_port_max := _dict.get('destination_port_max')) is not None:
            args['destination_port_max'] = destination_port_max
        else:
            raise ValueError('Required property \'destination_port_max\' not present in NetworkACLRuleItemNetworkACLRuleProtocolTCPUDP JSON')
        if (destination_port_min := _dict.get('destination_port_min')) is not None:
            args['destination_port_min'] = destination_port_min
        else:
            raise ValueError('Required property \'destination_port_min\' not present in NetworkACLRuleItemNetworkACLRuleProtocolTCPUDP JSON')
        if (protocol := _dict.get('protocol')) is not None:
            args['protocol'] = protocol
        else:
            raise ValueError('Required property \'protocol\' not present in NetworkACLRuleItemNetworkACLRuleProtocolTCPUDP JSON')
        if (source_port_max := _dict.get('source_port_max')) is not None:
            args['source_port_max'] = source_port_max
        else:
            raise ValueError('Required property \'source_port_max\' not present in NetworkACLRuleItemNetworkACLRuleProtocolTCPUDP JSON')
        if (source_port_min := _dict.get('source_port_min')) is not None:
            args['source_port_min'] = 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 network protocol.
        """

        TCP = 'tcp'
        UDP = 'udp'



class NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolAllPrototype(NetworkACLRulePrototypeNetworkACLContext):
    """
    NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolAllPrototype.

    :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 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 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 network protocol.
    """

    def __init__(
        self,
        action: str,
        destination: str,
        direction: str,
        source: str,
        protocol: str,
        *,
        ip_version: Optional[str] = None,
        name: Optional[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 network protocol.
        :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 := _dict.get('action')) is not None:
            args['action'] = action
        else:
            raise ValueError('Required property \'action\' not present in NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolAllPrototype JSON')
        if (destination := _dict.get('destination')) is not None:
            args['destination'] = destination
        else:
            raise ValueError('Required property \'destination\' not present in NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolAllPrototype JSON')
        if (direction := _dict.get('direction')) is not None:
            args['direction'] = direction
        else:
            raise ValueError('Required property \'direction\' not present in NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolAllPrototype JSON')
        if (ip_version := _dict.get('ip_version')) is not None:
            args['ip_version'] = ip_version
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        if (source := _dict.get('source')) is not None:
            args['source'] = source
        else:
            raise ValueError('Required property \'source\' not present in NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolAllPrototype JSON')
        if (protocol := _dict.get('protocol')) is not None:
            args['protocol'] = 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 network protocol.
        """

        ALL = 'all'



class NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolICMPPrototype(NetworkACLRulePrototypeNetworkACLContext):
    """
    NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolICMPPrototype.

    :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 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 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 code: (optional) The ICMP traffic code to match.
          If specified, `type` must also be specified.  If unspecified, all codes are
          matched.
    :param str protocol: The network protocol.
    :param 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: Optional[str] = None,
        name: Optional[str] = None,
        code: Optional[int] = None,
        type: Optional[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 network protocol.
        :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 := _dict.get('action')) is not None:
            args['action'] = action
        else:
            raise ValueError('Required property \'action\' not present in NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolICMPPrototype JSON')
        if (destination := _dict.get('destination')) is not None:
            args['destination'] = destination
        else:
            raise ValueError('Required property \'destination\' not present in NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolICMPPrototype JSON')
        if (direction := _dict.get('direction')) is not None:
            args['direction'] = direction
        else:
            raise ValueError('Required property \'direction\' not present in NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolICMPPrototype JSON')
        if (ip_version := _dict.get('ip_version')) is not None:
            args['ip_version'] = ip_version
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        if (source := _dict.get('source')) is not None:
            args['source'] = source
        else:
            raise ValueError('Required property \'source\' not present in NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolICMPPrototype JSON')
        if (code := _dict.get('code')) is not None:
            args['code'] = code
        if (protocol := _dict.get('protocol')) is not None:
            args['protocol'] = protocol
        else:
            raise ValueError('Required property \'protocol\' not present in NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolICMPPrototype JSON')
        if (type := _dict.get('type')) is not None:
            args['type'] = 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 network protocol.
        """

        ICMP = 'icmp'



class NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolTCPUDPPrototype(NetworkACLRulePrototypeNetworkACLContext):
    """
    NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolTCPUDPPrototype.

    :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 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 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: (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 protocol: The network protocol.
    :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.
    """

    def __init__(
        self,
        action: str,
        destination: str,
        direction: str,
        source: str,
        protocol: str,
        *,
        ip_version: Optional[str] = None,
        name: Optional[str] = None,
        destination_port_max: Optional[int] = None,
        destination_port_min: Optional[int] = None,
        source_port_max: Optional[int] = None,
        source_port_min: Optional[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 network protocol.
        :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 := _dict.get('action')) is not None:
            args['action'] = action
        else:
            raise ValueError('Required property \'action\' not present in NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolTCPUDPPrototype JSON')
        if (destination := _dict.get('destination')) is not None:
            args['destination'] = destination
        else:
            raise ValueError('Required property \'destination\' not present in NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolTCPUDPPrototype JSON')
        if (direction := _dict.get('direction')) is not None:
            args['direction'] = direction
        else:
            raise ValueError('Required property \'direction\' not present in NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolTCPUDPPrototype JSON')
        if (ip_version := _dict.get('ip_version')) is not None:
            args['ip_version'] = ip_version
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        if (source := _dict.get('source')) is not None:
            args['source'] = source
        else:
            raise ValueError('Required property \'source\' not present in NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolTCPUDPPrototype JSON')
        if (destination_port_max := _dict.get('destination_port_max')) is not None:
            args['destination_port_max'] = destination_port_max
        if (destination_port_min := _dict.get('destination_port_min')) is not None:
            args['destination_port_min'] = destination_port_min
        if (protocol := _dict.get('protocol')) is not None:
            args['protocol'] = protocol
        else:
            raise ValueError('Required property \'protocol\' not present in NetworkACLRulePrototypeNetworkACLContextNetworkACLRuleProtocolTCPUDPPrototype JSON')
        if (source_port_max := _dict.get('source_port_max')) is not None:
            args['source_port_max'] = source_port_max
        if (source_port_min := _dict.get('source_port_min')) is not None:
            args['source_port_min'] = 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 network protocol.
        """

        TCP = 'tcp'
        UDP = 'udp'



class NetworkACLRulePrototypeNetworkACLRuleProtocolAllPrototype(NetworkACLRulePrototype):
    """
    NetworkACLRulePrototypeNetworkACLRuleProtocolAllPrototype.

    :param str action: The action to perform for a packet matching the rule.
    :param NetworkACLRuleBeforePrototype before: (optional)
    :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 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 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 network protocol.
    """

    def __init__(
        self,
        action: str,
        destination: str,
        direction: str,
        source: str,
        protocol: str,
        *,
        before: Optional['NetworkACLRuleBeforePrototype'] = None,
        ip_version: Optional[str] = None,
        name: Optional[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 network protocol.
        :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 := _dict.get('action')) is not None:
            args['action'] = action
        else:
            raise ValueError('Required property \'action\' not present in NetworkACLRulePrototypeNetworkACLRuleProtocolAllPrototype JSON')
        if (before := _dict.get('before')) is not None:
            args['before'] = before
        if (destination := _dict.get('destination')) is not None:
            args['destination'] = destination
        else:
            raise ValueError('Required property \'destination\' not present in NetworkACLRulePrototypeNetworkACLRuleProtocolAllPrototype JSON')
        if (direction := _dict.get('direction')) is not None:
            args['direction'] = direction
        else:
            raise ValueError('Required property \'direction\' not present in NetworkACLRulePrototypeNetworkACLRuleProtocolAllPrototype JSON')
        if (ip_version := _dict.get('ip_version')) is not None:
            args['ip_version'] = ip_version
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        if (source := _dict.get('source')) is not None:
            args['source'] = source
        else:
            raise ValueError('Required property \'source\' not present in NetworkACLRulePrototypeNetworkACLRuleProtocolAllPrototype JSON')
        if (protocol := _dict.get('protocol')) is not None:
            args['protocol'] = 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 network protocol.
        """

        ALL = 'all'



class NetworkACLRulePrototypeNetworkACLRuleProtocolICMPPrototype(NetworkACLRulePrototype):
    """
    NetworkACLRulePrototypeNetworkACLRuleProtocolICMPPrototype.

    :param str action: The action to perform for a packet matching the rule.
    :param NetworkACLRuleBeforePrototype before: (optional)
    :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 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 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 code: (optional) The ICMP traffic code to match.
          If specified, `type` must also be specified.  If unspecified, all codes are
          matched.
    :param str protocol: The network protocol.
    :param 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: Optional['NetworkACLRuleBeforePrototype'] = None,
        ip_version: Optional[str] = None,
        name: Optional[str] = None,
        code: Optional[int] = None,
        type: Optional[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 network protocol.
        :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 := _dict.get('action')) is not None:
            args['action'] = action
        else:
            raise ValueError('Required property \'action\' not present in NetworkACLRulePrototypeNetworkACLRuleProtocolICMPPrototype JSON')
        if (before := _dict.get('before')) is not None:
            args['before'] = before
        if (destination := _dict.get('destination')) is not None:
            args['destination'] = destination
        else:
            raise ValueError('Required property \'destination\' not present in NetworkACLRulePrototypeNetworkACLRuleProtocolICMPPrototype JSON')
        if (direction := _dict.get('direction')) is not None:
            args['direction'] = direction
        else:
            raise ValueError('Required property \'direction\' not present in NetworkACLRulePrototypeNetworkACLRuleProtocolICMPPrototype JSON')
        if (ip_version := _dict.get('ip_version')) is not None:
            args['ip_version'] = ip_version
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        if (source := _dict.get('source')) is not None:
            args['source'] = source
        else:
            raise ValueError('Required property \'source\' not present in NetworkACLRulePrototypeNetworkACLRuleProtocolICMPPrototype JSON')
        if (code := _dict.get('code')) is not None:
            args['code'] = code
        if (protocol := _dict.get('protocol')) is not None:
            args['protocol'] = protocol
        else:
            raise ValueError('Required property \'protocol\' not present in NetworkACLRulePrototypeNetworkACLRuleProtocolICMPPrototype JSON')
        if (type := _dict.get('type')) is not None:
            args['type'] = 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 network protocol.
        """

        ICMP = 'icmp'



class NetworkACLRulePrototypeNetworkACLRuleProtocolTCPUDPPrototype(NetworkACLRulePrototype):
    """
    NetworkACLRulePrototypeNetworkACLRuleProtocolTCPUDPPrototype.

    :param str action: The action to perform for a packet matching the rule.
    :param NetworkACLRuleBeforePrototype before: (optional)
    :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 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 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: (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 protocol: The network protocol.
    :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.
    """

    def __init__(
        self,
        action: str,
        destination: str,
        direction: str,
        source: str,
        protocol: str,
        *,
        before: Optional['NetworkACLRuleBeforePrototype'] = None,
        ip_version: Optional[str] = None,
        name: Optional[str] = None,
        destination_port_max: Optional[int] = None,
        destination_port_min: Optional[int] = None,
        source_port_max: Optional[int] = None,
        source_port_min: Optional[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 network protocol.
        :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 := _dict.get('action')) is not None:
            args['action'] = action
        else:
            raise ValueError('Required property \'action\' not present in NetworkACLRulePrototypeNetworkACLRuleProtocolTCPUDPPrototype JSON')
        if (before := _dict.get('before')) is not None:
            args['before'] = before
        if (destination := _dict.get('destination')) is not None:
            args['destination'] = destination
        else:
            raise ValueError('Required property \'destination\' not present in NetworkACLRulePrototypeNetworkACLRuleProtocolTCPUDPPrototype JSON')
        if (direction := _dict.get('direction')) is not None:
            args['direction'] = direction
        else:
            raise ValueError('Required property \'direction\' not present in NetworkACLRulePrototypeNetworkACLRuleProtocolTCPUDPPrototype JSON')
        if (ip_version := _dict.get('ip_version')) is not None:
            args['ip_version'] = ip_version
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        if (source := _dict.get('source')) is not None:
            args['source'] = source
        else:
            raise ValueError('Required property \'source\' not present in NetworkACLRulePrototypeNetworkACLRuleProtocolTCPUDPPrototype JSON')
        if (destination_port_max := _dict.get('destination_port_max')) is not None:
            args['destination_port_max'] = destination_port_max
        if (destination_port_min := _dict.get('destination_port_min')) is not None:
            args['destination_port_min'] = destination_port_min
        if (protocol := _dict.get('protocol')) is not None:
            args['protocol'] = protocol
        else:
            raise ValueError('Required property \'protocol\' not present in NetworkACLRulePrototypeNetworkACLRuleProtocolTCPUDPPrototype JSON')
        if (source_port_max := _dict.get('source_port_max')) is not None:
            args['source_port_max'] = source_port_max
        if (source_port_min := _dict.get('source_port_min')) is not None:
            args['source_port_min'] = 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 network protocol.
        """

        TCP = 'tcp'
        UDP = 'udp'



class NetworkACLRuleNetworkACLRuleProtocolAll(NetworkACLRule):
    """
    NetworkACLRuleNetworkACLRuleProtocolAll.

    :param str action: The action to perform for a packet matching the rule.
    :param NetworkACLRuleReference before: (optional) The rule that this rule is
          immediately before. If absent, this is the last 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 network protocol.
    """

    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: Optional['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 network protocol.
        :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 := _dict.get('action')) is not None:
            args['action'] = action
        else:
            raise ValueError('Required property \'action\' not present in NetworkACLRuleNetworkACLRuleProtocolAll JSON')
        if (before := _dict.get('before')) is not None:
            args['before'] = NetworkACLRuleReference.from_dict(before)
        if (created_at := _dict.get('created_at')) is not None:
            args['created_at'] = string_to_datetime(created_at)
        else:
            raise ValueError('Required property \'created_at\' not present in NetworkACLRuleNetworkACLRuleProtocolAll JSON')
        if (destination := _dict.get('destination')) is not None:
            args['destination'] = destination
        else:
            raise ValueError('Required property \'destination\' not present in NetworkACLRuleNetworkACLRuleProtocolAll JSON')
        if (direction := _dict.get('direction')) is not None:
            args['direction'] = direction
        else:
            raise ValueError('Required property \'direction\' not present in NetworkACLRuleNetworkACLRuleProtocolAll JSON')
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in NetworkACLRuleNetworkACLRuleProtocolAll JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in NetworkACLRuleNetworkACLRuleProtocolAll JSON')
        if (ip_version := _dict.get('ip_version')) is not None:
            args['ip_version'] = ip_version
        else:
            raise ValueError('Required property \'ip_version\' not present in NetworkACLRuleNetworkACLRuleProtocolAll JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in NetworkACLRuleNetworkACLRuleProtocolAll JSON')
        if (source := _dict.get('source')) is not None:
            args['source'] = source
        else:
            raise ValueError('Required property \'source\' not present in NetworkACLRuleNetworkACLRuleProtocolAll JSON')
        if (protocol := _dict.get('protocol')) is not None:
            args['protocol'] = 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 network protocol.
        """

        ALL = 'all'



class NetworkACLRuleNetworkACLRuleProtocolICMP(NetworkACLRule):
    """
    NetworkACLRuleNetworkACLRuleProtocolICMP.

    :param str action: The action to perform for a packet matching the rule.
    :param NetworkACLRuleReference before: (optional) The rule that this rule is
          immediately before. If absent, this is the last 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 code: (optional) The ICMP traffic code to match.
          If absent, all codes are matched.
    :param str protocol: The network protocol.
    :param 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: Optional['NetworkACLRuleReference'] = None,
        code: Optional[int] = None,
        type: Optional[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 network protocol.
        :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 := _dict.get('action')) is not None:
            args['action'] = action
        else:
            raise ValueError('Required property \'action\' not present in NetworkACLRuleNetworkACLRuleProtocolICMP JSON')
        if (before := _dict.get('before')) is not None:
            args['before'] = NetworkACLRuleReference.from_dict(before)
        if (created_at := _dict.get('created_at')) is not None:
            args['created_at'] = string_to_datetime(created_at)
        else:
            raise ValueError('Required property \'created_at\' not present in NetworkACLRuleNetworkACLRuleProtocolICMP JSON')
        if (destination := _dict.get('destination')) is not None:
            args['destination'] = destination
        else:
            raise ValueError('Required property \'destination\' not present in NetworkACLRuleNetworkACLRuleProtocolICMP JSON')
        if (direction := _dict.get('direction')) is not None:
            args['direction'] = direction
        else:
            raise ValueError('Required property \'direction\' not present in NetworkACLRuleNetworkACLRuleProtocolICMP JSON')
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in NetworkACLRuleNetworkACLRuleProtocolICMP JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in NetworkACLRuleNetworkACLRuleProtocolICMP JSON')
        if (ip_version := _dict.get('ip_version')) is not None:
            args['ip_version'] = ip_version
        else:
            raise ValueError('Required property \'ip_version\' not present in NetworkACLRuleNetworkACLRuleProtocolICMP JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in NetworkACLRuleNetworkACLRuleProtocolICMP JSON')
        if (source := _dict.get('source')) is not None:
            args['source'] = source
        else:
            raise ValueError('Required property \'source\' not present in NetworkACLRuleNetworkACLRuleProtocolICMP JSON')
        if (code := _dict.get('code')) is not None:
            args['code'] = code
        if (protocol := _dict.get('protocol')) is not None:
            args['protocol'] = protocol
        else:
            raise ValueError('Required property \'protocol\' not present in NetworkACLRuleNetworkACLRuleProtocolICMP JSON')
        if (type := _dict.get('type')) is not None:
            args['type'] = 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 network protocol.
        """

        ICMP = 'icmp'



class NetworkACLRuleNetworkACLRuleProtocolTCPUDP(NetworkACLRule):
    """
    NetworkACLRuleNetworkACLRuleProtocolTCPUDP.

    :param str action: The action to perform for a packet matching the rule.
    :param NetworkACLRuleReference before: (optional) The rule that this rule is
          immediately before. If absent, this is the last 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 network protocol.
    :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.
    """

    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: Optional['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 network protocol.
        :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 := _dict.get('action')) is not None:
            args['action'] = action
        else:
            raise ValueError('Required property \'action\' not present in NetworkACLRuleNetworkACLRuleProtocolTCPUDP JSON')
        if (before := _dict.get('before')) is not None:
            args['before'] = NetworkACLRuleReference.from_dict(before)
        if (created_at := _dict.get('created_at')) is not None:
            args['created_at'] = string_to_datetime(created_at)
        else:
            raise ValueError('Required property \'created_at\' not present in NetworkACLRuleNetworkACLRuleProtocolTCPUDP JSON')
        if (destination := _dict.get('destination')) is not None:
            args['destination'] = destination
        else:
            raise ValueError('Required property \'destination\' not present in NetworkACLRuleNetworkACLRuleProtocolTCPUDP JSON')
        if (direction := _dict.get('direction')) is not None:
            args['direction'] = direction
        else:
            raise ValueError('Required property \'direction\' not present in NetworkACLRuleNetworkACLRuleProtocolTCPUDP JSON')
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in NetworkACLRuleNetworkACLRuleProtocolTCPUDP JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in NetworkACLRuleNetworkACLRuleProtocolTCPUDP JSON')
        if (ip_version := _dict.get('ip_version')) is not None:
            args['ip_version'] = ip_version
        else:
            raise ValueError('Required property \'ip_version\' not present in NetworkACLRuleNetworkACLRuleProtocolTCPUDP JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in NetworkACLRuleNetworkACLRuleProtocolTCPUDP JSON')
        if (source := _dict.get('source')) is not None:
            args['source'] = source
        else:
            raise ValueError('Required property \'source\' not present in NetworkACLRuleNetworkACLRuleProtocolTCPUDP JSON')
        if (destination_port_max := _dict.get('destination_port_max')) is not None:
            args['destination_port_max'] = destination_port_max
        else:
            raise ValueError('Required property \'destination_port_max\' not present in NetworkACLRuleNetworkACLRuleProtocolTCPUDP JSON')
        if (destination_port_min := _dict.get('destination_port_min')) is not None:
            args['destination_port_min'] = destination_port_min
        else:
            raise ValueError('Required property \'destination_port_min\' not present in NetworkACLRuleNetworkACLRuleProtocolTCPUDP JSON')
        if (protocol := _dict.get('protocol')) is not None:
            args['protocol'] = protocol
        else:
            raise ValueError('Required property \'protocol\' not present in NetworkACLRuleNetworkACLRuleProtocolTCPUDP JSON')
        if (source_port_max := _dict.get('source_port_max')) is not None:
            args['source_port_max'] = source_port_max
        else:
            raise ValueError('Required property \'source_port_max\' not present in NetworkACLRuleNetworkACLRuleProtocolTCPUDP JSON')
        if (source_port_min := _dict.get('source_port_min')) is not None:
            args['source_port_min'] = 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 network protocol.
        """

        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.

    :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.
    """

    def __init__(
        self,
        *,
        address: Optional[str] = None,
        auto_delete: Optional[bool] = None,
        name: Optional[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 := _dict.get('address')) is not None:
            args['address'] = address
        if (auto_delete := _dict.get('auto_delete')) is not None:
            args['auto_delete'] = auto_delete
        if (name := _dict.get('name')) is not None:
            args['name'] = 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.

    :param 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 := _dict.get('href')) is not None:
            args['href'] = 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.

    :param 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 := _dict.get('name')) is not None:
            args['name'] = 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.

    :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.
    """

    def __init__(
        self,
        *,
        name: Optional[str] = None,
        resource_group: Optional['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 := _dict.get('name')) is not None:
            args['name'] = name
        if (resource_group := _dict.get('resource_group')) is not None:
            args['resource_group'] = 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.

    :param 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 := _dict.get('crn')) is not None:
            args['crn'] = 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.

    :param 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 := _dict.get('href')) is not None:
            args['href'] = 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.

    :param 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 := _dict.get('id')) is not None:
            args['id'] = 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.

    :param 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 := _dict.get('href')) is not None:
            args['href'] = 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.

    :param 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 := _dict.get('name')) is not None:
            args['name'] = 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 ReservationIdentityByCRN(ReservationIdentity):
    """
    ReservationIdentityByCRN.

    :param str crn: The CRN for this reservation.
    """

    def __init__(
        self,
        crn: str,
    ) -> None:
        """
        Initialize a ReservationIdentityByCRN object.

        :param str crn: The CRN for this reservation.
        """
        # pylint: disable=super-init-not-called
        self.crn = crn

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ReservationIdentityByCRN':
        """Initialize a ReservationIdentityByCRN object from a json dictionary."""
        args = {}
        if (crn := _dict.get('crn')) is not None:
            args['crn'] = crn
        else:
            raise ValueError('Required property \'crn\' not present in ReservationIdentityByCRN JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ReservationIdentityByCRN object from 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 ReservationIdentityByCRN object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ReservationIdentityByCRN') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ReservationIdentityByCRN') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class ReservationIdentityByHref(ReservationIdentity):
    """
    ReservationIdentityByHref.

    :param str href: The URL for this reservation.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a ReservationIdentityByHref object.

        :param str href: The URL for this reservation.
        """
        # pylint: disable=super-init-not-called
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ReservationIdentityByHref':
        """Initialize a ReservationIdentityByHref object from a json dictionary."""
        args = {}
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in ReservationIdentityByHref JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ReservationIdentityByHref object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this ReservationIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ReservationIdentityByHref') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ReservationIdentityByHref') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class ReservationIdentityById(ReservationIdentity):
    """
    ReservationIdentityById.

    :param str id: The unique identifier for this reservation.
    """

    def __init__(
        self,
        id: str,
    ) -> None:
        """
        Initialize a ReservationIdentityById object.

        :param str id: The unique identifier for this reservation.
        """
        # pylint: disable=super-init-not-called
        self.id = id

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ReservationIdentityById':
        """Initialize a ReservationIdentityById object from a json dictionary."""
        args = {}
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in ReservationIdentityById JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ReservationIdentityById object from 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 ReservationIdentityById object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ReservationIdentityById') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ReservationIdentityById') -> 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 ReservedIPTargetPrototypeVirtualNetworkInterfaceIdentity(ReservedIPTargetPrototype):
    """
    Identifies a virtual network interface by a unique property.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a ReservedIPTargetPrototypeVirtualNetworkInterfaceIdentity object.

        """
        # pylint: disable=super-init-not-called
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['ReservedIPTargetPrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityById', 'ReservedIPTargetPrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByHref', 'ReservedIPTargetPrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByCRN'])
        )
        raise Exception(msg)


class ReservedIPTargetBareMetalServerNetworkInterfaceReferenceTargetContext(ReservedIPTarget):
    """
    ReservedIPTargetBareMetalServerNetworkInterfaceReferenceTargetContext.

    :param Deleted deleted: (optional) If present, this property indicates the
          referenced resource has been deleted, and provides
          some supplementary information.
    :param str href: The URL for this bare metal server network interface.
          If this bare metal server has network attachments, this network interface is a
          [read-only
          representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
          of its corresponding network attachment.
    :param str id: The unique identifier for this bare metal server network
          interface.
          If this bare metal server has network attachments, this network interface is a
          [read-only
          representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
          of its corresponding network attachment and its attached virtual network
          interface, and the identifier is that of the corresponding network attachment.
    :param str name: The name for this bare metal server network interface.
    :param str resource_type: The resource type.
    """

    def __init__(
        self,
        href: str,
        id: str,
        name: str,
        resource_type: str,
        *,
        deleted: Optional['Deleted'] = None,
    ) -> None:
        """
        Initialize a ReservedIPTargetBareMetalServerNetworkInterfaceReferenceTargetContext object.

        :param str href: The URL for this bare metal server network interface.
               If this bare metal server has network attachments, this network interface
               is a
               [read-only
               representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
               of its corresponding network attachment.
        :param str id: The unique identifier for this bare metal server network
               interface.
               If this bare metal server has network attachments, this network interface
               is a
               [read-only
               representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
               of its corresponding network attachment and its attached virtual network
               interface, and the identifier is that of the corresponding network
               attachment.
        :param str name: The name for this bare metal server network interface.
        :param str resource_type: The resource type.
        :param Deleted 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 := _dict.get('deleted')) is not None:
            args['deleted'] = Deleted.from_dict(deleted)
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in ReservedIPTargetBareMetalServerNetworkInterfaceReferenceTargetContext JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in ReservedIPTargetBareMetalServerNetworkInterfaceReferenceTargetContext JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in ReservedIPTargetBareMetalServerNetworkInterfaceReferenceTargetContext JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = 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.

    :param str crn: The CRN for this endpoint gateway.
    :param Deleted deleted: (optional) If present, this property indicates the
          referenced resource has been deleted, and provides
          some supplementary information.
    :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.
    """

    def __init__(
        self,
        crn: str,
        href: str,
        id: str,
        name: str,
        resource_type: str,
        *,
        deleted: Optional['Deleted'] = 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 Deleted 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 := _dict.get('crn')) is not None:
            args['crn'] = crn
        else:
            raise ValueError('Required property \'crn\' not present in ReservedIPTargetEndpointGatewayReference JSON')
        if (deleted := _dict.get('deleted')) is not None:
            args['deleted'] = Deleted.from_dict(deleted)
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in ReservedIPTargetEndpointGatewayReference JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in ReservedIPTargetEndpointGatewayReference JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in ReservedIPTargetEndpointGatewayReference JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = 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.

    :param str crn: The CRN for the resource.
    :param Deleted deleted: (optional) If present, this property indicates the
          referenced resource has been deleted, and provides
          some supplementary information.
    :param str resource_type: The resource type.
    """

    def __init__(
        self,
        crn: str,
        resource_type: str,
        *,
        deleted: Optional['Deleted'] = None,
    ) -> None:
        """
        Initialize a ReservedIPTargetGenericResourceReference object.

        :param str crn: The CRN for the resource.
        :param str resource_type: The resource type.
        :param Deleted 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 := _dict.get('crn')) is not None:
            args['crn'] = crn
        else:
            raise ValueError('Required property \'crn\' not present in ReservedIPTargetGenericResourceReference JSON')
        if (deleted := _dict.get('deleted')) is not None:
            args['deleted'] = Deleted.from_dict(deleted)
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = 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.

    :param str crn: The CRN for this load balancer.
    :param Deleted deleted: (optional) If present, this property indicates the
          referenced resource has been deleted, and provides
          some supplementary information.
    :param str href: The URL for this load balancer.
    :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.
    """

    def __init__(
        self,
        crn: str,
        href: str,
        id: str,
        name: str,
        resource_type: str,
        *,
        deleted: Optional['Deleted'] = None,
    ) -> None:
        """
        Initialize a ReservedIPTargetLoadBalancerReference object.

        :param str crn: The CRN for this load balancer.
        :param str href: The URL for this load balancer.
        :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 Deleted 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 := _dict.get('crn')) is not None:
            args['crn'] = crn
        else:
            raise ValueError('Required property \'crn\' not present in ReservedIPTargetLoadBalancerReference JSON')
        if (deleted := _dict.get('deleted')) is not None:
            args['deleted'] = Deleted.from_dict(deleted)
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in ReservedIPTargetLoadBalancerReference JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in ReservedIPTargetLoadBalancerReference JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in ReservedIPTargetLoadBalancerReference JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = 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.

    :param Deleted deleted: (optional) If present, this property indicates the
          referenced resource has been deleted, and provides
          some supplementary information.
    :param str href: The URL for this instance network interface.
          If this instance has network attachments, this network interface is a
          [read-only
          representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
          of its corresponding network attachment.
    :param str id: The unique identifier for this instance network interface.
          If this instance has network attachments, this network interface is a
          [read-only
          representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
          of its corresponding network attachment and its attached virtual network
          interface, and the identifier is that of the corresponding network attachment.
    :param str name: The name for this instance network interface.
    :param str resource_type: The resource type.
    """

    def __init__(
        self,
        href: str,
        id: str,
        name: str,
        resource_type: str,
        *,
        deleted: Optional['Deleted'] = None,
    ) -> None:
        """
        Initialize a ReservedIPTargetNetworkInterfaceReferenceTargetContext object.

        :param str href: The URL for this instance network interface.
               If this instance has network attachments, this network interface is a
               [read-only
               representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
               of its corresponding network attachment.
        :param str id: The unique identifier for this instance network interface.
               If this instance has network attachments, this network interface is a
               [read-only
               representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
               of its corresponding network attachment and its attached virtual network
               interface, and the identifier is that of the corresponding network
               attachment.
        :param str name: The name for this instance network interface.
        :param str resource_type: The resource type.
        :param Deleted 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 := _dict.get('deleted')) is not None:
            args['deleted'] = Deleted.from_dict(deleted)
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in ReservedIPTargetNetworkInterfaceReferenceTargetContext JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in ReservedIPTargetNetworkInterfaceReferenceTargetContext JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in ReservedIPTargetNetworkInterfaceReferenceTargetContext JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = 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.

    :param str crn: The CRN for this VPN gateway.
    :param Deleted deleted: (optional) If present, this property indicates the
          referenced resource has been deleted, and provides
          some supplementary information.
    :param str href: The URL for this VPN gateway.
    :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.
    """

    def __init__(
        self,
        crn: str,
        href: str,
        id: str,
        name: str,
        resource_type: str,
        *,
        deleted: Optional['Deleted'] = None,
    ) -> None:
        """
        Initialize a ReservedIPTargetVPNGatewayReference object.

        :param str crn: The CRN for this VPN gateway.
        :param str href: The URL for this VPN gateway.
        :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 Deleted 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 := _dict.get('crn')) is not None:
            args['crn'] = crn
        else:
            raise ValueError('Required property \'crn\' not present in ReservedIPTargetVPNGatewayReference JSON')
        if (deleted := _dict.get('deleted')) is not None:
            args['deleted'] = Deleted.from_dict(deleted)
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in ReservedIPTargetVPNGatewayReference JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in ReservedIPTargetVPNGatewayReference JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in ReservedIPTargetVPNGatewayReference JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = 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.

    :param str crn: The CRN for this VPN server.
    :param Deleted deleted: (optional) If present, this property indicates the
          referenced resource has been deleted, and provides
          some supplementary information.
    :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.
    """

    def __init__(
        self,
        crn: str,
        href: str,
        id: str,
        name: str,
        resource_type: str,
        *,
        deleted: Optional['Deleted'] = 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 Deleted 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 := _dict.get('crn')) is not None:
            args['crn'] = crn
        else:
            raise ValueError('Required property \'crn\' not present in ReservedIPTargetVPNServerReference JSON')
        if (deleted := _dict.get('deleted')) is not None:
            args['deleted'] = Deleted.from_dict(deleted)
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in ReservedIPTargetVPNServerReference JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in ReservedIPTargetVPNServerReference JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in ReservedIPTargetVPNServerReference JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = 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.

    :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.
    """

    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 := _dict.get('crn')) is not None:
            args['crn'] = crn
        else:
            raise ValueError('Required property \'crn\' not present in ReservedIPTargetVirtualNetworkInterfaceReferenceReservedIPTargetContext JSON')
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in ReservedIPTargetVirtualNetworkInterfaceReferenceReservedIPTargetContext JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in ReservedIPTargetVirtualNetworkInterfaceReferenceReservedIPTargetContext JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in ReservedIPTargetVirtualNetworkInterfaceReferenceReservedIPTargetContext JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = 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.

    :param 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 := _dict.get('id')) is not None:
            args['id'] = 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.

    :param str crn: The CRN for this VPN gateway.
    :param Deleted deleted: (optional) If present, this property indicates the
          referenced resource has been deleted, and provides
          some supplementary information.
    :param str href: The URL for this VPN gateway.
    :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.
    """

    def __init__(
        self,
        crn: str,
        href: str,
        id: str,
        name: str,
        resource_type: str,
        *,
        deleted: Optional['Deleted'] = None,
    ) -> None:
        """
        Initialize a RouteCreatorVPNGatewayReference object.

        :param str crn: The CRN for this VPN gateway.
        :param str href: The URL for this VPN gateway.
        :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 Deleted 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 := _dict.get('crn')) is not None:
            args['crn'] = crn
        else:
            raise ValueError('Required property \'crn\' not present in RouteCreatorVPNGatewayReference JSON')
        if (deleted := _dict.get('deleted')) is not None:
            args['deleted'] = Deleted.from_dict(deleted)
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in RouteCreatorVPNGatewayReference JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in RouteCreatorVPNGatewayReference JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in RouteCreatorVPNGatewayReference JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = 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.

    :param str crn: The CRN for this VPN server.
    :param Deleted deleted: (optional) If present, this property indicates the
          referenced resource has been deleted, and provides
          some supplementary information.
    :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.
    """

    def __init__(
        self,
        crn: str,
        href: str,
        id: str,
        name: str,
        resource_type: str,
        *,
        deleted: Optional['Deleted'] = 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 Deleted 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 := _dict.get('crn')) is not None:
            args['crn'] = crn
        else:
            raise ValueError('Required property \'crn\' not present in RouteCreatorVPNServerReference JSON')
        if (deleted := _dict.get('deleted')) is not None:
            args['deleted'] = Deleted.from_dict(deleted)
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in RouteCreatorVPNServerReference JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in RouteCreatorVPNServerReference JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in RouteCreatorVPNServerReference JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = 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.

    :param str address: The IP address.
          This property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) to support
          IPv6 addresses in the future.
    """

    def __init__(
        self,
        address: str,
    ) -> None:
        """
        Initialize a RouteNextHopIP object.

        :param str address: The IP address.
               This property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) to
               support IPv6 addresses in the future.
        """
        # 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 := _dict.get('address')) is not None:
            args['address'] = 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 RouteNextHopPrototypeRouteNextHopIP(RouteNextHopPrototype):
    """
    RouteNextHopPrototypeRouteNextHopIP.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a RouteNextHopPrototypeRouteNextHopIP object.

        """
        # pylint: disable=super-init-not-called
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['RouteNextHopPrototypeRouteNextHopIPRouteNextHopIPSentinelIP', 'RouteNextHopPrototypeRouteNextHopIPRouteNextHopIPUnicastIP'])
        )
        raise Exception(msg)


class RouteNextHopPrototypeVPNGatewayConnectionIdentity(RouteNextHopPrototype):
    """
    Identifies a VPN gateway connection by a unique property.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a RouteNextHopPrototypeVPNGatewayConnectionIdentity object.

        """
        # pylint: disable=super-init-not-called
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['RouteNextHopPrototypeVPNGatewayConnectionIdentityVPNGatewayConnectionIdentityById', 'RouteNextHopPrototypeVPNGatewayConnectionIdentityVPNGatewayConnectionIdentityByHref'])
        )
        raise Exception(msg)


class RouteNextHopVPNGatewayConnectionReference(RouteNextHop):
    """
    RouteNextHopVPNGatewayConnectionReference.

    :param Deleted deleted: (optional) If present, this property indicates the
          referenced resource has been deleted, and provides
          some supplementary information.
    :param str href: The URL for this VPN gateway connection.
    :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.
    """

    def __init__(
        self,
        href: str,
        id: str,
        name: str,
        resource_type: str,
        *,
        deleted: Optional['Deleted'] = None,
    ) -> None:
        """
        Initialize a RouteNextHopVPNGatewayConnectionReference object.

        :param str href: The URL for this VPN gateway connection.
        :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 Deleted 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 := _dict.get('deleted')) is not None:
            args['deleted'] = Deleted.from_dict(deleted)
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in RouteNextHopVPNGatewayConnectionReference JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in RouteNextHopVPNGatewayConnectionReference JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in RouteNextHopVPNGatewayConnectionReference JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = 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 RoutingTableIdentityByCRN(RoutingTableIdentity):
    """
    RoutingTableIdentityByCRN.

    :param str crn: The CRN for this VPC routing table.
    """

    def __init__(
        self,
        crn: str,
    ) -> None:
        """
        Initialize a RoutingTableIdentityByCRN object.

        :param str crn: The CRN for this VPC routing table.
        """
        # pylint: disable=super-init-not-called
        self.crn = crn

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'RoutingTableIdentityByCRN':
        """Initialize a RoutingTableIdentityByCRN object from a json dictionary."""
        args = {}
        if (crn := _dict.get('crn')) is not None:
            args['crn'] = crn
        else:
            raise ValueError('Required property \'crn\' not present in RoutingTableIdentityByCRN JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a RoutingTableIdentityByCRN object from 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 RoutingTableIdentityByCRN object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'RoutingTableIdentityByCRN') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'RoutingTableIdentityByCRN') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class RoutingTableIdentityByHref(RoutingTableIdentity):
    """
    RoutingTableIdentityByHref.

    :param 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 := _dict.get('href')) is not None:
            args['href'] = 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.

    :param 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 := _dict.get('id')) is not None:
            args['id'] = 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.

    :param str crn: The CRN for this security group.
    """

    def __init__(
        self,
        crn: str,
    ) -> None:
        """
        Initialize a SecurityGroupIdentityByCRN object.

        :param str crn: The CRN for this security group.
        """
        # 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 := _dict.get('crn')) is not None:
            args['crn'] = 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.

    :param str href: The URL for this security group.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a SecurityGroupIdentityByHref object.

        :param str href: The URL for this security group.
        """
        # 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 := _dict.get('href')) is not None:
            args['href'] = 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.

    :param 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 := _dict.get('id')) is not None:
            args['id'] = 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 SecurityGroupRuleLocalPatchCIDR(SecurityGroupRuleLocalPatch):
    """
    SecurityGroupRuleLocalPatchCIDR.

    :param str cidr_block: The CIDR block.
          This property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) to support
          IPv6 address blocks in the future.
    """

    def __init__(
        self,
        cidr_block: str,
    ) -> None:
        """
        Initialize a SecurityGroupRuleLocalPatchCIDR object.

        :param str cidr_block: The CIDR block.
               This property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) to
               support IPv6 address blocks in the future.
        """
        # pylint: disable=super-init-not-called
        self.cidr_block = cidr_block

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'SecurityGroupRuleLocalPatchCIDR':
        """Initialize a SecurityGroupRuleLocalPatchCIDR object from a json dictionary."""
        args = {}
        if (cidr_block := _dict.get('cidr_block')) is not None:
            args['cidr_block'] = cidr_block
        else:
            raise ValueError('Required property \'cidr_block\' not present in SecurityGroupRuleLocalPatchCIDR JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SecurityGroupRuleLocalPatchCIDR object from 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 SecurityGroupRuleLocalPatchCIDR object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'SecurityGroupRuleLocalPatchCIDR') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'SecurityGroupRuleLocalPatchCIDR') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class SecurityGroupRuleLocalPatchIP(SecurityGroupRuleLocalPatch):
    """
    SecurityGroupRuleLocalPatchIP.

    :param str address: The IP address.
          This property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) to support
          IPv6 addresses in the future.
    """

    def __init__(
        self,
        address: str,
    ) -> None:
        """
        Initialize a SecurityGroupRuleLocalPatchIP object.

        :param str address: The IP address.
               This property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) to
               support IPv6 addresses in the future.
        """
        # pylint: disable=super-init-not-called
        self.address = address

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'SecurityGroupRuleLocalPatchIP':
        """Initialize a SecurityGroupRuleLocalPatchIP object from a json dictionary."""
        args = {}
        if (address := _dict.get('address')) is not None:
            args['address'] = address
        else:
            raise ValueError('Required property \'address\' not present in SecurityGroupRuleLocalPatchIP JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SecurityGroupRuleLocalPatchIP object from 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 SecurityGroupRuleLocalPatchIP object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'SecurityGroupRuleLocalPatchIP') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'SecurityGroupRuleLocalPatchIP') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class SecurityGroupRuleLocalPrototypeCIDR(SecurityGroupRuleLocalPrototype):
    """
    SecurityGroupRuleLocalPrototypeCIDR.

    :param str cidr_block: The CIDR block.
          This property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) to support
          IPv6 address blocks in the future.
    """

    def __init__(
        self,
        cidr_block: str,
    ) -> None:
        """
        Initialize a SecurityGroupRuleLocalPrototypeCIDR object.

        :param str cidr_block: The CIDR block.
               This property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) to
               support IPv6 address blocks in the future.
        """
        # pylint: disable=super-init-not-called
        self.cidr_block = cidr_block

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'SecurityGroupRuleLocalPrototypeCIDR':
        """Initialize a SecurityGroupRuleLocalPrototypeCIDR object from a json dictionary."""
        args = {}
        if (cidr_block := _dict.get('cidr_block')) is not None:
            args['cidr_block'] = cidr_block
        else:
            raise ValueError('Required property \'cidr_block\' not present in SecurityGroupRuleLocalPrototypeCIDR JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SecurityGroupRuleLocalPrototypeCIDR object from 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 SecurityGroupRuleLocalPrototypeCIDR object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'SecurityGroupRuleLocalPrototypeCIDR') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'SecurityGroupRuleLocalPrototypeCIDR') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class SecurityGroupRuleLocalPrototypeIP(SecurityGroupRuleLocalPrototype):
    """
    SecurityGroupRuleLocalPrototypeIP.

    :param str address: The IP address.
          This property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) to support
          IPv6 addresses in the future.
    """

    def __init__(
        self,
        address: str,
    ) -> None:
        """
        Initialize a SecurityGroupRuleLocalPrototypeIP object.

        :param str address: The IP address.
               This property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) to
               support IPv6 addresses in the future.
        """
        # pylint: disable=super-init-not-called
        self.address = address

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'SecurityGroupRuleLocalPrototypeIP':
        """Initialize a SecurityGroupRuleLocalPrototypeIP object from a json dictionary."""
        args = {}
        if (address := _dict.get('address')) is not None:
            args['address'] = address
        else:
            raise ValueError('Required property \'address\' not present in SecurityGroupRuleLocalPrototypeIP JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SecurityGroupRuleLocalPrototypeIP object from 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 SecurityGroupRuleLocalPrototypeIP object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'SecurityGroupRuleLocalPrototypeIP') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'SecurityGroupRuleLocalPrototypeIP') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class SecurityGroupRuleLocalCIDR(SecurityGroupRuleLocal):
    """
    SecurityGroupRuleLocalCIDR.

    :param str cidr_block: The CIDR block.
          This property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) to support
          IPv6 address blocks in the future.
    """

    def __init__(
        self,
        cidr_block: str,
    ) -> None:
        """
        Initialize a SecurityGroupRuleLocalCIDR object.

        :param str cidr_block: The CIDR block.
               This property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) to
               support IPv6 address blocks in the future.
        """
        # pylint: disable=super-init-not-called
        self.cidr_block = cidr_block

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'SecurityGroupRuleLocalCIDR':
        """Initialize a SecurityGroupRuleLocalCIDR object from a json dictionary."""
        args = {}
        if (cidr_block := _dict.get('cidr_block')) is not None:
            args['cidr_block'] = cidr_block
        else:
            raise ValueError('Required property \'cidr_block\' not present in SecurityGroupRuleLocalCIDR JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SecurityGroupRuleLocalCIDR object from 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 SecurityGroupRuleLocalCIDR object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'SecurityGroupRuleLocalCIDR') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'SecurityGroupRuleLocalCIDR') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class SecurityGroupRuleLocalIP(SecurityGroupRuleLocal):
    """
    SecurityGroupRuleLocalIP.

    :param str address: The IP address.
          This property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) to support
          IPv6 addresses in the future.
    """

    def __init__(
        self,
        address: str,
    ) -> None:
        """
        Initialize a SecurityGroupRuleLocalIP object.

        :param str address: The IP address.
               This property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) to
               support IPv6 addresses in the future.
        """
        # pylint: disable=super-init-not-called
        self.address = address

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'SecurityGroupRuleLocalIP':
        """Initialize a SecurityGroupRuleLocalIP object from a json dictionary."""
        args = {}
        if (address := _dict.get('address')) is not None:
            args['address'] = address
        else:
            raise ValueError('Required property \'address\' not present in SecurityGroupRuleLocalIP JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SecurityGroupRuleLocalIP object from 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 SecurityGroupRuleLocalIP object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'SecurityGroupRuleLocalIP') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'SecurityGroupRuleLocalIP') -> 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.

    :param str direction: The direction of traffic to allow.
    :param str ip_version: (optional) The IP version to allow. The format of
          `local.address`, `remote.address`,
          `local.cidr_block` or `remote.cidr_block` must match this property, if they are
          used.
          If `remote` references a security group, then this rule only applies to IP
          addresses in that group matching this IP version.
    :param SecurityGroupRuleLocalPrototype local: (optional) The local IP address or
          range of local IP addresses to which this rule will allow inbound
          traffic (or from which, for outbound traffic)
          If unspecified, a CIDR block of `0.0.0.0/0` will be used to allow traffic to all
          local IP
          addresses (or from all local IP addresses, for outbound rules).
    :param str protocol: The network protocol.
    :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).
    """

    def __init__(
        self,
        direction: str,
        protocol: str,
        *,
        ip_version: Optional[str] = None,
        local: Optional['SecurityGroupRuleLocalPrototype'] = None,
        remote: Optional['SecurityGroupRuleRemotePrototype'] = None,
    ) -> None:
        """
        Initialize a SecurityGroupRulePrototypeSecurityGroupRuleProtocolAll object.

        :param str direction: The direction of traffic to allow.
        :param str protocol: The network protocol.
        :param str ip_version: (optional) The IP version to allow. The format of
               `local.address`, `remote.address`,
               `local.cidr_block` or `remote.cidr_block` must match this property, if they
               are used.
               If `remote` references a security group, then this rule only applies to IP
               addresses in that group matching this IP version.
        :param SecurityGroupRuleLocalPrototype local: (optional) The local IP
               address or range of local IP addresses to which this rule will allow
               inbound
               traffic (or from which, for outbound traffic)
               If unspecified, a CIDR block of `0.0.0.0/0` will be used to allow traffic
               to all local IP
               addresses (or from all local IP addresses, for outbound rules).
        :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.local = local
        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 := _dict.get('direction')) is not None:
            args['direction'] = direction
        else:
            raise ValueError('Required property \'direction\' not present in SecurityGroupRulePrototypeSecurityGroupRuleProtocolAll JSON')
        if (ip_version := _dict.get('ip_version')) is not None:
            args['ip_version'] = ip_version
        if (local := _dict.get('local')) is not None:
            args['local'] = local
        if (protocol := _dict.get('protocol')) is not None:
            args['protocol'] = protocol
        else:
            raise ValueError('Required property \'protocol\' not present in SecurityGroupRulePrototypeSecurityGroupRuleProtocolAll JSON')
        if (remote := _dict.get('remote')) is not None:
            args['remote'] = 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, 'local') and self.local is not None:
            if isinstance(self.local, dict):
                _dict['local'] = self.local
            else:
                _dict['local'] = self.local.to_dict()
        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 allow.
        """

        INBOUND = 'inbound'
        OUTBOUND = 'outbound'


    class IpVersionEnum(str, Enum):
        """
        The IP version to allow. The format of `local.address`, `remote.address`,
        `local.cidr_block` or `remote.cidr_block` must match this property, if they are
        used.
        If `remote` references a security group, then this rule only applies to IP
        addresses in that group matching this IP version.
        """

        IPV4 = 'ipv4'


    class ProtocolEnum(str, Enum):
        """
        The network protocol.
        """

        ALL = 'all'



class SecurityGroupRulePrototypeSecurityGroupRuleProtocolICMP(SecurityGroupRulePrototype):
    """
    A rule specifying the ICMP traffic to allow.

    :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 direction: The direction of traffic to allow.
    :param str ip_version: (optional) The IP version to allow. The format of
          `local.address`, `remote.address`,
          `local.cidr_block` or `remote.cidr_block` must match this property, if they are
          used.
          If `remote` references a security group, then this rule only applies to IP
          addresses in that group matching this IP version.
    :param SecurityGroupRuleLocalPrototype local: (optional) The local IP address or
          range of local IP addresses to which this rule will allow inbound
          traffic (or from which, for outbound traffic)
          If unspecified, a CIDR block of `0.0.0.0/0` will be used to allow traffic to all
          local IP
          addresses (or from all local IP addresses, for outbound rules).
    :param str protocol: The network protocol.
    :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.
    """

    def __init__(
        self,
        direction: str,
        protocol: str,
        *,
        code: Optional[int] = None,
        ip_version: Optional[str] = None,
        local: Optional['SecurityGroupRuleLocalPrototype'] = None,
        remote: Optional['SecurityGroupRuleRemotePrototype'] = None,
        type: Optional[int] = None,
    ) -> None:
        """
        Initialize a SecurityGroupRulePrototypeSecurityGroupRuleProtocolICMP object.

        :param str direction: The direction of traffic to allow.
        :param str protocol: The network protocol.
        :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 allow. The format of
               `local.address`, `remote.address`,
               `local.cidr_block` or `remote.cidr_block` must match this property, if they
               are used.
               If `remote` references a security group, then this rule only applies to IP
               addresses in that group matching this IP version.
        :param SecurityGroupRuleLocalPrototype local: (optional) The local IP
               address or range of local IP addresses to which this rule will allow
               inbound
               traffic (or from which, for outbound traffic)
               If unspecified, a CIDR block of `0.0.0.0/0` will be used to allow traffic
               to all local IP
               addresses (or from all local IP addresses, for outbound rules).
        :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.local = local
        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 := _dict.get('code')) is not None:
            args['code'] = code
        if (direction := _dict.get('direction')) is not None:
            args['direction'] = direction
        else:
            raise ValueError('Required property \'direction\' not present in SecurityGroupRulePrototypeSecurityGroupRuleProtocolICMP JSON')
        if (ip_version := _dict.get('ip_version')) is not None:
            args['ip_version'] = ip_version
        if (local := _dict.get('local')) is not None:
            args['local'] = local
        if (protocol := _dict.get('protocol')) is not None:
            args['protocol'] = protocol
        else:
            raise ValueError('Required property \'protocol\' not present in SecurityGroupRulePrototypeSecurityGroupRuleProtocolICMP JSON')
        if (remote := _dict.get('remote')) is not None:
            args['remote'] = remote
        if (type := _dict.get('type')) is not None:
            args['type'] = 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, 'local') and self.local is not None:
            if isinstance(self.local, dict):
                _dict['local'] = self.local
            else:
                _dict['local'] = self.local.to_dict()
        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 allow.
        """

        INBOUND = 'inbound'
        OUTBOUND = 'outbound'


    class IpVersionEnum(str, Enum):
        """
        The IP version to allow. The format of `local.address`, `remote.address`,
        `local.cidr_block` or `remote.cidr_block` must match this property, if they are
        used.
        If `remote` references a security group, then this rule only applies to IP
        addresses in that group matching this IP version.
        """

        IPV4 = 'ipv4'


    class ProtocolEnum(str, Enum):
        """
        The network protocol.
        """

        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.

    :param str direction: The direction of traffic to allow.
    :param str ip_version: (optional) The IP version to allow. The format of
          `local.address`, `remote.address`,
          `local.cidr_block` or `remote.cidr_block` must match this property, if they are
          used.
          If `remote` references a security group, then this rule only applies to IP
          addresses in that group matching this IP version.
    :param SecurityGroupRuleLocalPrototype local: (optional) The local IP address or
          range of local IP addresses to which this rule will allow inbound
          traffic (or from which, for outbound traffic)
          If unspecified, a CIDR block of `0.0.0.0/0` will be used to allow traffic to all
          local IP
          addresses (or from all local IP addresses, for outbound rules).
    :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 str protocol: The network protocol.
    :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).
    """

    def __init__(
        self,
        direction: str,
        protocol: str,
        *,
        ip_version: Optional[str] = None,
        local: Optional['SecurityGroupRuleLocalPrototype'] = None,
        port_max: Optional[int] = None,
        port_min: Optional[int] = None,
        remote: Optional['SecurityGroupRuleRemotePrototype'] = None,
    ) -> None:
        """
        Initialize a SecurityGroupRulePrototypeSecurityGroupRuleProtocolTCPUDP object.

        :param str direction: The direction of traffic to allow.
        :param str protocol: The network protocol.
        :param str ip_version: (optional) The IP version to allow. The format of
               `local.address`, `remote.address`,
               `local.cidr_block` or `remote.cidr_block` must match this property, if they
               are used.
               If `remote` references a security group, then this rule only applies to IP
               addresses in that group matching this IP version.
        :param SecurityGroupRuleLocalPrototype local: (optional) The local IP
               address or range of local IP addresses to which this rule will allow
               inbound
               traffic (or from which, for outbound traffic)
               If unspecified, a CIDR block of `0.0.0.0/0` will be used to allow traffic
               to all local IP
               addresses (or from all local IP addresses, for outbound rules).
        :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.local = local
        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 := _dict.get('direction')) is not None:
            args['direction'] = direction
        else:
            raise ValueError('Required property \'direction\' not present in SecurityGroupRulePrototypeSecurityGroupRuleProtocolTCPUDP JSON')
        if (ip_version := _dict.get('ip_version')) is not None:
            args['ip_version'] = ip_version
        if (local := _dict.get('local')) is not None:
            args['local'] = local
        if (port_max := _dict.get('port_max')) is not None:
            args['port_max'] = port_max
        if (port_min := _dict.get('port_min')) is not None:
            args['port_min'] = port_min
        if (protocol := _dict.get('protocol')) is not None:
            args['protocol'] = protocol
        else:
            raise ValueError('Required property \'protocol\' not present in SecurityGroupRulePrototypeSecurityGroupRuleProtocolTCPUDP JSON')
        if (remote := _dict.get('remote')) is not None:
            args['remote'] = 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, 'local') and self.local is not None:
            if isinstance(self.local, dict):
                _dict['local'] = self.local
            else:
                _dict['local'] = self.local.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
        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 allow.
        """

        INBOUND = 'inbound'
        OUTBOUND = 'outbound'


    class IpVersionEnum(str, Enum):
        """
        The IP version to allow. The format of `local.address`, `remote.address`,
        `local.cidr_block` or `remote.cidr_block` must match this property, if they are
        used.
        If `remote` references a security group, then this rule only applies to IP
        addresses in that group matching this IP version.
        """

        IPV4 = 'ipv4'


    class ProtocolEnum(str, Enum):
        """
        The network protocol.
        """

        TCP = 'tcp'
        UDP = 'udp'



class SecurityGroupRuleRemotePatchCIDR(SecurityGroupRuleRemotePatch):
    """
    SecurityGroupRuleRemotePatchCIDR.

    :param str cidr_block: The CIDR block.
          This property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) to support
          IPv6 address blocks in the future.
    """

    def __init__(
        self,
        cidr_block: str,
    ) -> None:
        """
        Initialize a SecurityGroupRuleRemotePatchCIDR object.

        :param str cidr_block: The CIDR block.
               This property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) to
               support IPv6 address blocks in the future.
        """
        # 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 := _dict.get('cidr_block')) is not None:
            args['cidr_block'] = 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.

    :param str address: The IP address.
          This property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) to support
          IPv6 addresses in the future.
    """

    def __init__(
        self,
        address: str,
    ) -> None:
        """
        Initialize a SecurityGroupRuleRemotePatchIP object.

        :param str address: The IP address.
               This property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) to
               support IPv6 addresses in the future.
        """
        # 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 := _dict.get('address')) is not None:
            args['address'] = 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.

    :param str cidr_block: The CIDR block.
          This property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) to support
          IPv6 address blocks in the future.
    """

    def __init__(
        self,
        cidr_block: str,
    ) -> None:
        """
        Initialize a SecurityGroupRuleRemotePrototypeCIDR object.

        :param str cidr_block: The CIDR block.
               This property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) to
               support IPv6 address blocks in the future.
        """
        # 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 := _dict.get('cidr_block')) is not None:
            args['cidr_block'] = 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.

    :param str address: The IP address.
          This property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) to support
          IPv6 addresses in the future.
    """

    def __init__(
        self,
        address: str,
    ) -> None:
        """
        Initialize a SecurityGroupRuleRemotePrototypeIP object.

        :param str address: The IP address.
               This property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) to
               support IPv6 addresses in the future.
        """
        # 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 := _dict.get('address')) is not None:
            args['address'] = 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.

    :param str cidr_block: The CIDR block.
          This property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) to support
          IPv6 address blocks in the future.
    """

    def __init__(
        self,
        cidr_block: str,
    ) -> None:
        """
        Initialize a SecurityGroupRuleRemoteCIDR object.

        :param str cidr_block: The CIDR block.
               This property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) to
               support IPv6 address blocks in the future.
        """
        # 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 := _dict.get('cidr_block')) is not None:
            args['cidr_block'] = 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.

    :param str address: The IP address.
          This property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) to support
          IPv6 addresses in the future.
    """

    def __init__(
        self,
        address: str,
    ) -> None:
        """
        Initialize a SecurityGroupRuleRemoteIP object.

        :param str address: The IP address.
               This property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) to
               support IPv6 addresses in the future.
        """
        # 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 := _dict.get('address')) is not None:
            args['address'] = 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.

    :param str crn: The CRN for this security group.
    :param Deleted deleted: (optional) If present, this property indicates the
          referenced resource has been deleted, and provides
          some supplementary information.
    :param str href: The URL for this security group.
    :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.
    """

    def __init__(
        self,
        crn: str,
        href: str,
        id: str,
        name: str,
        *,
        deleted: Optional['Deleted'] = None,
    ) -> None:
        """
        Initialize a SecurityGroupRuleRemoteSecurityGroupReference object.

        :param str crn: The CRN for this security group.
        :param str href: The URL for this security group.
        :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 Deleted 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 := _dict.get('crn')) is not None:
            args['crn'] = crn
        else:
            raise ValueError('Required property \'crn\' not present in SecurityGroupRuleRemoteSecurityGroupReference JSON')
        if (deleted := _dict.get('deleted')) is not None:
            args['deleted'] = Deleted.from_dict(deleted)
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in SecurityGroupRuleRemoteSecurityGroupReference JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in SecurityGroupRuleRemoteSecurityGroupReference JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = 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.

    :param str direction: The direction of traffic to allow.
    :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 allow. The format of `local.address`,
          `remote.address`,
          `local.cidr_block` or `remote.cidr_block` must match this property, if they are
          used.
          If `remote` references a security group, then this rule only applies to IP
          addresses in that group matching this IP version.
    :param SecurityGroupRuleLocal local:
    :param SecurityGroupRuleRemote remote:
    :param str protocol: The network protocol.
    """

    def __init__(
        self,
        direction: str,
        href: str,
        id: str,
        ip_version: str,
        local: 'SecurityGroupRuleLocal',
        remote: 'SecurityGroupRuleRemote',
        protocol: str,
    ) -> None:
        """
        Initialize a SecurityGroupRuleSecurityGroupRuleProtocolAll object.

        :param str direction: The direction of traffic to allow.
        :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 allow. The format of
               `local.address`, `remote.address`,
               `local.cidr_block` or `remote.cidr_block` must match this property, if they
               are used.
               If `remote` references a security group, then this rule only applies to IP
               addresses in that group matching this IP version.
        :param SecurityGroupRuleLocal local:
        :param SecurityGroupRuleRemote remote:
        :param str protocol: The network protocol.
        """
        # pylint: disable=super-init-not-called
        self.direction = direction
        self.href = href
        self.id = id
        self.ip_version = ip_version
        self.local = local
        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 := _dict.get('direction')) is not None:
            args['direction'] = direction
        else:
            raise ValueError('Required property \'direction\' not present in SecurityGroupRuleSecurityGroupRuleProtocolAll JSON')
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in SecurityGroupRuleSecurityGroupRuleProtocolAll JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in SecurityGroupRuleSecurityGroupRuleProtocolAll JSON')
        if (ip_version := _dict.get('ip_version')) is not None:
            args['ip_version'] = ip_version
        else:
            raise ValueError('Required property \'ip_version\' not present in SecurityGroupRuleSecurityGroupRuleProtocolAll JSON')
        if (local := _dict.get('local')) is not None:
            args['local'] = local
        else:
            raise ValueError('Required property \'local\' not present in SecurityGroupRuleSecurityGroupRuleProtocolAll JSON')
        if (remote := _dict.get('remote')) is not None:
            args['remote'] = remote
        else:
            raise ValueError('Required property \'remote\' not present in SecurityGroupRuleSecurityGroupRuleProtocolAll JSON')
        if (protocol := _dict.get('protocol')) is not None:
            args['protocol'] = 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, 'local') and self.local is not None:
            if isinstance(self.local, dict):
                _dict['local'] = self.local
            else:
                _dict['local'] = self.local.to_dict()
        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 allow.
        """

        INBOUND = 'inbound'
        OUTBOUND = 'outbound'


    class IpVersionEnum(str, Enum):
        """
        The IP version to allow. The format of `local.address`, `remote.address`,
        `local.cidr_block` or `remote.cidr_block` must match this property, if they are
        used.
        If `remote` references a security group, then this rule only applies to IP
        addresses in that group matching this IP version.
        """

        IPV4 = 'ipv4'


    class ProtocolEnum(str, Enum):
        """
        The network protocol.
        """

        ALL = 'all'



class SecurityGroupRuleSecurityGroupRuleProtocolICMP(SecurityGroupRule):
    """
    A rule specifying the ICMP traffic to allow.

    :param str direction: The direction of traffic to allow.
    :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 allow. The format of `local.address`,
          `remote.address`,
          `local.cidr_block` or `remote.cidr_block` must match this property, if they are
          used.
          If `remote` references a security group, then this rule only applies to IP
          addresses in that group matching this IP version.
    :param SecurityGroupRuleLocal local:
    :param SecurityGroupRuleRemote remote:
    :param int code: (optional) The ICMP traffic code to allow. If absent, all codes
          are allowed.
    :param str protocol: The network protocol.
    :param 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,
        local: 'SecurityGroupRuleLocal',
        remote: 'SecurityGroupRuleRemote',
        protocol: str,
        *,
        code: Optional[int] = None,
        type: Optional[int] = None,
    ) -> None:
        """
        Initialize a SecurityGroupRuleSecurityGroupRuleProtocolICMP object.

        :param str direction: The direction of traffic to allow.
        :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 allow. The format of
               `local.address`, `remote.address`,
               `local.cidr_block` or `remote.cidr_block` must match this property, if they
               are used.
               If `remote` references a security group, then this rule only applies to IP
               addresses in that group matching this IP version.
        :param SecurityGroupRuleLocal local:
        :param SecurityGroupRuleRemote remote:
        :param str protocol: The network protocol.
        :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.local = local
        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 := _dict.get('direction')) is not None:
            args['direction'] = direction
        else:
            raise ValueError('Required property \'direction\' not present in SecurityGroupRuleSecurityGroupRuleProtocolICMP JSON')
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in SecurityGroupRuleSecurityGroupRuleProtocolICMP JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in SecurityGroupRuleSecurityGroupRuleProtocolICMP JSON')
        if (ip_version := _dict.get('ip_version')) is not None:
            args['ip_version'] = ip_version
        else:
            raise ValueError('Required property \'ip_version\' not present in SecurityGroupRuleSecurityGroupRuleProtocolICMP JSON')
        if (local := _dict.get('local')) is not None:
            args['local'] = local
        else:
            raise ValueError('Required property \'local\' not present in SecurityGroupRuleSecurityGroupRuleProtocolICMP JSON')
        if (remote := _dict.get('remote')) is not None:
            args['remote'] = remote
        else:
            raise ValueError('Required property \'remote\' not present in SecurityGroupRuleSecurityGroupRuleProtocolICMP JSON')
        if (code := _dict.get('code')) is not None:
            args['code'] = code
        if (protocol := _dict.get('protocol')) is not None:
            args['protocol'] = protocol
        else:
            raise ValueError('Required property \'protocol\' not present in SecurityGroupRuleSecurityGroupRuleProtocolICMP JSON')
        if (type := _dict.get('type')) is not None:
            args['type'] = 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, 'local') and self.local is not None:
            if isinstance(self.local, dict):
                _dict['local'] = self.local
            else:
                _dict['local'] = self.local.to_dict()
        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 allow.
        """

        INBOUND = 'inbound'
        OUTBOUND = 'outbound'


    class IpVersionEnum(str, Enum):
        """
        The IP version to allow. The format of `local.address`, `remote.address`,
        `local.cidr_block` or `remote.cidr_block` must match this property, if they are
        used.
        If `remote` references a security group, then this rule only applies to IP
        addresses in that group matching this IP version.
        """

        IPV4 = 'ipv4'


    class ProtocolEnum(str, Enum):
        """
        The network protocol.
        """

        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.

    :param str direction: The direction of traffic to allow.
    :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 allow. The format of `local.address`,
          `remote.address`,
          `local.cidr_block` or `remote.cidr_block` must match this property, if they are
          used.
          If `remote` references a security group, then this rule only applies to IP
          addresses in that group matching this IP version.
    :param SecurityGroupRuleLocal local:
    :param SecurityGroupRuleRemote remote:
    :param int port_max: (optional) The inclusive upper bound of TCP/UDP destination
          port range.
    :param int port_min: (optional) The inclusive lower bound of TCP/UDP destination
          port range.
    :param str protocol: The network protocol.
    """

    def __init__(
        self,
        direction: str,
        href: str,
        id: str,
        ip_version: str,
        local: 'SecurityGroupRuleLocal',
        remote: 'SecurityGroupRuleRemote',
        protocol: str,
        *,
        port_max: Optional[int] = None,
        port_min: Optional[int] = None,
    ) -> None:
        """
        Initialize a SecurityGroupRuleSecurityGroupRuleProtocolTCPUDP object.

        :param str direction: The direction of traffic to allow.
        :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 allow. The format of
               `local.address`, `remote.address`,
               `local.cidr_block` or `remote.cidr_block` must match this property, if they
               are used.
               If `remote` references a security group, then this rule only applies to IP
               addresses in that group matching this IP version.
        :param SecurityGroupRuleLocal local:
        :param SecurityGroupRuleRemote remote:
        :param str protocol: The network protocol.
        :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.local = local
        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 := _dict.get('direction')) is not None:
            args['direction'] = direction
        else:
            raise ValueError('Required property \'direction\' not present in SecurityGroupRuleSecurityGroupRuleProtocolTCPUDP JSON')
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in SecurityGroupRuleSecurityGroupRuleProtocolTCPUDP JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in SecurityGroupRuleSecurityGroupRuleProtocolTCPUDP JSON')
        if (ip_version := _dict.get('ip_version')) is not None:
            args['ip_version'] = ip_version
        else:
            raise ValueError('Required property \'ip_version\' not present in SecurityGroupRuleSecurityGroupRuleProtocolTCPUDP JSON')
        if (local := _dict.get('local')) is not None:
            args['local'] = local
        else:
            raise ValueError('Required property \'local\' not present in SecurityGroupRuleSecurityGroupRuleProtocolTCPUDP JSON')
        if (remote := _dict.get('remote')) is not None:
            args['remote'] = remote
        else:
            raise ValueError('Required property \'remote\' not present in SecurityGroupRuleSecurityGroupRuleProtocolTCPUDP JSON')
        if (port_max := _dict.get('port_max')) is not None:
            args['port_max'] = port_max
        if (port_min := _dict.get('port_min')) is not None:
            args['port_min'] = port_min
        if (protocol := _dict.get('protocol')) is not None:
            args['protocol'] = 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, 'local') and self.local is not None:
            if isinstance(self.local, dict):
                _dict['local'] = self.local
            else:
                _dict['local'] = self.local.to_dict()
        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 allow.
        """

        INBOUND = 'inbound'
        OUTBOUND = 'outbound'


    class IpVersionEnum(str, Enum):
        """
        The IP version to allow. The format of `local.address`, `remote.address`,
        `local.cidr_block` or `remote.cidr_block` must match this property, if they are
        used.
        If `remote` references a security group, then this rule only applies to IP
        addresses in that group matching this IP version.
        """

        IPV4 = 'ipv4'


    class ProtocolEnum(str, Enum):
        """
        The network protocol.
        """

        TCP = 'tcp'
        UDP = 'udp'



class SecurityGroupTargetReferenceBareMetalServerNetworkInterfaceReferenceTargetContext(SecurityGroupTargetReference):
    """
    SecurityGroupTargetReferenceBareMetalServerNetworkInterfaceReferenceTargetContext.

    :param Deleted deleted: (optional) If present, this property indicates the
          referenced resource has been deleted, and provides
          some supplementary information.
    :param str href: The URL for this bare metal server network interface.
          If this bare metal server has network attachments, this network interface is a
          [read-only
          representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
          of its corresponding network attachment.
    :param str id: The unique identifier for this bare metal server network
          interface.
          If this bare metal server has network attachments, this network interface is a
          [read-only
          representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
          of its corresponding network attachment and its attached virtual network
          interface, and the identifier is that of the corresponding network attachment.
    :param str name: The name for this bare metal server network interface.
    :param str resource_type: The resource type.
    """

    def __init__(
        self,
        href: str,
        id: str,
        name: str,
        resource_type: str,
        *,
        deleted: Optional['Deleted'] = None,
    ) -> None:
        """
        Initialize a SecurityGroupTargetReferenceBareMetalServerNetworkInterfaceReferenceTargetContext object.

        :param str href: The URL for this bare metal server network interface.
               If this bare metal server has network attachments, this network interface
               is a
               [read-only
               representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
               of its corresponding network attachment.
        :param str id: The unique identifier for this bare metal server network
               interface.
               If this bare metal server has network attachments, this network interface
               is a
               [read-only
               representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
               of its corresponding network attachment and its attached virtual network
               interface, and the identifier is that of the corresponding network
               attachment.
        :param str name: The name for this bare metal server network interface.
        :param str resource_type: The resource type.
        :param Deleted 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 := _dict.get('deleted')) is not None:
            args['deleted'] = Deleted.from_dict(deleted)
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in SecurityGroupTargetReferenceBareMetalServerNetworkInterfaceReferenceTargetContext JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in SecurityGroupTargetReferenceBareMetalServerNetworkInterfaceReferenceTargetContext JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in SecurityGroupTargetReferenceBareMetalServerNetworkInterfaceReferenceTargetContext JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = 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.

    :param str crn: The CRN for this endpoint gateway.
    :param Deleted deleted: (optional) If present, this property indicates the
          referenced resource has been deleted, and provides
          some supplementary information.
    :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.
    """

    def __init__(
        self,
        crn: str,
        href: str,
        id: str,
        name: str,
        resource_type: str,
        *,
        deleted: Optional['Deleted'] = 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 Deleted 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 := _dict.get('crn')) is not None:
            args['crn'] = crn
        else:
            raise ValueError('Required property \'crn\' not present in SecurityGroupTargetReferenceEndpointGatewayReference JSON')
        if (deleted := _dict.get('deleted')) is not None:
            args['deleted'] = Deleted.from_dict(deleted)
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in SecurityGroupTargetReferenceEndpointGatewayReference JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in SecurityGroupTargetReferenceEndpointGatewayReference JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in SecurityGroupTargetReferenceEndpointGatewayReference JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = 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.

    :param str crn: The CRN for this load balancer.
    :param Deleted deleted: (optional) If present, this property indicates the
          referenced resource has been deleted, and provides
          some supplementary information.
    :param str href: The URL for this load balancer.
    :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.
    """

    def __init__(
        self,
        crn: str,
        href: str,
        id: str,
        name: str,
        resource_type: str,
        *,
        deleted: Optional['Deleted'] = None,
    ) -> None:
        """
        Initialize a SecurityGroupTargetReferenceLoadBalancerReference object.

        :param str crn: The CRN for this load balancer.
        :param str href: The URL for this load balancer.
        :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 Deleted 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 := _dict.get('crn')) is not None:
            args['crn'] = crn
        else:
            raise ValueError('Required property \'crn\' not present in SecurityGroupTargetReferenceLoadBalancerReference JSON')
        if (deleted := _dict.get('deleted')) is not None:
            args['deleted'] = Deleted.from_dict(deleted)
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in SecurityGroupTargetReferenceLoadBalancerReference JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in SecurityGroupTargetReferenceLoadBalancerReference JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in SecurityGroupTargetReferenceLoadBalancerReference JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = 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.

    :param Deleted deleted: (optional) If present, this property indicates the
          referenced resource has been deleted, and provides
          some supplementary information.
    :param str href: The URL for this instance network interface.
          If this instance has network attachments, this network interface is a
          [read-only
          representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
          of its corresponding network attachment.
    :param str id: The unique identifier for this instance network interface.
          If this instance has network attachments, this network interface is a
          [read-only
          representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
          of its corresponding network attachment and its attached virtual network
          interface, and the identifier is that of the corresponding network attachment.
    :param str name: The name for this instance network interface.
    :param str resource_type: The resource type.
    """

    def __init__(
        self,
        href: str,
        id: str,
        name: str,
        resource_type: str,
        *,
        deleted: Optional['Deleted'] = None,
    ) -> None:
        """
        Initialize a SecurityGroupTargetReferenceNetworkInterfaceReferenceTargetContext object.

        :param str href: The URL for this instance network interface.
               If this instance has network attachments, this network interface is a
               [read-only
               representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
               of its corresponding network attachment.
        :param str id: The unique identifier for this instance network interface.
               If this instance has network attachments, this network interface is a
               [read-only
               representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
               of its corresponding network attachment and its attached virtual network
               interface, and the identifier is that of the corresponding network
               attachment.
        :param str name: The name for this instance network interface.
        :param str resource_type: The resource type.
        :param Deleted 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 := _dict.get('deleted')) is not None:
            args['deleted'] = Deleted.from_dict(deleted)
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in SecurityGroupTargetReferenceNetworkInterfaceReferenceTargetContext JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in SecurityGroupTargetReferenceNetworkInterfaceReferenceTargetContext JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in SecurityGroupTargetReferenceNetworkInterfaceReferenceTargetContext JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = 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.

    :param str crn: The CRN for this VPN server.
    :param Deleted deleted: (optional) If present, this property indicates the
          referenced resource has been deleted, and provides
          some supplementary information.
    :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.
    """

    def __init__(
        self,
        crn: str,
        href: str,
        id: str,
        name: str,
        resource_type: str,
        *,
        deleted: Optional['Deleted'] = 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 Deleted 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 := _dict.get('crn')) is not None:
            args['crn'] = crn
        else:
            raise ValueError('Required property \'crn\' not present in SecurityGroupTargetReferenceVPNServerReference JSON')
        if (deleted := _dict.get('deleted')) is not None:
            args['deleted'] = Deleted.from_dict(deleted)
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in SecurityGroupTargetReferenceVPNServerReference JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in SecurityGroupTargetReferenceVPNServerReference JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in SecurityGroupTargetReferenceVPNServerReference JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = 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.

    :param str crn: The CRN for this virtual network interface.
    :param Deleted deleted: (optional) If present, this property indicates the
          referenced resource has been deleted, and provides
          some supplementary information.
    :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.
    """

    def __init__(
        self,
        crn: str,
        href: str,
        id: str,
        name: str,
        primary_ip: 'ReservedIPReference',
        resource_type: str,
        subnet: 'SubnetReference',
        *,
        deleted: Optional['Deleted'] = 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 Deleted 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 := _dict.get('crn')) is not None:
            args['crn'] = crn
        else:
            raise ValueError('Required property \'crn\' not present in SecurityGroupTargetReferenceVirtualNetworkInterfaceReference JSON')
        if (deleted := _dict.get('deleted')) is not None:
            args['deleted'] = Deleted.from_dict(deleted)
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in SecurityGroupTargetReferenceVirtualNetworkInterfaceReference JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in SecurityGroupTargetReferenceVirtualNetworkInterfaceReference JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in SecurityGroupTargetReferenceVirtualNetworkInterfaceReference JSON')
        if (primary_ip := _dict.get('primary_ip')) is not None:
            args['primary_ip'] = ReservedIPReference.from_dict(primary_ip)
        else:
            raise ValueError('Required property \'primary_ip\' not present in SecurityGroupTargetReferenceVirtualNetworkInterfaceReference JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = resource_type
        else:
            raise ValueError('Required property \'resource_type\' not present in SecurityGroupTargetReferenceVirtualNetworkInterfaceReference JSON')
        if (subnet := _dict.get('subnet')) is not None:
            args['subnet'] = SubnetReference.from_dict(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 ShareAccessorBindingAccessorShareReference(ShareAccessorBindingAccessor):
    """
    ShareAccessorBindingAccessorShareReference.

    :param str crn: The CRN for this file share.
    :param Deleted deleted: (optional) If present, this property indicates the
          referenced resource has been deleted, and provides
          some supplementary information.
    :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 ShareRemote remote: (optional) If present, this property indicates that
          the resource associated with this reference
          is remote and therefore may not be directly retrievable.
    :param str resource_type: The resource type.
    """

    def __init__(
        self,
        crn: str,
        href: str,
        id: str,
        name: str,
        resource_type: str,
        *,
        deleted: Optional['Deleted'] = None,
        remote: Optional['ShareRemote'] = None,
    ) -> None:
        """
        Initialize a ShareAccessorBindingAccessorShareReference 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 Deleted deleted: (optional) If present, this property indicates the
               referenced resource has been deleted, and provides
               some supplementary information.
        :param ShareRemote 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) -> 'ShareAccessorBindingAccessorShareReference':
        """Initialize a ShareAccessorBindingAccessorShareReference object from a json dictionary."""
        args = {}
        if (crn := _dict.get('crn')) is not None:
            args['crn'] = crn
        else:
            raise ValueError('Required property \'crn\' not present in ShareAccessorBindingAccessorShareReference JSON')
        if (deleted := _dict.get('deleted')) is not None:
            args['deleted'] = Deleted.from_dict(deleted)
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in ShareAccessorBindingAccessorShareReference JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in ShareAccessorBindingAccessorShareReference JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in ShareAccessorBindingAccessorShareReference JSON')
        if (remote := _dict.get('remote')) is not None:
            args['remote'] = ShareRemote.from_dict(remote)
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = resource_type
        else:
            raise ValueError('Required property \'resource_type\' not present in ShareAccessorBindingAccessorShareReference JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ShareAccessorBindingAccessorShareReference object from 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 ShareAccessorBindingAccessorShareReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ShareAccessorBindingAccessorShareReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ShareAccessorBindingAccessorShareReference') -> 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 ShareAccessorBindingAccessorWatsonxMachineLearningReference(ShareAccessorBindingAccessor):
    """
    ShareAccessorBindingAccessorWatsonxMachineLearningReference.

    :param str crn: The CRN for the watsonx machine learning resource.
    :param str resource_type: The resource type.
    """

    def __init__(
        self,
        crn: str,
        resource_type: str,
    ) -> None:
        """
        Initialize a ShareAccessorBindingAccessorWatsonxMachineLearningReference object.

        :param str crn: The CRN for the watsonx machine learning resource.
        :param str resource_type: The resource type.
        """
        # pylint: disable=super-init-not-called
        self.crn = crn
        self.resource_type = resource_type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ShareAccessorBindingAccessorWatsonxMachineLearningReference':
        """Initialize a ShareAccessorBindingAccessorWatsonxMachineLearningReference object from a json dictionary."""
        args = {}
        if (crn := _dict.get('crn')) is not None:
            args['crn'] = crn
        else:
            raise ValueError('Required property \'crn\' not present in ShareAccessorBindingAccessorWatsonxMachineLearningReference JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = resource_type
        else:
            raise ValueError('Required property \'resource_type\' not present in ShareAccessorBindingAccessorWatsonxMachineLearningReference JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ShareAccessorBindingAccessorWatsonxMachineLearningReference object from 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 ShareAccessorBindingAccessorWatsonxMachineLearningReference object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ShareAccessorBindingAccessorWatsonxMachineLearningReference') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ShareAccessorBindingAccessorWatsonxMachineLearningReference') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        WATSONX_MACHINE_LEARNING = 'watsonx_machine_learning'



class ShareIdentityByCRN(ShareIdentity):
    """
    ShareIdentityByCRN.

    :param 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 := _dict.get('crn')) is not None:
            args['crn'] = 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.

    :param 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 := _dict.get('href')) is not None:
            args['href'] = 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.

    :param 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 := _dict.get('id')) is not None:
            args['id'] = 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 must:
    - be in the same `zone` as the share
    - have `allow_ip_spoofing` set to `false`
    - have `enable_infrastructure_nat` set to `true`
    - have `protocol_state_filtering_mode` set to `auto` or `enabled`
    - not be in the same VPC as an existing mount target for this share
    - not have `ips` other than the `primary_ip` address
    If an existing virtual network interface is specified, it must not have a floating IP
    bound to it, and it must not be the target of a flow log collector.
    Required if the share's `access_control_mode` is `security_group`.

    :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`.
          The specified value must be listed in the share's
          `allowed_transit_encryption_modes`.
    :param ShareMountTargetVirtualNetworkInterfacePrototype
          virtual_network_interface:
    """

    def __init__(
        self,
        virtual_network_interface: 'ShareMountTargetVirtualNetworkInterfacePrototype',
        *,
        name: Optional[str] = None,
        transit_encryption: Optional[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`.
               The specified value must be listed in the share's
               `allowed_transit_encryption_modes`.
        """
        # 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 := _dict.get('name')) is not None:
            args['name'] = name
        if (transit_encryption := _dict.get('transit_encryption')) is not None:
            args['transit_encryption'] = transit_encryption
        if (virtual_network_interface := _dict.get('virtual_network_interface')) is not None:
            args['virtual_network_interface'] = 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`.
        The specified value must be listed in the share's
        `allowed_transit_encryption_modes`.
        """

        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`.

    :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`.
          The specified value must be listed in the share's
          `allowed_transit_encryption_modes`.
    :param VPCIdentity vpc: Identifies a VPC by a unique property.
    """

    def __init__(
        self,
        vpc: 'VPCIdentity',
        *,
        name: Optional[str] = None,
        transit_encryption: Optional[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`.
               The specified value must be listed in the share's
               `allowed_transit_encryption_modes`.
        """
        # 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 := _dict.get('name')) is not None:
            args['name'] = name
        if (transit_encryption := _dict.get('transit_encryption')) is not None:
            args['transit_encryption'] = transit_encryption
        if (vpc := _dict.get('vpc')) is not None:
            args['vpc'] = 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`.
        The specified value must be listed in the share's
        `allowed_transit_encryption_modes`.
        """

        NONE = 'none'
        USER_MANAGED = 'user_managed'



class ShareMountTargetVirtualNetworkInterfacePrototypeVirtualNetworkInterfaceIdentity(ShareMountTargetVirtualNetworkInterfacePrototype):
    """
    Identifies a virtual network interface by a unique property.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a ShareMountTargetVirtualNetworkInterfacePrototypeVirtualNetworkInterfaceIdentity object.

        """
        # pylint: disable=super-init-not-called
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['ShareMountTargetVirtualNetworkInterfacePrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityById', 'ShareMountTargetVirtualNetworkInterfacePrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByHref', 'ShareMountTargetVirtualNetworkInterfacePrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByCRN'])
        )
        raise Exception(msg)


class ShareMountTargetVirtualNetworkInterfacePrototypeVirtualNetworkInterfacePrototypeShareMountTargetContext(ShareMountTargetVirtualNetworkInterfacePrototype):
    """
    The virtual network interface for this target.

    :param bool allow_ip_spoofing: (optional) Indicates whether source IP spoofing
          is allowed on this interface. If `false`, source IP spoofing is prevented on
          this interface. If `true`, source IP spoofing is allowed on this interface.
    :param bool auto_delete: (optional) Indicates whether this virtual network
          interface will be automatically deleted when
          `target` is deleted.
    :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 virtual network interface,
            allowing the workload to perform any needed NAT operations.
          - `allow_ip_spoofing` must be `false`.
          - Can only be attached to a `target` with a `resource_type` of
            `bare_metal_server_network_attachment`.
    :param List[VirtualNetworkInterfaceIPPrototype] ips: (optional) Additional IP
          addresses to bind to the virtual network interface. Each item may be either a
          reserved IP identity, or a reserved IP prototype object which will be used to
          create a new reserved IP. All IP addresses must be in the primary IP's subnet.
          If reserved IP identities are provided, the specified reserved IPs must be
          unbound.
          If reserved IP prototype objects with addresses are provided, the addresses must
          be available on the virtual network interface's subnet. For any prototype
          objects that do not specify an address, an available address on the subnet will
          be automatically selected and reserved.
    :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 str protocol_state_filtering_mode: (optional) The protocol state
          filtering mode to use for this virtual network interface. If
          `auto`, protocol state packet filtering is enabled or disabled based on the
          virtual network interface's `target` resource type:
          - `bare_metal_server_network_attachment`: disabled
          - `instance_network_attachment`: enabled
          - `share_mount_target`: enabled
          Protocol state filtering monitors each network connection flowing over this
          virtual network interface, and drops any packets that are invalid based on the
          current connection state and protocol. See [Protocol state filtering
          mode](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#protocol-state-filtering)
          for more information.
    :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.
    """

    def __init__(
        self,
        *,
        allow_ip_spoofing: Optional[bool] = None,
        auto_delete: Optional[bool] = None,
        enable_infrastructure_nat: Optional[bool] = None,
        ips: Optional[List['VirtualNetworkInterfaceIPPrototype']] = None,
        name: Optional[str] = None,
        primary_ip: Optional['VirtualNetworkInterfacePrimaryIPPrototype'] = None,
        protocol_state_filtering_mode: Optional[str] = None,
        resource_group: Optional['ResourceGroupIdentity'] = None,
        security_groups: Optional[List['SecurityGroupIdentity']] = None,
        subnet: Optional['SubnetIdentity'] = None,
    ) -> None:
        """
        Initialize a ShareMountTargetVirtualNetworkInterfacePrototypeVirtualNetworkInterfacePrototypeShareMountTargetContext object.

        :param bool allow_ip_spoofing: (optional) Indicates whether source IP
               spoofing is allowed on this interface. If `false`, source IP spoofing is
               prevented on this interface. If `true`, source IP spoofing is allowed on
               this interface.
        :param bool auto_delete: (optional) Indicates whether this virtual network
               interface will be automatically deleted when
               `target` is deleted.
        :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 virtual network interface,
                 allowing the workload to perform any needed NAT operations.
               - `allow_ip_spoofing` must be `false`.
               - Can only be attached to a `target` with a `resource_type` of
                 `bare_metal_server_network_attachment`.
        :param List[VirtualNetworkInterfaceIPPrototype] ips: (optional) Additional
               IP addresses to bind to the virtual network interface. Each item may be
               either a reserved IP identity, or a reserved IP prototype object which will
               be used to create a new reserved IP. All IP addresses must be in the
               primary IP's subnet.
               If reserved IP identities are provided, the specified reserved IPs must be
               unbound.
               If reserved IP prototype objects with addresses are provided, the addresses
               must be available on the virtual network interface's subnet. For any
               prototype objects that do not specify an address, an available address on
               the subnet will be automatically selected and reserved.
        :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 str protocol_state_filtering_mode: (optional) The protocol state
               filtering mode to use for this virtual network interface. If
               `auto`, protocol state packet filtering is enabled or disabled based on the
               virtual network interface's `target` resource type:
               - `bare_metal_server_network_attachment`: disabled
               - `instance_network_attachment`: enabled
               - `share_mount_target`: enabled
               Protocol state filtering monitors each network connection flowing over this
               virtual network interface, and drops any packets that are invalid based on
               the current connection state and protocol. See [Protocol state filtering
               mode](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#protocol-state-filtering)
               for more information.
        :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.allow_ip_spoofing = allow_ip_spoofing
        self.auto_delete = auto_delete
        self.enable_infrastructure_nat = enable_infrastructure_nat
        self.ips = ips
        self.name = name
        self.primary_ip = primary_ip
        self.protocol_state_filtering_mode = protocol_state_filtering_mode
        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 (allow_ip_spoofing := _dict.get('allow_ip_spoofing')) is not None:
            args['allow_ip_spoofing'] = allow_ip_spoofing
        if (auto_delete := _dict.get('auto_delete')) is not None:
            args['auto_delete'] = auto_delete
        if (enable_infrastructure_nat := _dict.get('enable_infrastructure_nat')) is not None:
            args['enable_infrastructure_nat'] = enable_infrastructure_nat
        if (ips := _dict.get('ips')) is not None:
            args['ips'] = ips
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        if (primary_ip := _dict.get('primary_ip')) is not None:
            args['primary_ip'] = primary_ip
        if (protocol_state_filtering_mode := _dict.get('protocol_state_filtering_mode')) is not None:
            args['protocol_state_filtering_mode'] = protocol_state_filtering_mode
        if (resource_group := _dict.get('resource_group')) is not None:
            args['resource_group'] = resource_group
        if (security_groups := _dict.get('security_groups')) is not None:
            args['security_groups'] = security_groups
        if (subnet := _dict.get('subnet')) is not None:
            args['subnet'] = 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, 'allow_ip_spoofing') and self.allow_ip_spoofing is not None:
            _dict['allow_ip_spoofing'] = self.allow_ip_spoofing
        if hasattr(self, 'auto_delete') and self.auto_delete is not None:
            _dict['auto_delete'] = self.auto_delete
        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, '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, '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, 'protocol_state_filtering_mode') and self.protocol_state_filtering_mode is not None:
            _dict['protocol_state_filtering_mode'] = self.protocol_state_filtering_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, '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 ProtocolStateFilteringModeEnum(str, Enum):
        """
        The protocol state filtering mode to use for this virtual network interface. If
        `auto`, protocol state packet filtering is enabled or disabled based on the
        virtual network interface's `target` resource type:
        - `bare_metal_server_network_attachment`: disabled
        - `instance_network_attachment`: enabled
        - `share_mount_target`: enabled
        Protocol state filtering monitors each network connection flowing over this
        virtual network interface, and drops any packets that are invalid based on the
        current connection state and protocol. See [Protocol state filtering
        mode](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#protocol-state-filtering)
        for more information.
        """

        AUTO = 'auto'
        ENABLED = 'enabled'



class ShareProfileCapacityDependentRange(ShareProfileCapacity):
    """
    The permitted total capacity (in gigabytes) of a share with this profile depends on
    its configuration.

    :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.
    """

    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 := _dict.get('max')) is not None:
            args['max'] = max
        else:
            raise ValueError('Required property \'max\' not present in ShareProfileCapacityDependentRange JSON')
        if (min := _dict.get('min')) is not None:
            args['min'] = min
        else:
            raise ValueError('Required property \'min\' not present in ShareProfileCapacityDependentRange JSON')
        if (step := _dict.get('step')) is not None:
            args['step'] = step
        else:
            raise ValueError('Required property \'step\' not present in ShareProfileCapacityDependentRange JSON')
        if (type := _dict.get('type')) is not None:
            args['type'] = 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_RANGE = 'dependent_range'



class ShareProfileCapacityEnum(ShareProfileCapacity):
    """
    The permitted total capacities (in gigabytes) of a share with this profile.

    :param str type: The type for this profile field.
    :param List[int] values: The permitted values for this profile field.
    """

    def __init__(
        self,
        type: str,
        values: List[int],
    ) -> None:
        """
        Initialize a ShareProfileCapacityEnum object.

        :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.type = type
        self.values = values

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ShareProfileCapacityEnum':
        """Initialize a ShareProfileCapacityEnum object from a json dictionary."""
        args = {}
        if (type := _dict.get('type')) is not None:
            args['type'] = type
        else:
            raise ValueError('Required property \'type\' not present in ShareProfileCapacityEnum JSON')
        if (values := _dict.get('values')) is not None:
            args['values'] = 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, '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.

    :param str type: The type for this profile field.
    :param 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 := _dict.get('type')) is not None:
            args['type'] = type
        else:
            raise ValueError('Required property \'type\' not present in ShareProfileCapacityFixed JSON')
        if (value := _dict.get('value')) is not None:
            args['value'] = 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.

    :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.
    """

    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 := _dict.get('default')) is not None:
            args['default'] = default
        else:
            raise ValueError('Required property \'default\' not present in ShareProfileCapacityRange JSON')
        if (max := _dict.get('max')) is not None:
            args['max'] = max
        else:
            raise ValueError('Required property \'max\' not present in ShareProfileCapacityRange JSON')
        if (min := _dict.get('min')) is not None:
            args['min'] = min
        else:
            raise ValueError('Required property \'min\' not present in ShareProfileCapacityRange JSON')
        if (step := _dict.get('step')) is not None:
            args['step'] = step
        else:
            raise ValueError('Required property \'step\' not present in ShareProfileCapacityRange JSON')
        if (type := _dict.get('type')) is not None:
            args['type'] = 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.

    :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.
    """

    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 := _dict.get('max')) is not None:
            args['max'] = max
        else:
            raise ValueError('Required property \'max\' not present in ShareProfileIOPSDependentRange JSON')
        if (min := _dict.get('min')) is not None:
            args['min'] = min
        else:
            raise ValueError('Required property \'min\' not present in ShareProfileIOPSDependentRange JSON')
        if (step := _dict.get('step')) is not None:
            args['step'] = step
        else:
            raise ValueError('Required property \'step\' not present in ShareProfileIOPSDependentRange JSON')
        if (type := _dict.get('type')) is not None:
            args['type'] = 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_RANGE = 'dependent_range'



class ShareProfileIOPSEnum(ShareProfileIOPS):
    """
    The permitted IOPS values of a share with this profile.

    :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.
    """

    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 := _dict.get('default')) is not None:
            args['default'] = default
        else:
            raise ValueError('Required property \'default\' not present in ShareProfileIOPSEnum JSON')
        if (type := _dict.get('type')) is not None:
            args['type'] = type
        else:
            raise ValueError('Required property \'type\' not present in ShareProfileIOPSEnum JSON')
        if (values := _dict.get('values')) is not None:
            args['values'] = 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.

    :param str type: The type for this profile field.
    :param 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 := _dict.get('type')) is not None:
            args['type'] = type
        else:
            raise ValueError('Required property \'type\' not present in ShareProfileIOPSFixed JSON')
        if (value := _dict.get('value')) is not None:
            args['value'] = 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.

    :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.
    """

    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 := _dict.get('default')) is not None:
            args['default'] = default
        else:
            raise ValueError('Required property \'default\' not present in ShareProfileIOPSRange JSON')
        if (max := _dict.get('max')) is not None:
            args['max'] = max
        else:
            raise ValueError('Required property \'max\' not present in ShareProfileIOPSRange JSON')
        if (min := _dict.get('min')) is not None:
            args['min'] = min
        else:
            raise ValueError('Required property \'min\' not present in ShareProfileIOPSRange JSON')
        if (step := _dict.get('step')) is not None:
            args['step'] = step
        else:
            raise ValueError('Required property \'step\' not present in ShareProfileIOPSRange JSON')
        if (type := _dict.get('type')) is not None:
            args['type'] = 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.

    :param 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 := _dict.get('href')) is not None:
            args['href'] = 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.

    :param 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 := _dict.get('name')) is not None:
            args['name'] = 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 SharePrototypeShareByOriginShare(SharePrototype):
    """
    Create an accessor file share for an existing file share. The values for
    `initial_owner`,
    `access_control_mode`, `encryption_key`, `zone`, `profile`, `iops` and `size` will be
    inherited from `origin_share`.

    :param List[str] allowed_transit_encryption_modes: (optional) The transit
          encryption modes to allow for this share. If unspecified:
          - If share mount targets are specified, and those share mount targets all
          specify a
            `transit_encryption` of `user_managed`, then only `user_managed` will be
          allowed.
          - Otherwise, all `transit_encryption` modes will be allowed.
    :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 ShareIdentity origin_share: The origin share for the accessor share. The
          origin share must have an
          `access_control_mode` of `security_group`, and must not have an
          `accessor_binding_role` of `accessor`.
          The specified share may be in a different account, subject to IAM policies.
    """

    def __init__(
        self,
        origin_share: 'ShareIdentity',
        *,
        allowed_transit_encryption_modes: Optional[List[str]] = None,
        mount_targets: Optional[List['ShareMountTargetPrototype']] = None,
        name: Optional[str] = None,
        replica_share: Optional['SharePrototypeShareContext'] = None,
        user_tags: Optional[List[str]] = None,
    ) -> None:
        """
        Initialize a SharePrototypeShareByOriginShare object.

        :param ShareIdentity origin_share: The origin share for the accessor share.
               The origin share must have an
               `access_control_mode` of `security_group`, and must not have an
               `accessor_binding_role` of `accessor`.
               The specified share may be in a different account, subject to IAM policies.
        :param List[str] allowed_transit_encryption_modes: (optional) The transit
               encryption modes to allow for this share. If unspecified:
               - If share mount targets are specified, and those share mount targets all
               specify a
                 `transit_encryption` of `user_managed`, then only `user_managed` will be
               allowed.
               - Otherwise, all `transit_encryption` modes will be allowed.
        :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.
        """
        # pylint: disable=super-init-not-called
        self.allowed_transit_encryption_modes = allowed_transit_encryption_modes
        self.mount_targets = mount_targets
        self.name = name
        self.replica_share = replica_share
        self.user_tags = user_tags
        self.origin_share = origin_share

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'SharePrototypeShareByOriginShare':
        """Initialize a SharePrototypeShareByOriginShare object from a json dictionary."""
        args = {}
        if (allowed_transit_encryption_modes := _dict.get('allowed_transit_encryption_modes')) is not None:
            args['allowed_transit_encryption_modes'] = allowed_transit_encryption_modes
        if (mount_targets := _dict.get('mount_targets')) is not None:
            args['mount_targets'] = mount_targets
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        if (replica_share := _dict.get('replica_share')) is not None:
            args['replica_share'] = SharePrototypeShareContext.from_dict(replica_share)
        if (user_tags := _dict.get('user_tags')) is not None:
            args['user_tags'] = user_tags
        if (origin_share := _dict.get('origin_share')) is not None:
            args['origin_share'] = origin_share
        else:
            raise ValueError('Required property \'origin_share\' not present in SharePrototypeShareByOriginShare JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SharePrototypeShareByOriginShare object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'allowed_transit_encryption_modes') and self.allowed_transit_encryption_modes is not None:
            _dict['allowed_transit_encryption_modes'] = self.allowed_transit_encryption_modes
        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, '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, 'origin_share') and self.origin_share is not None:
            if isinstance(self.origin_share, dict):
                _dict['origin_share'] = self.origin_share
            else:
                _dict['origin_share'] = self.origin_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 SharePrototypeShareByOriginShare object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'SharePrototypeShareByOriginShare') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'SharePrototypeShareByOriginShare') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class AllowedTransitEncryptionModesEnum(str, Enum):
        """
        An allowed transit encryption mode for this share.
        - `none`: Not encrypted in transit.
        - `user_managed`: Encrypted in transit using an instance identity certificate.
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        NONE = 'none'
        USER_MANAGED = 'user_managed'



class SharePrototypeShareBySize(SharePrototype):
    """
    Create a file share by size.

    :param List[str] allowed_transit_encryption_modes: (optional) The transit
          encryption modes to allow for this share. If unspecified:
          - If share mount targets are specified, and those share mount targets all
          specify a
            `transit_encryption` of `user_managed`, then only `user_managed` will be
          allowed.
          - Otherwise, all `transit_encryption` modes will be allowed.
    :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 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 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 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 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 ZoneIdentity zone: The zone this file share will reside in. For a replica
          share in the same region as
          the source share, this must be a different zone from the source share.
    """

    def __init__(
        self,
        profile: 'ShareProfileIdentity',
        size: int,
        zone: 'ZoneIdentity',
        *,
        allowed_transit_encryption_modes: Optional[List[str]] = None,
        mount_targets: Optional[List['ShareMountTargetPrototype']] = None,
        name: Optional[str] = None,
        replica_share: Optional['SharePrototypeShareContext'] = None,
        user_tags: Optional[List[str]] = None,
        access_control_mode: Optional[str] = None,
        encryption_key: Optional['EncryptionKeyIdentity'] = None,
        initial_owner: Optional['ShareInitialOwner'] = None,
        iops: Optional[int] = None,
        resource_group: Optional['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 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 ZoneIdentity zone: The zone this file share will reside in. For a
               replica share in the same region as
               the source share, this must be a different zone from the source share.
        :param List[str] allowed_transit_encryption_modes: (optional) The transit
               encryption modes to allow for this share. If unspecified:
               - If share mount targets are specified, and those share mount targets all
               specify a
                 `transit_encryption` of `user_managed`, then only `user_managed` will be
               allowed.
               - Otherwise, all `transit_encryption` modes will be allowed.
        :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 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 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.allowed_transit_encryption_modes = allowed_transit_encryption_modes
        self.mount_targets = mount_targets
        self.name = name
        self.replica_share = replica_share
        self.user_tags = user_tags
        self.access_control_mode = access_control_mode
        self.encryption_key = encryption_key
        self.initial_owner = initial_owner
        self.iops = iops
        self.profile = profile
        self.resource_group = resource_group
        self.size = size
        self.zone = zone

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'SharePrototypeShareBySize':
        """Initialize a SharePrototypeShareBySize object from a json dictionary."""
        args = {}
        if (allowed_transit_encryption_modes := _dict.get('allowed_transit_encryption_modes')) is not None:
            args['allowed_transit_encryption_modes'] = allowed_transit_encryption_modes
        if (mount_targets := _dict.get('mount_targets')) is not None:
            args['mount_targets'] = mount_targets
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        if (replica_share := _dict.get('replica_share')) is not None:
            args['replica_share'] = SharePrototypeShareContext.from_dict(replica_share)
        if (user_tags := _dict.get('user_tags')) is not None:
            args['user_tags'] = user_tags
        if (access_control_mode := _dict.get('access_control_mode')) is not None:
            args['access_control_mode'] = access_control_mode
        if (encryption_key := _dict.get('encryption_key')) is not None:
            args['encryption_key'] = encryption_key
        if (initial_owner := _dict.get('initial_owner')) is not None:
            args['initial_owner'] = ShareInitialOwner.from_dict(initial_owner)
        if (iops := _dict.get('iops')) is not None:
            args['iops'] = iops
        if (profile := _dict.get('profile')) is not None:
            args['profile'] = profile
        else:
            raise ValueError('Required property \'profile\' not present in SharePrototypeShareBySize JSON')
        if (resource_group := _dict.get('resource_group')) is not None:
            args['resource_group'] = resource_group
        if (size := _dict.get('size')) is not None:
            args['size'] = size
        else:
            raise ValueError('Required property \'size\' not present in SharePrototypeShareBySize JSON')
        if (zone := _dict.get('zone')) is not None:
            args['zone'] = zone
        else:
            raise ValueError('Required property \'zone\' 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, 'allowed_transit_encryption_modes') and self.allowed_transit_encryption_modes is not None:
            _dict['allowed_transit_encryption_modes'] = self.allowed_transit_encryption_modes
        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, '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, '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, 'iops') and self.iops is not None:
            _dict['iops'] = self.iops
        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, 'size') and self.size is not None:
            _dict['size'] = self.size
        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 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 AllowedTransitEncryptionModesEnum(str, Enum):
        """
        An allowed transit encryption mode for this share.
        - `none`: Not encrypted in transit.
        - `user_managed`: Encrypted in transit using an instance identity certificate.
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        NONE = 'none'
        USER_MANAGED = 'user_managed'


    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
    `initial_owner`,
    `access_control_mode`, `encryption_key` and `size` will be inherited from
    `source_share`.

    :param List[str] allowed_transit_encryption_modes: (optional) The transit
          encryption modes to allow for this share. If unspecified:
          - If share mount targets are specified, and those share mount targets all
          specify a
            `transit_encryption` of `user_managed`, then only `user_managed` will be
          allowed.
          - Otherwise, all `transit_encryption` modes will be allowed.
    :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 EncryptionKeyIdentity encryption_key: (optional) The root key to use to
          wrap the data encryption key for the share.
          This property must be specified if the `source_share` is in a different region
          and has
          an `encryption` type of `user_managed`, and must not be specified otherwise (its
          value
          will be inherited from `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 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 every 15 minutes.
          The scheduling frequency for this property may
          [increase](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :param ResourceGroupIdentity resource_group: (optional) The resource group to
          use. If unspecified, the resource group from
          the source share will be used.
    :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. If source file share is
          specified
          by CRN, it may be in an [associated partner
          region](https://cloud.ibm.com/docs/vpc?topic=vpc-file-storage-replication).
    :param ZoneIdentity zone: The zone this file share will reside in. For a replica
          share in the same region as
          the source share, this must be a different zone from the source share.
    """

    def __init__(
        self,
        profile: 'ShareProfileIdentity',
        replication_cron_spec: str,
        source_share: 'ShareIdentity',
        zone: 'ZoneIdentity',
        *,
        allowed_transit_encryption_modes: Optional[List[str]] = None,
        mount_targets: Optional[List['ShareMountTargetPrototype']] = None,
        name: Optional[str] = None,
        replica_share: Optional['SharePrototypeShareContext'] = None,
        user_tags: Optional[List[str]] = None,
        encryption_key: Optional['EncryptionKeyIdentity'] = None,
        iops: Optional[int] = None,
        resource_group: Optional['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 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 every 15
               minutes.
               The scheduling frequency for this property may
               [increase](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in
               the future.
        :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. If source file share is
               specified
               by CRN, it may be in an [associated partner
               region](https://cloud.ibm.com/docs/vpc?topic=vpc-file-storage-replication).
        :param ZoneIdentity zone: The zone this file share will reside in. For a
               replica share in the same region as
               the source share, this must be a different zone from the source share.
        :param List[str] allowed_transit_encryption_modes: (optional) The transit
               encryption modes to allow for this share. If unspecified:
               - If share mount targets are specified, and those share mount targets all
               specify a
                 `transit_encryption` of `user_managed`, then only `user_managed` will be
               allowed.
               - Otherwise, all `transit_encryption` modes will be allowed.
        :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 EncryptionKeyIdentity encryption_key: (optional) The root key to use
               to wrap the data encryption key for the share.
               This property must be specified if the `source_share` is in a different
               region and has
               an `encryption` type of `user_managed`, and must not be specified otherwise
               (its value
               will be inherited from `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 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.allowed_transit_encryption_modes = allowed_transit_encryption_modes
        self.mount_targets = mount_targets
        self.name = name
        self.replica_share = replica_share
        self.user_tags = user_tags
        self.encryption_key = encryption_key
        self.iops = iops
        self.profile = profile
        self.replication_cron_spec = replication_cron_spec
        self.resource_group = resource_group
        self.source_share = source_share
        self.zone = zone

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'SharePrototypeShareBySourceShare':
        """Initialize a SharePrototypeShareBySourceShare object from a json dictionary."""
        args = {}
        if (allowed_transit_encryption_modes := _dict.get('allowed_transit_encryption_modes')) is not None:
            args['allowed_transit_encryption_modes'] = allowed_transit_encryption_modes
        if (mount_targets := _dict.get('mount_targets')) is not None:
            args['mount_targets'] = mount_targets
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        if (replica_share := _dict.get('replica_share')) is not None:
            args['replica_share'] = SharePrototypeShareContext.from_dict(replica_share)
        if (user_tags := _dict.get('user_tags')) is not None:
            args['user_tags'] = user_tags
        if (encryption_key := _dict.get('encryption_key')) is not None:
            args['encryption_key'] = encryption_key
        if (iops := _dict.get('iops')) is not None:
            args['iops'] = iops
        if (profile := _dict.get('profile')) is not None:
            args['profile'] = profile
        else:
            raise ValueError('Required property \'profile\' not present in SharePrototypeShareBySourceShare JSON')
        if (replication_cron_spec := _dict.get('replication_cron_spec')) is not None:
            args['replication_cron_spec'] = replication_cron_spec
        else:
            raise ValueError('Required property \'replication_cron_spec\' not present in SharePrototypeShareBySourceShare JSON')
        if (resource_group := _dict.get('resource_group')) is not None:
            args['resource_group'] = resource_group
        if (source_share := _dict.get('source_share')) is not None:
            args['source_share'] = source_share
        else:
            raise ValueError('Required property \'source_share\' not present in SharePrototypeShareBySourceShare JSON')
        if (zone := _dict.get('zone')) is not None:
            args['zone'] = zone
        else:
            raise ValueError('Required property \'zone\' 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, 'allowed_transit_encryption_modes') and self.allowed_transit_encryption_modes is not None:
            _dict['allowed_transit_encryption_modes'] = self.allowed_transit_encryption_modes
        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, '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, '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, '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, '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, '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 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 AllowedTransitEncryptionModesEnum(str, Enum):
        """
        An allowed transit encryption mode for this share.
        - `none`: Not encrypted in transit.
        - `user_managed`: Encrypted in transit using an instance identity certificate.
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        NONE = 'none'
        USER_MANAGED = 'user_managed'



class SnapshotConsistencyGroupPrototypeSnapshotConsistencyGroupBySnapshots(SnapshotConsistencyGroupPrototype):
    """
    SnapshotConsistencyGroupPrototypeSnapshotConsistencyGroupBySnapshots.

    :param bool delete_snapshots_on_delete: (optional) Indicates whether deleting
          the snapshot consistency group will also delete the snapshots in the group.
    :param str name: (optional) The name for this snapshot consistency group. The
          name must be unique across all snapshot consistency groups in the region.
          If unspecified, the name will be a hyphenated list of randomly-selected words.
    :param ResourceGroupIdentity resource_group: (optional)
    :param List[SnapshotPrototypeSnapshotConsistencyGroupContext] snapshots: The
          data-consistent member snapshots to create.  All snapshots must specify a
          `source_volume` attached to the same virtual server instance.
    """

    def __init__(
        self,
        snapshots: List['SnapshotPrototypeSnapshotConsistencyGroupContext'],
        *,
        delete_snapshots_on_delete: Optional[bool] = None,
        name: Optional[str] = None,
        resource_group: Optional['ResourceGroupIdentity'] = None,
    ) -> None:
        """
        Initialize a SnapshotConsistencyGroupPrototypeSnapshotConsistencyGroupBySnapshots object.

        :param List[SnapshotPrototypeSnapshotConsistencyGroupContext] snapshots:
               The data-consistent member snapshots to create.  All snapshots must specify
               a
               `source_volume` attached to the same virtual server instance.
        :param bool delete_snapshots_on_delete: (optional) Indicates whether
               deleting the snapshot consistency group will also delete the snapshots in
               the group.
        :param str name: (optional) The name for this snapshot consistency group.
               The name must be unique across all snapshot consistency groups 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.delete_snapshots_on_delete = delete_snapshots_on_delete
        self.name = name
        self.resource_group = resource_group
        self.snapshots = snapshots

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'SnapshotConsistencyGroupPrototypeSnapshotConsistencyGroupBySnapshots':
        """Initialize a SnapshotConsistencyGroupPrototypeSnapshotConsistencyGroupBySnapshots object from a json dictionary."""
        args = {}
        if (delete_snapshots_on_delete := _dict.get('delete_snapshots_on_delete')) is not None:
            args['delete_snapshots_on_delete'] = delete_snapshots_on_delete
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        if (resource_group := _dict.get('resource_group')) is not None:
            args['resource_group'] = resource_group
        if (snapshots := _dict.get('snapshots')) is not None:
            args['snapshots'] = [SnapshotPrototypeSnapshotConsistencyGroupContext.from_dict(v) for v in snapshots]
        else:
            raise ValueError('Required property \'snapshots\' not present in SnapshotConsistencyGroupPrototypeSnapshotConsistencyGroupBySnapshots JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a SnapshotConsistencyGroupPrototypeSnapshotConsistencyGroupBySnapshots object from 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_snapshots_on_delete') and self.delete_snapshots_on_delete is not None:
            _dict['delete_snapshots_on_delete'] = self.delete_snapshots_on_delete
        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, '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
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this SnapshotConsistencyGroupPrototypeSnapshotConsistencyGroupBySnapshots object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'SnapshotConsistencyGroupPrototypeSnapshotConsistencyGroupBySnapshots') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'SnapshotConsistencyGroupPrototypeSnapshotConsistencyGroupBySnapshots') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class SnapshotIdentityByCRN(SnapshotIdentity):
    """
    SnapshotIdentityByCRN.

    :param 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 := _dict.get('crn')) is not None:
            args['crn'] = 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.

    :param 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 := _dict.get('href')) is not None:
            args['href'] = 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.

    :param 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 := _dict.get('id')) is not None:
            args['id'] = 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.

    :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.
    :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.
    """

    def __init__(
        self,
        source_snapshot: 'SnapshotIdentityByCRN',
        *,
        clones: Optional[List['SnapshotClonePrototype']] = None,
        name: Optional[str] = None,
        resource_group: Optional['ResourceGroupIdentity'] = None,
        user_tags: Optional[List[str]] = None,
        encryption_key: Optional['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 := _dict.get('clones')) is not None:
            args['clones'] = [SnapshotClonePrototype.from_dict(v) for v in clones]
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        if (resource_group := _dict.get('resource_group')) is not None:
            args['resource_group'] = resource_group
        if (user_tags := _dict.get('user_tags')) is not None:
            args['user_tags'] = user_tags
        if (encryption_key := _dict.get('encryption_key')) is not None:
            args['encryption_key'] = encryption_key
        if (source_snapshot := _dict.get('source_snapshot')) is not None:
            args['source_snapshot'] = SnapshotIdentityByCRN.from_dict(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.

    :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 VolumeIdentity source_volume: The volume to create this snapshot from.
    """

    def __init__(
        self,
        source_volume: 'VolumeIdentity',
        *,
        clones: Optional[List['SnapshotClonePrototype']] = None,
        name: Optional[str] = None,
        resource_group: Optional['ResourceGroupIdentity'] = None,
        user_tags: Optional[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 := _dict.get('clones')) is not None:
            args['clones'] = [SnapshotClonePrototype.from_dict(v) for v in clones]
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        if (resource_group := _dict.get('resource_group')) is not None:
            args['resource_group'] = resource_group
        if (user_tags := _dict.get('user_tags')) is not None:
            args['user_tags'] = user_tags
        if (source_volume := _dict.get('source_volume')) is not None:
            args['source_volume'] = 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.

    :param 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 := _dict.get('crn')) is not None:
            args['crn'] = 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.

    :param 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 := _dict.get('href')) is not None:
            args['href'] = 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.

    :param 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 := _dict.get('id')) is not None:
            args['id'] = 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.

    :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 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 ZoneIdentity zone: (optional) The zone this subnet will reside in.
    """

    def __init__(
        self,
        vpc: 'VPCIdentity',
        ipv4_cidr_block: str,
        *,
        ip_version: Optional[str] = None,
        name: Optional[str] = None,
        network_acl: Optional['NetworkACLIdentity'] = None,
        public_gateway: Optional['PublicGatewayIdentity'] = None,
        resource_group: Optional['ResourceGroupIdentity'] = None,
        routing_table: Optional['RoutingTableIdentity'] = None,
        zone: Optional['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 := _dict.get('ip_version')) is not None:
            args['ip_version'] = ip_version
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        if (network_acl := _dict.get('network_acl')) is not None:
            args['network_acl'] = network_acl
        if (public_gateway := _dict.get('public_gateway')) is not None:
            args['public_gateway'] = public_gateway
        if (resource_group := _dict.get('resource_group')) is not None:
            args['resource_group'] = resource_group
        if (routing_table := _dict.get('routing_table')) is not None:
            args['routing_table'] = routing_table
        if (vpc := _dict.get('vpc')) is not None:
            args['vpc'] = vpc
        else:
            raise ValueError('Required property \'vpc\' not present in SubnetPrototypeSubnetByCIDR JSON')
        if (ipv4_cidr_block := _dict.get('ipv4_cidr_block')) is not None:
            args['ipv4_cidr_block'] = ipv4_cidr_block
        else:
            raise ValueError('Required property \'ipv4_cidr_block\' not present in SubnetPrototypeSubnetByCIDR JSON')
        if (zone := _dict.get('zone')) is not None:
            args['zone'] = 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.

    :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 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.
    """

    def __init__(
        self,
        vpc: 'VPCIdentity',
        total_ipv4_address_count: int,
        zone: 'ZoneIdentity',
        *,
        ip_version: Optional[str] = None,
        name: Optional[str] = None,
        network_acl: Optional['NetworkACLIdentity'] = None,
        public_gateway: Optional['PublicGatewayIdentity'] = None,
        resource_group: Optional['ResourceGroupIdentity'] = None,
        routing_table: Optional['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 := _dict.get('ip_version')) is not None:
            args['ip_version'] = ip_version
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        if (network_acl := _dict.get('network_acl')) is not None:
            args['network_acl'] = network_acl
        if (public_gateway := _dict.get('public_gateway')) is not None:
            args['public_gateway'] = public_gateway
        if (resource_group := _dict.get('resource_group')) is not None:
            args['resource_group'] = resource_group
        if (routing_table := _dict.get('routing_table')) is not None:
            args['routing_table'] = routing_table
        if (vpc := _dict.get('vpc')) is not None:
            args['vpc'] = vpc
        else:
            raise ValueError('Required property \'vpc\' not present in SubnetPrototypeSubnetByTotalCount JSON')
        if (total_ipv4_address_count := _dict.get('total_ipv4_address_count')) is not None:
            args['total_ipv4_address_count'] = total_ipv4_address_count
        else:
            raise ValueError('Required property \'total_ipv4_address_count\' not present in SubnetPrototypeSubnetByTotalCount JSON')
        if (zone := _dict.get('zone')) is not None:
            args['zone'] = 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.

    :param 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 := _dict.get('crn')) is not None:
            args['crn'] = 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.

    :param 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 := _dict.get('href')) is not None:
            args['href'] = 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.

    :param 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 := _dict.get('id')) is not None:
            args['id'] = 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 TrustedProfileIdentityByCRN(TrustedProfileIdentity):
    """
    TrustedProfileIdentityByCRN.

    :param str crn: The CRN for this trusted profile.
    """

    def __init__(
        self,
        crn: str,
    ) -> None:
        """
        Initialize a TrustedProfileIdentityByCRN 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) -> 'TrustedProfileIdentityByCRN':
        """Initialize a TrustedProfileIdentityByCRN object from a json dictionary."""
        args = {}
        if (crn := _dict.get('crn')) is not None:
            args['crn'] = crn
        else:
            raise ValueError('Required property \'crn\' not present in TrustedProfileIdentityByCRN JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a TrustedProfileIdentityByCRN object from 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 TrustedProfileIdentityByCRN object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'TrustedProfileIdentityByCRN') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'TrustedProfileIdentityByCRN') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class TrustedProfileIdentityById(TrustedProfileIdentity):
    """
    TrustedProfileIdentityById.

    :param str id: The unique identifier for this trusted profile.
    """

    def __init__(
        self,
        id: str,
    ) -> None:
        """
        Initialize a TrustedProfileIdentityById 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) -> 'TrustedProfileIdentityById':
        """Initialize a TrustedProfileIdentityById object from a json dictionary."""
        args = {}
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in TrustedProfileIdentityById JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a TrustedProfileIdentityById object from 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 TrustedProfileIdentityById object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'TrustedProfileIdentityById') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'TrustedProfileIdentityById') -> 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.

    :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`.
          If `zone_affinity` is specified, exactly one DNS server must be specified for
          each zone in the region. The DHCP [Domain Name Server
          Option](https://datatracker.ietf.org/doc/html/rfc2132#section-3.8) for a zone
          will list this DNS server first, followed by unique DNS servers from other zones
          if available.
          If `zone_affinity` is not specified, the DHCP [Domain Name Server
          Option](https://datatracker.ietf.org/doc/html/rfc2132#section-3.8) for each zone
          will list all the manual DNS servers in the order specified.
    :param 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`.
               If `zone_affinity` is specified, exactly one DNS server must be specified
               for each zone in the region. The DHCP [Domain Name Server
               Option](https://datatracker.ietf.org/doc/html/rfc2132#section-3.8) for a
               zone will list this DNS server first, followed by unique DNS servers from
               other zones if available.
               If `zone_affinity` is not specified, the DHCP [Domain Name Server
               Option](https://datatracker.ietf.org/doc/html/rfc2132#section-3.8) for each
               zone will list all the manual DNS servers in the order specified.
        :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 := _dict.get('manual_servers')) is not None:
            args['manual_servers'] = [DNSServerPrototype.from_dict(v) for v in manual_servers]
        else:
            raise ValueError('Required property \'manual_servers\' not present in VPCDNSResolverPrototypeVPCDNSResolverTypeManualPrototype JSON')
        if (type := _dict.get('type')) is not None:
            args['type'] = 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.

    :param str type: (optional) The type of the DNS resolver to use.
    """

    def __init__(
        self,
        *,
        type: Optional[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 := _dict.get('type')) is not None:
            args['type'] = 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.

    :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`
          The maximum number of DNS servers is expected to
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :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.
    """

    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`
               The maximum number of DNS servers is expected to
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :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 := _dict.get('servers')) is not None:
            args['servers'] = [DNSServer.from_dict(v) for v in servers]
        else:
            raise ValueError('Required property \'servers\' not present in VPCDNSResolverTypeDelegated JSON')
        if (type := _dict.get('type')) is not None:
            args['type'] = type
        else:
            raise ValueError('Required property \'type\' not present in VPCDNSResolverTypeDelegated JSON')
        if (vpc := _dict.get('vpc')) is not None:
            args['vpc'] = VPCReferenceDNSResolverContext.from_dict(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.

    :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`
          The maximum number of DNS servers is expected to
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :param List[DNSServer] manual_servers: The manually specified DNS servers for
          this VPC.
          If the DNS servers have `zone_affinity`, the DHCP [Domain Name Server
          Option](https://datatracker.ietf.org/doc/html/rfc2132#section-3.8) for a zone
          will list the DNS server with the affinity for that zone first, followed by the
          unique DNS servers from other zones.
          If the DNS servers do not have `zone_affinity`, the DHCP [Domain Name Server
          Option](https://datatracker.ietf.org/doc/html/rfc2132#section-3.8) for each zone
          will list all the manual DNS servers in the order specified.
          The maximum number of manual DNS servers is expected to
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :param 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`
               The maximum number of DNS servers is expected to
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :param List[DNSServer] manual_servers: The manually specified DNS servers
               for this VPC.
               If the DNS servers have `zone_affinity`, the DHCP [Domain Name Server
               Option](https://datatracker.ietf.org/doc/html/rfc2132#section-3.8) for a
               zone will list the DNS server with the affinity for that zone first,
               followed by the unique DNS servers from other zones.
               If the DNS servers do not have `zone_affinity`, the DHCP [Domain Name
               Server Option](https://datatracker.ietf.org/doc/html/rfc2132#section-3.8)
               for each zone will list all the manual DNS servers in the order specified.
               The maximum number of manual DNS servers is expected to
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :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 := _dict.get('servers')) is not None:
            args['servers'] = [DNSServer.from_dict(v) for v in servers]
        else:
            raise ValueError('Required property \'servers\' not present in VPCDNSResolverTypeManual JSON')
        if (manual_servers := _dict.get('manual_servers')) is not None:
            args['manual_servers'] = [DNSServer.from_dict(v) for v in manual_servers]
        else:
            raise ValueError('Required property \'manual_servers\' not present in VPCDNSResolverTypeManual JSON')
        if (type := _dict.get('type')) is not None:
            args['type'] = 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.

    :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`
          The maximum number of DNS servers is expected to
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :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. Applies
          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.
    """

    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`
               The maximum number of DNS servers is expected to
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :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.
               Applies 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 := _dict.get('servers')) is not None:
            args['servers'] = [DNSServer.from_dict(v) for v in servers]
        else:
            raise ValueError('Required property \'servers\' not present in VPCDNSResolverTypeSystem JSON')
        if (configuration := _dict.get('configuration')) is not None:
            args['configuration'] = configuration
        else:
            raise ValueError('Required property \'configuration\' not present in VPCDNSResolverTypeSystem JSON')
        if (type := _dict.get('type')) is not None:
            args['type'] = 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. Applies
        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.

    :param 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 := _dict.get('crn')) is not None:
            args['crn'] = 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.

    :param 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 := _dict.get('href')) is not None:
            args['href'] = 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.

    :param 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 := _dict.get('id')) is not None:
            args['id'] = 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.

    :param 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 := _dict.get('crn')) is not None:
            args['crn'] = 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.

    :param 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 := _dict.get('href')) is not None:
            args['href'] = 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.

    :param 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 := _dict.get('id')) is not None:
            args['id'] = 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 VPNGatewayConnectionIKEIdentityPrototypeVPNGatewayConnectionIKEIdentityFQDN(VPNGatewayConnectionIKEIdentityPrototype):
    """
    VPNGatewayConnectionIKEIdentityPrototypeVPNGatewayConnectionIKEIdentityFQDN.

    :param str type: The IKE identity type.
    :param str value: The IKE identity FQDN value.
    """

    def __init__(
        self,
        type: str,
        value: str,
    ) -> None:
        """
        Initialize a VPNGatewayConnectionIKEIdentityPrototypeVPNGatewayConnectionIKEIdentityFQDN object.

        :param str type: The IKE identity type.
        :param str value: The IKE identity FQDN value.
        """
        # pylint: disable=super-init-not-called
        self.type = type
        self.value = value

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPNGatewayConnectionIKEIdentityPrototypeVPNGatewayConnectionIKEIdentityFQDN':
        """Initialize a VPNGatewayConnectionIKEIdentityPrototypeVPNGatewayConnectionIKEIdentityFQDN object from a json dictionary."""
        args = {}
        if (type := _dict.get('type')) is not None:
            args['type'] = type
        else:
            raise ValueError('Required property \'type\' not present in VPNGatewayConnectionIKEIdentityPrototypeVPNGatewayConnectionIKEIdentityFQDN JSON')
        if (value := _dict.get('value')) is not None:
            args['value'] = value
        else:
            raise ValueError('Required property \'value\' not present in VPNGatewayConnectionIKEIdentityPrototypeVPNGatewayConnectionIKEIdentityFQDN JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPNGatewayConnectionIKEIdentityPrototypeVPNGatewayConnectionIKEIdentityFQDN object from 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 VPNGatewayConnectionIKEIdentityPrototypeVPNGatewayConnectionIKEIdentityFQDN object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPNGatewayConnectionIKEIdentityPrototypeVPNGatewayConnectionIKEIdentityFQDN') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPNGatewayConnectionIKEIdentityPrototypeVPNGatewayConnectionIKEIdentityFQDN') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class TypeEnum(str, Enum):
        """
        The IKE identity type.
        """

        FQDN = 'fqdn'
        HOSTNAME = 'hostname'
        IPV4_ADDRESS = 'ipv4_address'
        KEY_ID = 'key_id'



class VPNGatewayConnectionIKEIdentityPrototypeVPNGatewayConnectionIKEIdentityHostname(VPNGatewayConnectionIKEIdentityPrototype):
    """
    VPNGatewayConnectionIKEIdentityPrototypeVPNGatewayConnectionIKEIdentityHostname.

    :param str type: The IKE identity type.
    :param str value: The IKE identity hostname value.
    """

    def __init__(
        self,
        type: str,
        value: str,
    ) -> None:
        """
        Initialize a VPNGatewayConnectionIKEIdentityPrototypeVPNGatewayConnectionIKEIdentityHostname object.

        :param str type: The IKE identity type.
        :param str value: The IKE identity hostname value.
        """
        # pylint: disable=super-init-not-called
        self.type = type
        self.value = value

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPNGatewayConnectionIKEIdentityPrototypeVPNGatewayConnectionIKEIdentityHostname':
        """Initialize a VPNGatewayConnectionIKEIdentityPrototypeVPNGatewayConnectionIKEIdentityHostname object from a json dictionary."""
        args = {}
        if (type := _dict.get('type')) is not None:
            args['type'] = type
        else:
            raise ValueError('Required property \'type\' not present in VPNGatewayConnectionIKEIdentityPrototypeVPNGatewayConnectionIKEIdentityHostname JSON')
        if (value := _dict.get('value')) is not None:
            args['value'] = value
        else:
            raise ValueError('Required property \'value\' not present in VPNGatewayConnectionIKEIdentityPrototypeVPNGatewayConnectionIKEIdentityHostname JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPNGatewayConnectionIKEIdentityPrototypeVPNGatewayConnectionIKEIdentityHostname object from 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 VPNGatewayConnectionIKEIdentityPrototypeVPNGatewayConnectionIKEIdentityHostname object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPNGatewayConnectionIKEIdentityPrototypeVPNGatewayConnectionIKEIdentityHostname') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPNGatewayConnectionIKEIdentityPrototypeVPNGatewayConnectionIKEIdentityHostname') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class TypeEnum(str, Enum):
        """
        The IKE identity type.
        """

        FQDN = 'fqdn'
        HOSTNAME = 'hostname'
        IPV4_ADDRESS = 'ipv4_address'
        KEY_ID = 'key_id'



class VPNGatewayConnectionIKEIdentityPrototypeVPNGatewayConnectionIKEIdentityIPv4(VPNGatewayConnectionIKEIdentityPrototype):
    """
    VPNGatewayConnectionIKEIdentityPrototypeVPNGatewayConnectionIKEIdentityIPv4.

    :param str type: The IKE identity type.
    :param str value: The IKE identity IPv4 address value.
    """

    def __init__(
        self,
        type: str,
        value: str,
    ) -> None:
        """
        Initialize a VPNGatewayConnectionIKEIdentityPrototypeVPNGatewayConnectionIKEIdentityIPv4 object.

        :param str type: The IKE identity type.
        :param str value: The IKE identity IPv4 address value.
        """
        # pylint: disable=super-init-not-called
        self.type = type
        self.value = value

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPNGatewayConnectionIKEIdentityPrototypeVPNGatewayConnectionIKEIdentityIPv4':
        """Initialize a VPNGatewayConnectionIKEIdentityPrototypeVPNGatewayConnectionIKEIdentityIPv4 object from a json dictionary."""
        args = {}
        if (type := _dict.get('type')) is not None:
            args['type'] = type
        else:
            raise ValueError('Required property \'type\' not present in VPNGatewayConnectionIKEIdentityPrototypeVPNGatewayConnectionIKEIdentityIPv4 JSON')
        if (value := _dict.get('value')) is not None:
            args['value'] = value
        else:
            raise ValueError('Required property \'value\' not present in VPNGatewayConnectionIKEIdentityPrototypeVPNGatewayConnectionIKEIdentityIPv4 JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPNGatewayConnectionIKEIdentityPrototypeVPNGatewayConnectionIKEIdentityIPv4 object from 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 VPNGatewayConnectionIKEIdentityPrototypeVPNGatewayConnectionIKEIdentityIPv4 object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPNGatewayConnectionIKEIdentityPrototypeVPNGatewayConnectionIKEIdentityIPv4') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPNGatewayConnectionIKEIdentityPrototypeVPNGatewayConnectionIKEIdentityIPv4') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class TypeEnum(str, Enum):
        """
        The IKE identity type.
        """

        FQDN = 'fqdn'
        HOSTNAME = 'hostname'
        IPV4_ADDRESS = 'ipv4_address'
        KEY_ID = 'key_id'



class VPNGatewayConnectionIKEIdentityPrototypeVPNGatewayConnectionIKEIdentityKeyID(VPNGatewayConnectionIKEIdentityPrototype):
    """
    VPNGatewayConnectionIKEIdentityPrototypeVPNGatewayConnectionIKEIdentityKeyID.

    :param str type: The IKE identity type.
    :param str value: The base64-encoded IKE identity key ID value.
    """

    def __init__(
        self,
        type: str,
        value: str,
    ) -> None:
        """
        Initialize a VPNGatewayConnectionIKEIdentityPrototypeVPNGatewayConnectionIKEIdentityKeyID object.

        :param str type: The IKE identity type.
        :param str value: The base64-encoded IKE identity key ID value.
        """
        # pylint: disable=super-init-not-called
        self.type = type
        self.value = value

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPNGatewayConnectionIKEIdentityPrototypeVPNGatewayConnectionIKEIdentityKeyID':
        """Initialize a VPNGatewayConnectionIKEIdentityPrototypeVPNGatewayConnectionIKEIdentityKeyID object from a json dictionary."""
        args = {}
        if (type := _dict.get('type')) is not None:
            args['type'] = type
        else:
            raise ValueError('Required property \'type\' not present in VPNGatewayConnectionIKEIdentityPrototypeVPNGatewayConnectionIKEIdentityKeyID JSON')
        if (value := _dict.get('value')) is not None:
            args['value'] = value
        else:
            raise ValueError('Required property \'value\' not present in VPNGatewayConnectionIKEIdentityPrototypeVPNGatewayConnectionIKEIdentityKeyID JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPNGatewayConnectionIKEIdentityPrototypeVPNGatewayConnectionIKEIdentityKeyID object from 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 VPNGatewayConnectionIKEIdentityPrototypeVPNGatewayConnectionIKEIdentityKeyID object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPNGatewayConnectionIKEIdentityPrototypeVPNGatewayConnectionIKEIdentityKeyID') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPNGatewayConnectionIKEIdentityPrototypeVPNGatewayConnectionIKEIdentityKeyID') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class TypeEnum(str, Enum):
        """
        The IKE identity type.
        """

        FQDN = 'fqdn'
        HOSTNAME = 'hostname'
        IPV4_ADDRESS = 'ipv4_address'
        KEY_ID = 'key_id'



class VPNGatewayConnectionIKEIdentityVPNGatewayConnectionIKEIdentityFQDN(VPNGatewayConnectionIKEIdentity):
    """
    VPNGatewayConnectionIKEIdentityVPNGatewayConnectionIKEIdentityFQDN.

    :param str type: The IKE identity type.
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :param str value: The IKE identity FQDN value.
    """

    def __init__(
        self,
        type: str,
        value: str,
    ) -> None:
        """
        Initialize a VPNGatewayConnectionIKEIdentityVPNGatewayConnectionIKEIdentityFQDN object.

        :param str type: The IKE identity type.
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :param str value: The IKE identity FQDN value.
        """
        # pylint: disable=super-init-not-called
        self.type = type
        self.value = value

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPNGatewayConnectionIKEIdentityVPNGatewayConnectionIKEIdentityFQDN':
        """Initialize a VPNGatewayConnectionIKEIdentityVPNGatewayConnectionIKEIdentityFQDN object from a json dictionary."""
        args = {}
        if (type := _dict.get('type')) is not None:
            args['type'] = type
        else:
            raise ValueError('Required property \'type\' not present in VPNGatewayConnectionIKEIdentityVPNGatewayConnectionIKEIdentityFQDN JSON')
        if (value := _dict.get('value')) is not None:
            args['value'] = value
        else:
            raise ValueError('Required property \'value\' not present in VPNGatewayConnectionIKEIdentityVPNGatewayConnectionIKEIdentityFQDN JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPNGatewayConnectionIKEIdentityVPNGatewayConnectionIKEIdentityFQDN object from 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 VPNGatewayConnectionIKEIdentityVPNGatewayConnectionIKEIdentityFQDN object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPNGatewayConnectionIKEIdentityVPNGatewayConnectionIKEIdentityFQDN') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPNGatewayConnectionIKEIdentityVPNGatewayConnectionIKEIdentityFQDN') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class TypeEnum(str, Enum):
        """
        The IKE identity type.
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        FQDN = 'fqdn'
        HOSTNAME = 'hostname'
        IPV4_ADDRESS = 'ipv4_address'
        KEY_ID = 'key_id'



class VPNGatewayConnectionIKEIdentityVPNGatewayConnectionIKEIdentityHostname(VPNGatewayConnectionIKEIdentity):
    """
    VPNGatewayConnectionIKEIdentityVPNGatewayConnectionIKEIdentityHostname.

    :param str type: The IKE identity type.
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :param str value: The IKE identity hostname value.
    """

    def __init__(
        self,
        type: str,
        value: str,
    ) -> None:
        """
        Initialize a VPNGatewayConnectionIKEIdentityVPNGatewayConnectionIKEIdentityHostname object.

        :param str type: The IKE identity type.
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :param str value: The IKE identity hostname value.
        """
        # pylint: disable=super-init-not-called
        self.type = type
        self.value = value

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPNGatewayConnectionIKEIdentityVPNGatewayConnectionIKEIdentityHostname':
        """Initialize a VPNGatewayConnectionIKEIdentityVPNGatewayConnectionIKEIdentityHostname object from a json dictionary."""
        args = {}
        if (type := _dict.get('type')) is not None:
            args['type'] = type
        else:
            raise ValueError('Required property \'type\' not present in VPNGatewayConnectionIKEIdentityVPNGatewayConnectionIKEIdentityHostname JSON')
        if (value := _dict.get('value')) is not None:
            args['value'] = value
        else:
            raise ValueError('Required property \'value\' not present in VPNGatewayConnectionIKEIdentityVPNGatewayConnectionIKEIdentityHostname JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPNGatewayConnectionIKEIdentityVPNGatewayConnectionIKEIdentityHostname object from 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 VPNGatewayConnectionIKEIdentityVPNGatewayConnectionIKEIdentityHostname object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPNGatewayConnectionIKEIdentityVPNGatewayConnectionIKEIdentityHostname') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPNGatewayConnectionIKEIdentityVPNGatewayConnectionIKEIdentityHostname') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class TypeEnum(str, Enum):
        """
        The IKE identity type.
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        FQDN = 'fqdn'
        HOSTNAME = 'hostname'
        IPV4_ADDRESS = 'ipv4_address'
        KEY_ID = 'key_id'



class VPNGatewayConnectionIKEIdentityVPNGatewayConnectionIKEIdentityIPv4(VPNGatewayConnectionIKEIdentity):
    """
    VPNGatewayConnectionIKEIdentityVPNGatewayConnectionIKEIdentityIPv4.

    :param str type: The IKE identity type.
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :param str value: The IKE identity IPv4 address value.
    """

    def __init__(
        self,
        type: str,
        value: str,
    ) -> None:
        """
        Initialize a VPNGatewayConnectionIKEIdentityVPNGatewayConnectionIKEIdentityIPv4 object.

        :param str type: The IKE identity type.
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :param str value: The IKE identity IPv4 address value.
        """
        # pylint: disable=super-init-not-called
        self.type = type
        self.value = value

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPNGatewayConnectionIKEIdentityVPNGatewayConnectionIKEIdentityIPv4':
        """Initialize a VPNGatewayConnectionIKEIdentityVPNGatewayConnectionIKEIdentityIPv4 object from a json dictionary."""
        args = {}
        if (type := _dict.get('type')) is not None:
            args['type'] = type
        else:
            raise ValueError('Required property \'type\' not present in VPNGatewayConnectionIKEIdentityVPNGatewayConnectionIKEIdentityIPv4 JSON')
        if (value := _dict.get('value')) is not None:
            args['value'] = value
        else:
            raise ValueError('Required property \'value\' not present in VPNGatewayConnectionIKEIdentityVPNGatewayConnectionIKEIdentityIPv4 JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPNGatewayConnectionIKEIdentityVPNGatewayConnectionIKEIdentityIPv4 object from 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 VPNGatewayConnectionIKEIdentityVPNGatewayConnectionIKEIdentityIPv4 object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPNGatewayConnectionIKEIdentityVPNGatewayConnectionIKEIdentityIPv4') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPNGatewayConnectionIKEIdentityVPNGatewayConnectionIKEIdentityIPv4') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class TypeEnum(str, Enum):
        """
        The IKE identity type.
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        FQDN = 'fqdn'
        HOSTNAME = 'hostname'
        IPV4_ADDRESS = 'ipv4_address'
        KEY_ID = 'key_id'



class VPNGatewayConnectionIKEIdentityVPNGatewayConnectionIKEIdentityKeyID(VPNGatewayConnectionIKEIdentity):
    """
    VPNGatewayConnectionIKEIdentityVPNGatewayConnectionIKEIdentityKeyID.

    :param str type: The IKE identity type.
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :param str value: The base64-encoded IKE identity key ID value.
    """

    def __init__(
        self,
        type: str,
        value: str,
    ) -> None:
        """
        Initialize a VPNGatewayConnectionIKEIdentityVPNGatewayConnectionIKEIdentityKeyID object.

        :param str type: The IKE identity type.
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :param str value: The base64-encoded IKE identity key ID value.
        """
        # pylint: disable=super-init-not-called
        self.type = type
        self.value = value

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPNGatewayConnectionIKEIdentityVPNGatewayConnectionIKEIdentityKeyID':
        """Initialize a VPNGatewayConnectionIKEIdentityVPNGatewayConnectionIKEIdentityKeyID object from a json dictionary."""
        args = {}
        if (type := _dict.get('type')) is not None:
            args['type'] = type
        else:
            raise ValueError('Required property \'type\' not present in VPNGatewayConnectionIKEIdentityVPNGatewayConnectionIKEIdentityKeyID JSON')
        if (value := _dict.get('value')) is not None:
            args['value'] = value
        else:
            raise ValueError('Required property \'value\' not present in VPNGatewayConnectionIKEIdentityVPNGatewayConnectionIKEIdentityKeyID JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPNGatewayConnectionIKEIdentityVPNGatewayConnectionIKEIdentityKeyID object from 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 VPNGatewayConnectionIKEIdentityVPNGatewayConnectionIKEIdentityKeyID object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPNGatewayConnectionIKEIdentityVPNGatewayConnectionIKEIdentityKeyID') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPNGatewayConnectionIKEIdentityVPNGatewayConnectionIKEIdentityKeyID') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class TypeEnum(str, Enum):
        """
        The IKE identity type.
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        FQDN = 'fqdn'
        HOSTNAME = 'hostname'
        IPV4_ADDRESS = 'ipv4_address'
        KEY_ID = 'key_id'



class VPNGatewayConnectionIKEPolicyPatchIKEPolicyIdentityByHref(VPNGatewayConnectionIKEPolicyPatch):
    """
    VPNGatewayConnectionIKEPolicyPatchIKEPolicyIdentityByHref.

    :param str href: The URL for this IKE policy.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a VPNGatewayConnectionIKEPolicyPatchIKEPolicyIdentityByHref object.

        :param str href: The URL for this IKE policy.
        """
        # 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 := _dict.get('href')) is not None:
            args['href'] = 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.

    :param 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 := _dict.get('id')) is not None:
            args['id'] = 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.

    :param str href: The URL for this IKE policy.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a VPNGatewayConnectionIKEPolicyPrototypeIKEPolicyIdentityByHref object.

        :param str href: The URL for this IKE policy.
        """
        # 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 := _dict.get('href')) is not None:
            args['href'] = 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.

    :param 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 := _dict.get('id')) is not None:
            args['id'] = 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.

    :param str href: The URL for this IPsec policy.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a VPNGatewayConnectionIPsecPolicyPatchIPsecPolicyIdentityByHref object.

        :param str href: The URL for this IPsec policy.
        """
        # 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 := _dict.get('href')) is not None:
            args['href'] = 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.

    :param 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 := _dict.get('id')) is not None:
            args['id'] = 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.

    :param str href: The URL for this IPsec policy.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a VPNGatewayConnectionIPsecPolicyPrototypeIPsecPolicyIdentityByHref object.

        :param str href: The URL for this IPsec policy.
        """
        # 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 := _dict.get('href')) is not None:
            args['href'] = 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.

    :param 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 := _dict.get('id')) is not None:
            args['id'] = 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 VPNGatewayConnectionPeerPatchVPNGatewayConnectionPolicyModePeerPatch(VPNGatewayConnectionPeerPatch):
    """
    The peer VPN gateway for this connection. If `peer.type` is `ipv4_address`, only
    `peer.address` may be specified. If `peer.type` is fqdn, only `peer.fqdn` may be
    specified.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a VPNGatewayConnectionPeerPatchVPNGatewayConnectionPolicyModePeerPatch object.

        """
        # pylint: disable=super-init-not-called
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['VPNGatewayConnectionPeerPatchVPNGatewayConnectionPolicyModePeerPatchVPNGatewayConnectionPolicyModePeerPatchVPNGatewayConnectionPeerAddressPatch', 'VPNGatewayConnectionPeerPatchVPNGatewayConnectionPolicyModePeerPatchVPNGatewayConnectionPolicyModePeerPatchVPNGatewayConnectionPeerFQDNPatch'])
        )
        raise Exception(msg)


class VPNGatewayConnectionPeerPatchVPNGatewayConnectionStaticRouteModePeerPatch(VPNGatewayConnectionPeerPatch):
    """
    The peer VPN gateway for this connection. If `peer.type` is `ipv4_address`, only
    `peer.address` may be specified. If `peer.type` is fqdn, only `peer.fqdn` may be
    specified.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a VPNGatewayConnectionPeerPatchVPNGatewayConnectionStaticRouteModePeerPatch object.

        """
        # pylint: disable=super-init-not-called
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['VPNGatewayConnectionPeerPatchVPNGatewayConnectionStaticRouteModePeerPatchVPNGatewayConnectionStaticRouteModePeerPatchVPNGatewayConnectionPeerAddressPatch', 'VPNGatewayConnectionPeerPatchVPNGatewayConnectionStaticRouteModePeerPatchVPNGatewayConnectionStaticRouteModePeerPatchVPNGatewayConnectionPeerFQDNPatch'])
        )
        raise Exception(msg)


class VPNGatewayConnectionPolicyMode(VPNGatewayConnection):
    """
    VPNGatewayConnectionPolicyMode.

    :param bool admin_state_up: If set to false, the VPN gateway connection is shut
          down.
    :param str authentication_mode: The authentication mode.
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :param datetime created_at: The date and time that this VPN gateway connection
          was created.
    :param VPNGatewayConnectionDPD dead_peer_detection:
    :param str establish_mode: The establish mode of the VPN gateway connection:
          - `bidirectional`: Either side of the VPN gateway can initiate IKE protocol
             negotiations or rekeying processes.
          - `peer_only`: Only the peer can initiate IKE protocol negotiations for this VPN
          gateway
             connection. Additionally, the peer is responsible for initiating the rekeying
          process
             after the connection is established. If rekeying does not occur, the VPN
          gateway
             connection will be brought down after its lifetime expires.
    :param str href: The URL for this VPN gateway connection.
    :param str id: The unique identifier for this VPN gateway connection.
    :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).
    :param str mode: The mode of the VPN gateway.
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :param str name: The name for this VPN gateway connection. The name is unique
          across all connections for the 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).
    :param VPNGatewayConnectionPolicyModeLocal local:
    :param VPNGatewayConnectionPolicyModePeer peer:
    """

    def __init__(
        self,
        admin_state_up: bool,
        authentication_mode: str,
        created_at: datetime,
        dead_peer_detection: 'VPNGatewayConnectionDPD',
        establish_mode: str,
        href: str,
        id: str,
        mode: str,
        name: str,
        psk: str,
        resource_type: str,
        status: str,
        status_reasons: List['VPNGatewayConnectionStatusReason'],
        local: 'VPNGatewayConnectionPolicyModeLocal',
        peer: 'VPNGatewayConnectionPolicyModePeer',
        *,
        ike_policy: Optional['IKEPolicyReference'] = None,
        ipsec_policy: Optional['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.
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :param datetime created_at: The date and time that this VPN gateway
               connection was created.
        :param VPNGatewayConnectionDPD dead_peer_detection:
        :param str establish_mode: The establish mode of the VPN gateway
               connection:
               - `bidirectional`: Either side of the VPN gateway can initiate IKE protocol
                  negotiations or rekeying processes.
               - `peer_only`: Only the peer can initiate IKE protocol negotiations for
               this VPN gateway
                  connection. Additionally, the peer is responsible for initiating the
               rekeying process
                  after the connection is established. If rekeying does not occur, the VPN
               gateway
                  connection will be brought down after its lifetime expires.
        :param str href: The URL for this VPN gateway connection.
        :param str id: The unique identifier for this VPN gateway connection.
        :param str mode: The mode of the VPN gateway.
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :param str name: The name for this VPN gateway connection. The name is
               unique across all connections for the 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).
        :param VPNGatewayConnectionPolicyModeLocal local:
        :param VPNGatewayConnectionPolicyModePeer peer:
        :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.establish_mode = establish_mode
        self.href = href
        self.id = id
        self.ike_policy = ike_policy
        self.ipsec_policy = ipsec_policy
        self.mode = mode
        self.name = name
        self.psk = psk
        self.resource_type = resource_type
        self.status = status
        self.status_reasons = status_reasons
        self.local = local
        self.peer = peer

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPNGatewayConnectionPolicyMode':
        """Initialize a VPNGatewayConnectionPolicyMode object from a json dictionary."""
        args = {}
        if (admin_state_up := _dict.get('admin_state_up')) is not None:
            args['admin_state_up'] = admin_state_up
        else:
            raise ValueError('Required property \'admin_state_up\' not present in VPNGatewayConnectionPolicyMode JSON')
        if (authentication_mode := _dict.get('authentication_mode')) is not None:
            args['authentication_mode'] = authentication_mode
        else:
            raise ValueError('Required property \'authentication_mode\' not present in VPNGatewayConnectionPolicyMode JSON')
        if (created_at := _dict.get('created_at')) is not None:
            args['created_at'] = string_to_datetime(created_at)
        else:
            raise ValueError('Required property \'created_at\' not present in VPNGatewayConnectionPolicyMode JSON')
        if (dead_peer_detection := _dict.get('dead_peer_detection')) is not None:
            args['dead_peer_detection'] = VPNGatewayConnectionDPD.from_dict(dead_peer_detection)
        else:
            raise ValueError('Required property \'dead_peer_detection\' not present in VPNGatewayConnectionPolicyMode JSON')
        if (establish_mode := _dict.get('establish_mode')) is not None:
            args['establish_mode'] = establish_mode
        else:
            raise ValueError('Required property \'establish_mode\' not present in VPNGatewayConnectionPolicyMode JSON')
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in VPNGatewayConnectionPolicyMode JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in VPNGatewayConnectionPolicyMode JSON')
        if (ike_policy := _dict.get('ike_policy')) is not None:
            args['ike_policy'] = IKEPolicyReference.from_dict(ike_policy)
        if (ipsec_policy := _dict.get('ipsec_policy')) is not None:
            args['ipsec_policy'] = IPsecPolicyReference.from_dict(ipsec_policy)
        if (mode := _dict.get('mode')) is not None:
            args['mode'] = mode
        else:
            raise ValueError('Required property \'mode\' not present in VPNGatewayConnectionPolicyMode JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in VPNGatewayConnectionPolicyMode JSON')
        if (psk := _dict.get('psk')) is not None:
            args['psk'] = psk
        else:
            raise ValueError('Required property \'psk\' not present in VPNGatewayConnectionPolicyMode JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = resource_type
        else:
            raise ValueError('Required property \'resource_type\' not present in VPNGatewayConnectionPolicyMode JSON')
        if (status := _dict.get('status')) is not None:
            args['status'] = status
        else:
            raise ValueError('Required property \'status\' not present in VPNGatewayConnectionPolicyMode JSON')
        if (status_reasons := _dict.get('status_reasons')) is not None:
            args['status_reasons'] = [VPNGatewayConnectionStatusReason.from_dict(v) for v in status_reasons]
        else:
            raise ValueError('Required property \'status_reasons\' not present in VPNGatewayConnectionPolicyMode JSON')
        if (local := _dict.get('local')) is not None:
            args['local'] = VPNGatewayConnectionPolicyModeLocal.from_dict(local)
        else:
            raise ValueError('Required property \'local\' not present in VPNGatewayConnectionPolicyMode JSON')
        if (peer := _dict.get('peer')) is not None:
            args['peer'] = peer
        else:
            raise ValueError('Required property \'peer\' 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, 'establish_mode') and self.establish_mode is not None:
            _dict['establish_mode'] = self.establish_mode
        if hasattr(self, 'href') and self.href 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, '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') and self.local is not None:
            if isinstance(self.local, dict):
                _dict['local'] = self.local
            else:
                _dict['local'] = self.local.to_dict()
        if hasattr(self, 'peer') and self.peer is not None:
            if isinstance(self.peer, dict):
                _dict['peer'] = self.peer
            else:
                _dict['peer'] = self.peer.to_dict()
        return _dict

    def _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.
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        PSK = 'psk'


    class EstablishModeEnum(str, Enum):
        """
        The establish mode of the VPN gateway connection:
        - `bidirectional`: Either side of the VPN gateway can initiate IKE protocol
           negotiations or rekeying processes.
        - `peer_only`: Only the peer can initiate IKE protocol negotiations for this VPN
        gateway
           connection. Additionally, the peer is responsible for initiating the rekeying
        process
           after the connection is established. If rekeying does not occur, the VPN
        gateway
           connection will be brought down after its lifetime expires.
        """

        BIDIRECTIONAL = 'bidirectional'
        PEER_ONLY = 'peer_only'


    class ModeEnum(str, Enum):
        """
        The mode of the VPN gateway.
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        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 VPNGatewayConnectionPolicyModePeerPrototypeVPNGatewayConnectionPeerByAddress(VPNGatewayConnectionPolicyModePeerPrototype):
    """
    VPNGatewayConnectionPolicyModePeerPrototypeVPNGatewayConnectionPeerByAddress.

    :param List[str] cidrs: The peer CIDRs for this VPN gateway connection.
    :param VPNGatewayConnectionIKEIdentityPrototype ike_identity: (optional) The
          peer IKE identity to use.
          If unspecified:
          - If `peer.address` is specified, the `type` will be `ipv4_address`, and the
          `value` will be `peer.address`.
          - If `peer.fqdn` is specified, the `type` will be `fqdn`, and the `value` will
          be `peer.fqdn`.
    :param str address: The IP address of the peer VPN gateway for this connection.
    """

    def __init__(
        self,
        cidrs: List[str],
        address: str,
        *,
        ike_identity: Optional['VPNGatewayConnectionIKEIdentityPrototype'] = None,
    ) -> None:
        """
        Initialize a VPNGatewayConnectionPolicyModePeerPrototypeVPNGatewayConnectionPeerByAddress object.

        :param List[str] cidrs: The peer CIDRs for this VPN gateway connection.
        :param str address: The IP address of the peer VPN gateway for this
               connection.
        :param VPNGatewayConnectionIKEIdentityPrototype ike_identity: (optional)
               The peer IKE identity to use.
               If unspecified:
               - If `peer.address` is specified, the `type` will be `ipv4_address`, and
               the `value` will be `peer.address`.
               - If `peer.fqdn` is specified, the `type` will be `fqdn`, and the `value`
               will be `peer.fqdn`.
        """
        # pylint: disable=super-init-not-called
        self.cidrs = cidrs
        self.ike_identity = ike_identity
        self.address = address

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPNGatewayConnectionPolicyModePeerPrototypeVPNGatewayConnectionPeerByAddress':
        """Initialize a VPNGatewayConnectionPolicyModePeerPrototypeVPNGatewayConnectionPeerByAddress object from a json dictionary."""
        args = {}
        if (cidrs := _dict.get('cidrs')) is not None:
            args['cidrs'] = cidrs
        else:
            raise ValueError('Required property \'cidrs\' not present in VPNGatewayConnectionPolicyModePeerPrototypeVPNGatewayConnectionPeerByAddress JSON')
        if (ike_identity := _dict.get('ike_identity')) is not None:
            args['ike_identity'] = ike_identity
        if (address := _dict.get('address')) is not None:
            args['address'] = address
        else:
            raise ValueError('Required property \'address\' not present in VPNGatewayConnectionPolicyModePeerPrototypeVPNGatewayConnectionPeerByAddress JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPNGatewayConnectionPolicyModePeerPrototypeVPNGatewayConnectionPeerByAddress object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'cidrs') and self.cidrs is not None:
            _dict['cidrs'] = self.cidrs
        if hasattr(self, 'ike_identity') and self.ike_identity is not None:
            if isinstance(self.ike_identity, dict):
                _dict['ike_identity'] = self.ike_identity
            else:
                _dict['ike_identity'] = self.ike_identity.to_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 VPNGatewayConnectionPolicyModePeerPrototypeVPNGatewayConnectionPeerByAddress object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPNGatewayConnectionPolicyModePeerPrototypeVPNGatewayConnectionPeerByAddress') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPNGatewayConnectionPolicyModePeerPrototypeVPNGatewayConnectionPeerByAddress') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VPNGatewayConnectionPolicyModePeerPrototypeVPNGatewayConnectionPeerByFQDN(VPNGatewayConnectionPolicyModePeerPrototype):
    """
    VPNGatewayConnectionPolicyModePeerPrototypeVPNGatewayConnectionPeerByFQDN.

    :param List[str] cidrs: The peer CIDRs for this VPN gateway connection.
    :param VPNGatewayConnectionIKEIdentityPrototype ike_identity: (optional) The
          peer IKE identity to use.
          If unspecified:
          - If `peer.address` is specified, the `type` will be `ipv4_address`, and the
          `value` will be `peer.address`.
          - If `peer.fqdn` is specified, the `type` will be `fqdn`, and the `value` will
          be `peer.fqdn`.
    :param str fqdn: The FQDN of the peer VPN gateway for this connection.
    """

    def __init__(
        self,
        cidrs: List[str],
        fqdn: str,
        *,
        ike_identity: Optional['VPNGatewayConnectionIKEIdentityPrototype'] = None,
    ) -> None:
        """
        Initialize a VPNGatewayConnectionPolicyModePeerPrototypeVPNGatewayConnectionPeerByFQDN object.

        :param List[str] cidrs: The peer CIDRs for this VPN gateway connection.
        :param str fqdn: The FQDN of the peer VPN gateway for this connection.
        :param VPNGatewayConnectionIKEIdentityPrototype ike_identity: (optional)
               The peer IKE identity to use.
               If unspecified:
               - If `peer.address` is specified, the `type` will be `ipv4_address`, and
               the `value` will be `peer.address`.
               - If `peer.fqdn` is specified, the `type` will be `fqdn`, and the `value`
               will be `peer.fqdn`.
        """
        # pylint: disable=super-init-not-called
        self.cidrs = cidrs
        self.ike_identity = ike_identity
        self.fqdn = fqdn

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPNGatewayConnectionPolicyModePeerPrototypeVPNGatewayConnectionPeerByFQDN':
        """Initialize a VPNGatewayConnectionPolicyModePeerPrototypeVPNGatewayConnectionPeerByFQDN object from a json dictionary."""
        args = {}
        if (cidrs := _dict.get('cidrs')) is not None:
            args['cidrs'] = cidrs
        else:
            raise ValueError('Required property \'cidrs\' not present in VPNGatewayConnectionPolicyModePeerPrototypeVPNGatewayConnectionPeerByFQDN JSON')
        if (ike_identity := _dict.get('ike_identity')) is not None:
            args['ike_identity'] = ike_identity
        if (fqdn := _dict.get('fqdn')) is not None:
            args['fqdn'] = fqdn
        else:
            raise ValueError('Required property \'fqdn\' not present in VPNGatewayConnectionPolicyModePeerPrototypeVPNGatewayConnectionPeerByFQDN JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPNGatewayConnectionPolicyModePeerPrototypeVPNGatewayConnectionPeerByFQDN object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'cidrs') and self.cidrs is not None:
            _dict['cidrs'] = self.cidrs
        if hasattr(self, 'ike_identity') and self.ike_identity is not None:
            if isinstance(self.ike_identity, dict):
                _dict['ike_identity'] = self.ike_identity
            else:
                _dict['ike_identity'] = self.ike_identity.to_dict()
        if hasattr(self, 'fqdn') and self.fqdn is not None:
            _dict['fqdn'] = self.fqdn
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VPNGatewayConnectionPolicyModePeerPrototypeVPNGatewayConnectionPeerByFQDN object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPNGatewayConnectionPolicyModePeerPrototypeVPNGatewayConnectionPeerByFQDN') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPNGatewayConnectionPolicyModePeerPrototypeVPNGatewayConnectionPeerByFQDN') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VPNGatewayConnectionPolicyModePeerVPNGatewayConnectionPeerByAddress(VPNGatewayConnectionPolicyModePeer):
    """
    VPNGatewayConnectionPolicyModePeerVPNGatewayConnectionPeerByAddress.

    :param List[str] cidrs: The peer CIDRs for this VPN gateway connection.
    :param VPNGatewayConnectionIKEIdentity ike_identity: The peer IKE identity.
    :param str type: Indicates whether `peer.address` or `peer.fqdn` is used.
    :param str address: The IP address of the peer VPN gateway for this connection.
    """

    def __init__(
        self,
        cidrs: List[str],
        ike_identity: 'VPNGatewayConnectionIKEIdentity',
        type: str,
        address: str,
    ) -> None:
        """
        Initialize a VPNGatewayConnectionPolicyModePeerVPNGatewayConnectionPeerByAddress object.

        :param List[str] cidrs: The peer CIDRs for this VPN gateway connection.
        :param VPNGatewayConnectionIKEIdentity ike_identity: The peer IKE identity.
        :param str type: Indicates whether `peer.address` or `peer.fqdn` is used.
        :param str address: The IP address of the peer VPN gateway for this
               connection.
        """
        # pylint: disable=super-init-not-called
        self.cidrs = cidrs
        self.ike_identity = ike_identity
        self.type = type
        self.address = address

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPNGatewayConnectionPolicyModePeerVPNGatewayConnectionPeerByAddress':
        """Initialize a VPNGatewayConnectionPolicyModePeerVPNGatewayConnectionPeerByAddress object from a json dictionary."""
        args = {}
        if (cidrs := _dict.get('cidrs')) is not None:
            args['cidrs'] = cidrs
        else:
            raise ValueError('Required property \'cidrs\' not present in VPNGatewayConnectionPolicyModePeerVPNGatewayConnectionPeerByAddress JSON')
        if (ike_identity := _dict.get('ike_identity')) is not None:
            args['ike_identity'] = ike_identity
        else:
            raise ValueError('Required property \'ike_identity\' not present in VPNGatewayConnectionPolicyModePeerVPNGatewayConnectionPeerByAddress JSON')
        if (type := _dict.get('type')) is not None:
            args['type'] = type
        else:
            raise ValueError('Required property \'type\' not present in VPNGatewayConnectionPolicyModePeerVPNGatewayConnectionPeerByAddress JSON')
        if (address := _dict.get('address')) is not None:
            args['address'] = address
        else:
            raise ValueError('Required property \'address\' not present in VPNGatewayConnectionPolicyModePeerVPNGatewayConnectionPeerByAddress JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPNGatewayConnectionPolicyModePeerVPNGatewayConnectionPeerByAddress object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'cidrs') and self.cidrs is not None:
            _dict['cidrs'] = self.cidrs
        if hasattr(self, 'ike_identity') and self.ike_identity is not None:
            if isinstance(self.ike_identity, dict):
                _dict['ike_identity'] = self.ike_identity
            else:
                _dict['ike_identity'] = self.ike_identity.to_dict()
        if hasattr(self, 'type') and self.type is not None:
            _dict['type'] = self.type
        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 VPNGatewayConnectionPolicyModePeerVPNGatewayConnectionPeerByAddress object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPNGatewayConnectionPolicyModePeerVPNGatewayConnectionPeerByAddress') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPNGatewayConnectionPolicyModePeerVPNGatewayConnectionPeerByAddress') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class TypeEnum(str, Enum):
        """
        Indicates whether `peer.address` or `peer.fqdn` is used.
        """

        ADDRESS = 'address'
        FQDN = 'fqdn'



class VPNGatewayConnectionPolicyModePeerVPNGatewayConnectionPeerByFQDN(VPNGatewayConnectionPolicyModePeer):
    """
    VPNGatewayConnectionPolicyModePeerVPNGatewayConnectionPeerByFQDN.

    :param List[str] cidrs: The peer CIDRs for this VPN gateway connection.
    :param VPNGatewayConnectionIKEIdentity ike_identity: The peer IKE identity.
    :param str type: Indicates whether `peer.address` or `peer.fqdn` is used.
    :param str fqdn: The FQDN of the peer VPN gateway for this connection.
    """

    def __init__(
        self,
        cidrs: List[str],
        ike_identity: 'VPNGatewayConnectionIKEIdentity',
        type: str,
        fqdn: str,
    ) -> None:
        """
        Initialize a VPNGatewayConnectionPolicyModePeerVPNGatewayConnectionPeerByFQDN object.

        :param List[str] cidrs: The peer CIDRs for this VPN gateway connection.
        :param VPNGatewayConnectionIKEIdentity ike_identity: The peer IKE identity.
        :param str type: Indicates whether `peer.address` or `peer.fqdn` is used.
        :param str fqdn: The FQDN of the peer VPN gateway for this connection.
        """
        # pylint: disable=super-init-not-called
        self.cidrs = cidrs
        self.ike_identity = ike_identity
        self.type = type
        self.fqdn = fqdn

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPNGatewayConnectionPolicyModePeerVPNGatewayConnectionPeerByFQDN':
        """Initialize a VPNGatewayConnectionPolicyModePeerVPNGatewayConnectionPeerByFQDN object from a json dictionary."""
        args = {}
        if (cidrs := _dict.get('cidrs')) is not None:
            args['cidrs'] = cidrs
        else:
            raise ValueError('Required property \'cidrs\' not present in VPNGatewayConnectionPolicyModePeerVPNGatewayConnectionPeerByFQDN JSON')
        if (ike_identity := _dict.get('ike_identity')) is not None:
            args['ike_identity'] = ike_identity
        else:
            raise ValueError('Required property \'ike_identity\' not present in VPNGatewayConnectionPolicyModePeerVPNGatewayConnectionPeerByFQDN JSON')
        if (type := _dict.get('type')) is not None:
            args['type'] = type
        else:
            raise ValueError('Required property \'type\' not present in VPNGatewayConnectionPolicyModePeerVPNGatewayConnectionPeerByFQDN JSON')
        if (fqdn := _dict.get('fqdn')) is not None:
            args['fqdn'] = fqdn
        else:
            raise ValueError('Required property \'fqdn\' not present in VPNGatewayConnectionPolicyModePeerVPNGatewayConnectionPeerByFQDN JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPNGatewayConnectionPolicyModePeerVPNGatewayConnectionPeerByFQDN object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'cidrs') and self.cidrs is not None:
            _dict['cidrs'] = self.cidrs
        if hasattr(self, 'ike_identity') and self.ike_identity is not None:
            if isinstance(self.ike_identity, dict):
                _dict['ike_identity'] = self.ike_identity
            else:
                _dict['ike_identity'] = self.ike_identity.to_dict()
        if hasattr(self, 'type') and self.type is not None:
            _dict['type'] = self.type
        if hasattr(self, 'fqdn') and self.fqdn is not None:
            _dict['fqdn'] = self.fqdn
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VPNGatewayConnectionPolicyModePeerVPNGatewayConnectionPeerByFQDN object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPNGatewayConnectionPolicyModePeerVPNGatewayConnectionPeerByFQDN') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPNGatewayConnectionPolicyModePeerVPNGatewayConnectionPeerByFQDN') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class TypeEnum(str, Enum):
        """
        Indicates whether `peer.address` or `peer.fqdn` is used.
        """

        ADDRESS = 'address'
        FQDN = 'fqdn'



class VPNGatewayConnectionPrototypeVPNGatewayConnectionPolicyModePrototype(VPNGatewayConnectionPrototype):
    """
    VPNGatewayConnectionPrototypeVPNGatewayConnectionPolicyModePrototype.

    :param bool admin_state_up: (optional) If set to false, the VPN gateway
          connection is shut down.
    :param VPNGatewayConnectionDPDPrototype dead_peer_detection: (optional)
    :param str establish_mode: (optional) The establish mode of the VPN gateway
          connection:
          - `bidirectional`: Either side of the VPN gateway can initiate IKE protocol
             negotiations or rekeying processes.
          - `peer_only`: Only the peer can initiate IKE protocol negotiations for this VPN
          gateway
             connection. Additionally, the peer is responsible for initiating the rekeying
          process
             after the connection is established. If rekeying does not occur, the VPN
          gateway
             connection will be brought down after its lifetime expires.
    :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 psk: The pre-shared key.
    :param VPNGatewayConnectionPolicyModeLocalPrototype local:
    :param VPNGatewayConnectionPolicyModePeerPrototype peer:
    """

    def __init__(
        self,
        psk: str,
        local: 'VPNGatewayConnectionPolicyModeLocalPrototype',
        peer: 'VPNGatewayConnectionPolicyModePeerPrototype',
        *,
        admin_state_up: Optional[bool] = None,
        dead_peer_detection: Optional['VPNGatewayConnectionDPDPrototype'] = None,
        establish_mode: Optional[str] = None,
        ike_policy: Optional['VPNGatewayConnectionIKEPolicyPrototype'] = None,
        ipsec_policy: Optional['VPNGatewayConnectionIPsecPolicyPrototype'] = None,
        name: Optional[str] = None,
    ) -> None:
        """
        Initialize a VPNGatewayConnectionPrototypeVPNGatewayConnectionPolicyModePrototype object.

        :param str psk: The pre-shared key.
        :param VPNGatewayConnectionPolicyModeLocalPrototype local:
        :param VPNGatewayConnectionPolicyModePeerPrototype peer:
        :param bool admin_state_up: (optional) If set to false, the VPN gateway
               connection is shut down.
        :param VPNGatewayConnectionDPDPrototype dead_peer_detection: (optional)
        :param str establish_mode: (optional) The establish mode of the VPN gateway
               connection:
               - `bidirectional`: Either side of the VPN gateway can initiate IKE protocol
                  negotiations or rekeying processes.
               - `peer_only`: Only the peer can initiate IKE protocol negotiations for
               this VPN gateway
                  connection. Additionally, the peer is responsible for initiating the
               rekeying process
                  after the connection is established. If rekeying does not occur, the VPN
               gateway
                  connection will be brought down after its lifetime expires.
        :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.establish_mode = establish_mode
        self.ike_policy = ike_policy
        self.ipsec_policy = ipsec_policy
        self.name = name
        self.psk = psk
        self.local = local
        self.peer = peer

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPNGatewayConnectionPrototypeVPNGatewayConnectionPolicyModePrototype':
        """Initialize a VPNGatewayConnectionPrototypeVPNGatewayConnectionPolicyModePrototype object from a json dictionary."""
        args = {}
        if (admin_state_up := _dict.get('admin_state_up')) is not None:
            args['admin_state_up'] = admin_state_up
        if (dead_peer_detection := _dict.get('dead_peer_detection')) is not None:
            args['dead_peer_detection'] = VPNGatewayConnectionDPDPrototype.from_dict(dead_peer_detection)
        if (establish_mode := _dict.get('establish_mode')) is not None:
            args['establish_mode'] = establish_mode
        if (ike_policy := _dict.get('ike_policy')) is not None:
            args['ike_policy'] = ike_policy
        if (ipsec_policy := _dict.get('ipsec_policy')) is not None:
            args['ipsec_policy'] = ipsec_policy
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        if (psk := _dict.get('psk')) is not None:
            args['psk'] = psk
        else:
            raise ValueError('Required property \'psk\' not present in VPNGatewayConnectionPrototypeVPNGatewayConnectionPolicyModePrototype JSON')
        if (local := _dict.get('local')) is not None:
            args['local'] = VPNGatewayConnectionPolicyModeLocalPrototype.from_dict(local)
        else:
            raise ValueError('Required property \'local\' not present in VPNGatewayConnectionPrototypeVPNGatewayConnectionPolicyModePrototype JSON')
        if (peer := _dict.get('peer')) is not None:
            args['peer'] = peer
        else:
            raise ValueError('Required property \'peer\' 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, 'establish_mode') and self.establish_mode is not None:
            _dict['establish_mode'] = self.establish_mode
        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, 'psk') and self.psk is not None:
            _dict['psk'] = self.psk
        if hasattr(self, 'local') and self.local is not None:
            if isinstance(self.local, dict):
                _dict['local'] = self.local
            else:
                _dict['local'] = self.local.to_dict()
        if hasattr(self, 'peer') and self.peer is not None:
            if isinstance(self.peer, dict):
                _dict['peer'] = self.peer
            else:
                _dict['peer'] = self.peer.to_dict()
        return _dict

    def _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 EstablishModeEnum(str, Enum):
        """
        The establish mode of the VPN gateway connection:
        - `bidirectional`: Either side of the VPN gateway can initiate IKE protocol
           negotiations or rekeying processes.
        - `peer_only`: Only the peer can initiate IKE protocol negotiations for this VPN
        gateway
           connection. Additionally, the peer is responsible for initiating the rekeying
        process
           after the connection is established. If rekeying does not occur, the VPN
        gateway
           connection will be brought down after its lifetime expires.
        """

        BIDIRECTIONAL = 'bidirectional'
        PEER_ONLY = 'peer_only'



class VPNGatewayConnectionPrototypeVPNGatewayConnectionStaticRouteModePrototype(VPNGatewayConnectionPrototype):
    """
    VPNGatewayConnectionPrototypeVPNGatewayConnectionStaticRouteModePrototype.

    :param bool admin_state_up: (optional) If set to false, the VPN gateway
          connection is shut down.
    :param VPNGatewayConnectionDPDPrototype dead_peer_detection: (optional)
    :param str establish_mode: (optional) The establish mode of the VPN gateway
          connection:
          - `bidirectional`: Either side of the VPN gateway can initiate IKE protocol
             negotiations or rekeying processes.
          - `peer_only`: Only the peer can initiate IKE protocol negotiations for this VPN
          gateway
             connection. Additionally, the peer is responsible for initiating the rekeying
          process
             after the connection is established. If rekeying does not occur, the VPN
          gateway
             connection will be brought down after its lifetime expires.
    :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 psk: The pre-shared key.
    :param bool distribute_traffic: (optional) Indicates whether the traffic is
          distributed between the `up` tunnels of the VPN gateway connection when the VPC
          route's next hop is a VPN connection. If `false`, the traffic is only routed
          through the `up` tunnel with the lower `public_ip` address. Before enabling it
          on VPN connections to on-prem private networks, review
          [distributing traffic
          restrictions](https://cloud.ibm.com/docs/vpc?topic=vpc-vpn-limitations#distributing-traffic-restrictions).
    :param VPNGatewayConnectionStaticRouteModeLocalPrototype local: (optional)
    :param VPNGatewayConnectionStaticRouteModePeerPrototype peer:
    :param str routing_protocol: (optional) Routing protocols are disabled for this
          VPN gateway connection.
    """

    def __init__(
        self,
        psk: str,
        peer: 'VPNGatewayConnectionStaticRouteModePeerPrototype',
        *,
        admin_state_up: Optional[bool] = None,
        dead_peer_detection: Optional['VPNGatewayConnectionDPDPrototype'] = None,
        establish_mode: Optional[str] = None,
        ike_policy: Optional['VPNGatewayConnectionIKEPolicyPrototype'] = None,
        ipsec_policy: Optional['VPNGatewayConnectionIPsecPolicyPrototype'] = None,
        name: Optional[str] = None,
        distribute_traffic: Optional[bool] = None,
        local: Optional['VPNGatewayConnectionStaticRouteModeLocalPrototype'] = None,
        routing_protocol: Optional[str] = None,
    ) -> None:
        """
        Initialize a VPNGatewayConnectionPrototypeVPNGatewayConnectionStaticRouteModePrototype object.

        :param str psk: The pre-shared key.
        :param VPNGatewayConnectionStaticRouteModePeerPrototype peer:
        :param bool admin_state_up: (optional) If set to false, the VPN gateway
               connection is shut down.
        :param VPNGatewayConnectionDPDPrototype dead_peer_detection: (optional)
        :param str establish_mode: (optional) The establish mode of the VPN gateway
               connection:
               - `bidirectional`: Either side of the VPN gateway can initiate IKE protocol
                  negotiations or rekeying processes.
               - `peer_only`: Only the peer can initiate IKE protocol negotiations for
               this VPN gateway
                  connection. Additionally, the peer is responsible for initiating the
               rekeying process
                  after the connection is established. If rekeying does not occur, the VPN
               gateway
                  connection will be brought down after its lifetime expires.
        :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 bool distribute_traffic: (optional) Indicates whether the traffic is
               distributed between the `up` tunnels of the VPN gateway connection when the
               VPC route's next hop is a VPN connection. If `false`, the traffic is only
               routed through the `up` tunnel with the lower `public_ip` address. Before
               enabling it on VPN connections to on-prem private networks, review
               [distributing traffic
               restrictions](https://cloud.ibm.com/docs/vpc?topic=vpc-vpn-limitations#distributing-traffic-restrictions).
        :param VPNGatewayConnectionStaticRouteModeLocalPrototype local: (optional)
        :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.establish_mode = establish_mode
        self.ike_policy = ike_policy
        self.ipsec_policy = ipsec_policy
        self.name = name
        self.psk = psk
        self.distribute_traffic = distribute_traffic
        self.local = local
        self.peer = peer
        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 := _dict.get('admin_state_up')) is not None:
            args['admin_state_up'] = admin_state_up
        if (dead_peer_detection := _dict.get('dead_peer_detection')) is not None:
            args['dead_peer_detection'] = VPNGatewayConnectionDPDPrototype.from_dict(dead_peer_detection)
        if (establish_mode := _dict.get('establish_mode')) is not None:
            args['establish_mode'] = establish_mode
        if (ike_policy := _dict.get('ike_policy')) is not None:
            args['ike_policy'] = ike_policy
        if (ipsec_policy := _dict.get('ipsec_policy')) is not None:
            args['ipsec_policy'] = ipsec_policy
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        if (psk := _dict.get('psk')) is not None:
            args['psk'] = psk
        else:
            raise ValueError('Required property \'psk\' not present in VPNGatewayConnectionPrototypeVPNGatewayConnectionStaticRouteModePrototype JSON')
        if (distribute_traffic := _dict.get('distribute_traffic')) is not None:
            args['distribute_traffic'] = distribute_traffic
        if (local := _dict.get('local')) is not None:
            args['local'] = VPNGatewayConnectionStaticRouteModeLocalPrototype.from_dict(local)
        if (peer := _dict.get('peer')) is not None:
            args['peer'] = peer
        else:
            raise ValueError('Required property \'peer\' not present in VPNGatewayConnectionPrototypeVPNGatewayConnectionStaticRouteModePrototype JSON')
        if (routing_protocol := _dict.get('routing_protocol')) is not None:
            args['routing_protocol'] = 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, 'establish_mode') and self.establish_mode is not None:
            _dict['establish_mode'] = self.establish_mode
        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, 'psk') and self.psk is not None:
            _dict['psk'] = self.psk
        if hasattr(self, 'distribute_traffic') and self.distribute_traffic is not None:
            _dict['distribute_traffic'] = self.distribute_traffic
        if hasattr(self, 'local') and self.local is not None:
            if isinstance(self.local, dict):
                _dict['local'] = self.local
            else:
                _dict['local'] = self.local.to_dict()
        if hasattr(self, 'peer') and self.peer is not None:
            if isinstance(self.peer, dict):
                _dict['peer'] = self.peer
            else:
                _dict['peer'] = self.peer.to_dict()
        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 EstablishModeEnum(str, Enum):
        """
        The establish mode of the VPN gateway connection:
        - `bidirectional`: Either side of the VPN gateway can initiate IKE protocol
           negotiations or rekeying processes.
        - `peer_only`: Only the peer can initiate IKE protocol negotiations for this VPN
        gateway
           connection. Additionally, the peer is responsible for initiating the rekeying
        process
           after the connection is established. If rekeying does not occur, the VPN
        gateway
           connection will be brought down after its lifetime expires.
        """

        BIDIRECTIONAL = 'bidirectional'
        PEER_ONLY = 'peer_only'


    class RoutingProtocolEnum(str, Enum):
        """
        Routing protocols are disabled for this VPN gateway connection.
        """

        NONE = 'none'



class VPNGatewayConnectionRouteMode(VPNGatewayConnection):
    """
    VPNGatewayConnectionRouteMode.

    :param bool admin_state_up: If set to false, the VPN gateway connection is shut
          down.
    :param str authentication_mode: The authentication mode.
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :param datetime created_at: The date and time that this VPN gateway connection
          was created.
    :param VPNGatewayConnectionDPD dead_peer_detection:
    :param str establish_mode: The establish mode of the VPN gateway connection:
          - `bidirectional`: Either side of the VPN gateway can initiate IKE protocol
             negotiations or rekeying processes.
          - `peer_only`: Only the peer can initiate IKE protocol negotiations for this VPN
          gateway
             connection. Additionally, the peer is responsible for initiating the rekeying
          process
             after the connection is established. If rekeying does not occur, the VPN
          gateway
             connection will be brought down after its lifetime expires.
    :param str href: The URL for this VPN gateway connection.
    :param str id: The unique identifier for this VPN gateway connection.
    :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).
    :param str mode: The mode of the VPN gateway.
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :param str name: The name for this VPN gateway connection. The name is unique
          across all connections for the 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).
    """

    def __init__(
        self,
        admin_state_up: bool,
        authentication_mode: str,
        created_at: datetime,
        dead_peer_detection: 'VPNGatewayConnectionDPD',
        establish_mode: str,
        href: str,
        id: str,
        mode: str,
        name: str,
        psk: str,
        resource_type: str,
        status: str,
        status_reasons: List['VPNGatewayConnectionStatusReason'],
        *,
        ike_policy: Optional['IKEPolicyReference'] = None,
        ipsec_policy: Optional['IPsecPolicyReference'] = None,
    ) -> None:
        """
        Initialize a VPNGatewayConnectionRouteMode object.

        :param bool admin_state_up: If set to false, the VPN gateway connection is
               shut down.
        :param str authentication_mode: The authentication mode.
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :param datetime created_at: The date and time that this VPN gateway
               connection was created.
        :param VPNGatewayConnectionDPD dead_peer_detection:
        :param str establish_mode: The establish mode of the VPN gateway
               connection:
               - `bidirectional`: Either side of the VPN gateway can initiate IKE protocol
                  negotiations or rekeying processes.
               - `peer_only`: Only the peer can initiate IKE protocol negotiations for
               this VPN gateway
                  connection. Additionally, the peer is responsible for initiating the
               rekeying process
                  after the connection is established. If rekeying does not occur, the VPN
               gateway
                  connection will be brought down after its lifetime expires.
        :param str href: The URL for this VPN gateway connection.
        :param str id: The unique identifier for this VPN gateway connection.
        :param str mode: The mode of the VPN gateway.
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :param str name: The name for this VPN gateway connection. The name is
               unique across all connections for the 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).
        :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
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['VPNGatewayConnectionRouteModeVPNGatewayConnectionStaticRouteMode'])
        )
        raise Exception(msg)

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPNGatewayConnectionRouteMode':
        """Initialize a VPNGatewayConnectionRouteMode 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 'VPNGatewayConnectionRouteMode'. The discriminator value should map to a valid subclass: {1}".format(
            ", ".join(['VPNGatewayConnectionRouteModeVPNGatewayConnectionStaticRouteMode'])
        )
        raise Exception(msg)

    @classmethod
    def _from_dict(cls, _dict: Dict):
        """Initialize a VPNGatewayConnectionRouteMode object from a json dictionary."""
        return cls.from_dict(_dict)

    @classmethod
    def _get_class_by_discriminator(cls, _dict: Dict) -> object:
        mapping = {}
        mapping['none'] = 'VPNGatewayConnectionRouteModeVPNGatewayConnectionStaticRouteMode'
        disc_value = _dict.get('routing_protocol')
        if disc_value is None:
            raise ValueError('Discriminator property \'routing_protocol\' not found in VPNGatewayConnectionRouteMode 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 AuthenticationModeEnum(str, Enum):
        """
        The authentication mode.
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        PSK = 'psk'


    class EstablishModeEnum(str, Enum):
        """
        The establish mode of the VPN gateway connection:
        - `bidirectional`: Either side of the VPN gateway can initiate IKE protocol
           negotiations or rekeying processes.
        - `peer_only`: Only the peer can initiate IKE protocol negotiations for this VPN
        gateway
           connection. Additionally, the peer is responsible for initiating the rekeying
        process
           after the connection is established. If rekeying does not occur, the VPN
        gateway
           connection will be brought down after its lifetime expires.
        """

        BIDIRECTIONAL = 'bidirectional'
        PEER_ONLY = 'peer_only'


    class ModeEnum(str, Enum):
        """
        The mode of the VPN gateway.
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        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 VPNGatewayConnectionStaticRouteModePeerPrototypeVPNGatewayConnectionPeerByAddress(VPNGatewayConnectionStaticRouteModePeerPrototype):
    """
    VPNGatewayConnectionStaticRouteModePeerPrototypeVPNGatewayConnectionPeerByAddress.

    :param VPNGatewayConnectionIKEIdentityPrototype ike_identity: (optional) The
          peer IKE identity to use.
          If unspecified:
          - If `peer.address` is specified, the `type` will be `ipv4_address`, and the
          `value` will be `peer.address`.
          - If `peer.fqdn` is specified, the `type` will be `fqdn`, and the `value` will
          be `peer.fqdn`.
    :param str address: The IP address of the peer VPN gateway for this connection.
    """

    def __init__(
        self,
        address: str,
        *,
        ike_identity: Optional['VPNGatewayConnectionIKEIdentityPrototype'] = None,
    ) -> None:
        """
        Initialize a VPNGatewayConnectionStaticRouteModePeerPrototypeVPNGatewayConnectionPeerByAddress object.

        :param str address: The IP address of the peer VPN gateway for this
               connection.
        :param VPNGatewayConnectionIKEIdentityPrototype ike_identity: (optional)
               The peer IKE identity to use.
               If unspecified:
               - If `peer.address` is specified, the `type` will be `ipv4_address`, and
               the `value` will be `peer.address`.
               - If `peer.fqdn` is specified, the `type` will be `fqdn`, and the `value`
               will be `peer.fqdn`.
        """
        # pylint: disable=super-init-not-called
        self.ike_identity = ike_identity
        self.address = address

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPNGatewayConnectionStaticRouteModePeerPrototypeVPNGatewayConnectionPeerByAddress':
        """Initialize a VPNGatewayConnectionStaticRouteModePeerPrototypeVPNGatewayConnectionPeerByAddress object from a json dictionary."""
        args = {}
        if (ike_identity := _dict.get('ike_identity')) is not None:
            args['ike_identity'] = ike_identity
        if (address := _dict.get('address')) is not None:
            args['address'] = address
        else:
            raise ValueError('Required property \'address\' not present in VPNGatewayConnectionStaticRouteModePeerPrototypeVPNGatewayConnectionPeerByAddress JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPNGatewayConnectionStaticRouteModePeerPrototypeVPNGatewayConnectionPeerByAddress object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'ike_identity') and self.ike_identity is not None:
            if isinstance(self.ike_identity, dict):
                _dict['ike_identity'] = self.ike_identity
            else:
                _dict['ike_identity'] = self.ike_identity.to_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 VPNGatewayConnectionStaticRouteModePeerPrototypeVPNGatewayConnectionPeerByAddress object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPNGatewayConnectionStaticRouteModePeerPrototypeVPNGatewayConnectionPeerByAddress') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPNGatewayConnectionStaticRouteModePeerPrototypeVPNGatewayConnectionPeerByAddress') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VPNGatewayConnectionStaticRouteModePeerPrototypeVPNGatewayConnectionPeerByFQDN(VPNGatewayConnectionStaticRouteModePeerPrototype):
    """
    VPNGatewayConnectionStaticRouteModePeerPrototypeVPNGatewayConnectionPeerByFQDN.

    :param VPNGatewayConnectionIKEIdentityPrototype ike_identity: (optional) The
          peer IKE identity to use.
          If unspecified:
          - If `peer.address` is specified, the `type` will be `ipv4_address`, and the
          `value` will be `peer.address`.
          - If `peer.fqdn` is specified, the `type` will be `fqdn`, and the `value` will
          be `peer.fqdn`.
    :param str fqdn: The FQDN of the peer VPN gateway for this connection.
    """

    def __init__(
        self,
        fqdn: str,
        *,
        ike_identity: Optional['VPNGatewayConnectionIKEIdentityPrototype'] = None,
    ) -> None:
        """
        Initialize a VPNGatewayConnectionStaticRouteModePeerPrototypeVPNGatewayConnectionPeerByFQDN object.

        :param str fqdn: The FQDN of the peer VPN gateway for this connection.
        :param VPNGatewayConnectionIKEIdentityPrototype ike_identity: (optional)
               The peer IKE identity to use.
               If unspecified:
               - If `peer.address` is specified, the `type` will be `ipv4_address`, and
               the `value` will be `peer.address`.
               - If `peer.fqdn` is specified, the `type` will be `fqdn`, and the `value`
               will be `peer.fqdn`.
        """
        # pylint: disable=super-init-not-called
        self.ike_identity = ike_identity
        self.fqdn = fqdn

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPNGatewayConnectionStaticRouteModePeerPrototypeVPNGatewayConnectionPeerByFQDN':
        """Initialize a VPNGatewayConnectionStaticRouteModePeerPrototypeVPNGatewayConnectionPeerByFQDN object from a json dictionary."""
        args = {}
        if (ike_identity := _dict.get('ike_identity')) is not None:
            args['ike_identity'] = ike_identity
        if (fqdn := _dict.get('fqdn')) is not None:
            args['fqdn'] = fqdn
        else:
            raise ValueError('Required property \'fqdn\' not present in VPNGatewayConnectionStaticRouteModePeerPrototypeVPNGatewayConnectionPeerByFQDN JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPNGatewayConnectionStaticRouteModePeerPrototypeVPNGatewayConnectionPeerByFQDN object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'ike_identity') and self.ike_identity is not None:
            if isinstance(self.ike_identity, dict):
                _dict['ike_identity'] = self.ike_identity
            else:
                _dict['ike_identity'] = self.ike_identity.to_dict()
        if hasattr(self, 'fqdn') and self.fqdn is not None:
            _dict['fqdn'] = self.fqdn
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VPNGatewayConnectionStaticRouteModePeerPrototypeVPNGatewayConnectionPeerByFQDN object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPNGatewayConnectionStaticRouteModePeerPrototypeVPNGatewayConnectionPeerByFQDN') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPNGatewayConnectionStaticRouteModePeerPrototypeVPNGatewayConnectionPeerByFQDN') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VPNGatewayConnectionStaticRouteModePeerVPNGatewayConnectionPeerByAddress(VPNGatewayConnectionStaticRouteModePeer):
    """
    VPNGatewayConnectionStaticRouteModePeerVPNGatewayConnectionPeerByAddress.

    :param VPNGatewayConnectionIKEIdentity ike_identity: The peer IKE identity.
    :param str type: Indicates whether `peer.address` or `peer.fqdn` is used.
    :param str address: The IP address of the peer VPN gateway for this connection.
    """

    def __init__(
        self,
        ike_identity: 'VPNGatewayConnectionIKEIdentity',
        type: str,
        address: str,
    ) -> None:
        """
        Initialize a VPNGatewayConnectionStaticRouteModePeerVPNGatewayConnectionPeerByAddress object.

        :param VPNGatewayConnectionIKEIdentity ike_identity: The peer IKE identity.
        :param str type: Indicates whether `peer.address` or `peer.fqdn` is used.
        :param str address: The IP address of the peer VPN gateway for this
               connection.
        """
        # pylint: disable=super-init-not-called
        self.ike_identity = ike_identity
        self.type = type
        self.address = address

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPNGatewayConnectionStaticRouteModePeerVPNGatewayConnectionPeerByAddress':
        """Initialize a VPNGatewayConnectionStaticRouteModePeerVPNGatewayConnectionPeerByAddress object from a json dictionary."""
        args = {}
        if (ike_identity := _dict.get('ike_identity')) is not None:
            args['ike_identity'] = ike_identity
        else:
            raise ValueError('Required property \'ike_identity\' not present in VPNGatewayConnectionStaticRouteModePeerVPNGatewayConnectionPeerByAddress JSON')
        if (type := _dict.get('type')) is not None:
            args['type'] = type
        else:
            raise ValueError('Required property \'type\' not present in VPNGatewayConnectionStaticRouteModePeerVPNGatewayConnectionPeerByAddress JSON')
        if (address := _dict.get('address')) is not None:
            args['address'] = address
        else:
            raise ValueError('Required property \'address\' not present in VPNGatewayConnectionStaticRouteModePeerVPNGatewayConnectionPeerByAddress JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPNGatewayConnectionStaticRouteModePeerVPNGatewayConnectionPeerByAddress object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'ike_identity') and self.ike_identity is not None:
            if isinstance(self.ike_identity, dict):
                _dict['ike_identity'] = self.ike_identity
            else:
                _dict['ike_identity'] = self.ike_identity.to_dict()
        if hasattr(self, 'type') and self.type is not None:
            _dict['type'] = self.type
        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 VPNGatewayConnectionStaticRouteModePeerVPNGatewayConnectionPeerByAddress object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPNGatewayConnectionStaticRouteModePeerVPNGatewayConnectionPeerByAddress') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPNGatewayConnectionStaticRouteModePeerVPNGatewayConnectionPeerByAddress') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class TypeEnum(str, Enum):
        """
        Indicates whether `peer.address` or `peer.fqdn` is used.
        """

        ADDRESS = 'address'
        FQDN = 'fqdn'



class VPNGatewayConnectionStaticRouteModePeerVPNGatewayConnectionPeerByFQDN(VPNGatewayConnectionStaticRouteModePeer):
    """
    VPNGatewayConnectionStaticRouteModePeerVPNGatewayConnectionPeerByFQDN.

    :param VPNGatewayConnectionIKEIdentity ike_identity: The peer IKE identity.
    :param str type: Indicates whether `peer.address` or `peer.fqdn` is used.
    :param str fqdn: The FQDN of the peer VPN gateway for this connection.
    """

    def __init__(
        self,
        ike_identity: 'VPNGatewayConnectionIKEIdentity',
        type: str,
        fqdn: str,
    ) -> None:
        """
        Initialize a VPNGatewayConnectionStaticRouteModePeerVPNGatewayConnectionPeerByFQDN object.

        :param VPNGatewayConnectionIKEIdentity ike_identity: The peer IKE identity.
        :param str type: Indicates whether `peer.address` or `peer.fqdn` is used.
        :param str fqdn: The FQDN of the peer VPN gateway for this connection.
        """
        # pylint: disable=super-init-not-called
        self.ike_identity = ike_identity
        self.type = type
        self.fqdn = fqdn

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPNGatewayConnectionStaticRouteModePeerVPNGatewayConnectionPeerByFQDN':
        """Initialize a VPNGatewayConnectionStaticRouteModePeerVPNGatewayConnectionPeerByFQDN object from a json dictionary."""
        args = {}
        if (ike_identity := _dict.get('ike_identity')) is not None:
            args['ike_identity'] = ike_identity
        else:
            raise ValueError('Required property \'ike_identity\' not present in VPNGatewayConnectionStaticRouteModePeerVPNGatewayConnectionPeerByFQDN JSON')
        if (type := _dict.get('type')) is not None:
            args['type'] = type
        else:
            raise ValueError('Required property \'type\' not present in VPNGatewayConnectionStaticRouteModePeerVPNGatewayConnectionPeerByFQDN JSON')
        if (fqdn := _dict.get('fqdn')) is not None:
            args['fqdn'] = fqdn
        else:
            raise ValueError('Required property \'fqdn\' not present in VPNGatewayConnectionStaticRouteModePeerVPNGatewayConnectionPeerByFQDN JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPNGatewayConnectionStaticRouteModePeerVPNGatewayConnectionPeerByFQDN object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'ike_identity') and self.ike_identity is not None:
            if isinstance(self.ike_identity, dict):
                _dict['ike_identity'] = self.ike_identity
            else:
                _dict['ike_identity'] = self.ike_identity.to_dict()
        if hasattr(self, 'type') and self.type is not None:
            _dict['type'] = self.type
        if hasattr(self, 'fqdn') and self.fqdn is not None:
            _dict['fqdn'] = self.fqdn
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VPNGatewayConnectionStaticRouteModePeerVPNGatewayConnectionPeerByFQDN object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPNGatewayConnectionStaticRouteModePeerVPNGatewayConnectionPeerByFQDN') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPNGatewayConnectionStaticRouteModePeerVPNGatewayConnectionPeerByFQDN') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class TypeEnum(str, Enum):
        """
        Indicates whether `peer.address` or `peer.fqdn` is used.
        """

        ADDRESS = 'address'
        FQDN = 'fqdn'



class VPNGatewayPolicyMode(VPNGateway):
    """
    VPNGatewayPolicyMode.

    :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 CRN for this VPN gateway.
    :param List[VPNGatewayHealthReason] health_reasons: The reasons for the current
          `health_state` (if any).
    :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 gateway.
    :param str id: The unique identifier for this VPN gateway.
    :param List[VPNGatewayLifecycleReason] lifecycle_reasons: The reasons for the
          current `lifecycle_state` (if any).
    :param str lifecycle_state: The lifecycle state of the VPN gateway.
    :param List[VPNGatewayMember] members: The members for the VPN gateway.
    :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.
    """

    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 CRN for this VPN gateway.
        :param List[VPNGatewayHealthReason] health_reasons: The reasons for the
               current `health_state` (if any).
        :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 gateway.
        :param str id: The unique identifier for this VPN gateway.
        :param List[VPNGatewayLifecycleReason] lifecycle_reasons: The reasons for
               the current `lifecycle_state` (if any).
        :param str lifecycle_state: The lifecycle state of the VPN gateway.
        :param List[VPNGatewayMember] members: The members for the VPN gateway.
        :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 := _dict.get('connections')) is not None:
            args['connections'] = [VPNGatewayConnectionReference.from_dict(v) for v in connections]
        else:
            raise ValueError('Required property \'connections\' not present in VPNGatewayPolicyMode JSON')
        if (created_at := _dict.get('created_at')) is not None:
            args['created_at'] = string_to_datetime(created_at)
        else:
            raise ValueError('Required property \'created_at\' not present in VPNGatewayPolicyMode JSON')
        if (crn := _dict.get('crn')) is not None:
            args['crn'] = crn
        else:
            raise ValueError('Required property \'crn\' not present in VPNGatewayPolicyMode JSON')
        if (health_reasons := _dict.get('health_reasons')) is not None:
            args['health_reasons'] = [VPNGatewayHealthReason.from_dict(v) for v in health_reasons]
        else:
            raise ValueError('Required property \'health_reasons\' not present in VPNGatewayPolicyMode JSON')
        if (health_state := _dict.get('health_state')) is not None:
            args['health_state'] = health_state
        else:
            raise ValueError('Required property \'health_state\' not present in VPNGatewayPolicyMode JSON')
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in VPNGatewayPolicyMode JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in VPNGatewayPolicyMode JSON')
        if (lifecycle_reasons := _dict.get('lifecycle_reasons')) is not None:
            args['lifecycle_reasons'] = [VPNGatewayLifecycleReason.from_dict(v) for v in lifecycle_reasons]
        else:
            raise ValueError('Required property \'lifecycle_reasons\' not present in VPNGatewayPolicyMode JSON')
        if (lifecycle_state := _dict.get('lifecycle_state')) is not None:
            args['lifecycle_state'] = lifecycle_state
        else:
            raise ValueError('Required property \'lifecycle_state\' not present in VPNGatewayPolicyMode JSON')
        if (members := _dict.get('members')) is not None:
            args['members'] = [VPNGatewayMember.from_dict(v) for v in members]
        else:
            raise ValueError('Required property \'members\' not present in VPNGatewayPolicyMode JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in VPNGatewayPolicyMode JSON')
        if (resource_group := _dict.get('resource_group')) is not None:
            args['resource_group'] = ResourceGroupReference.from_dict(resource_group)
        else:
            raise ValueError('Required property \'resource_group\' not present in VPNGatewayPolicyMode JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = resource_type
        else:
            raise ValueError('Required property \'resource_type\' not present in VPNGatewayPolicyMode JSON')
        if (subnet := _dict.get('subnet')) is not None:
            args['subnet'] = SubnetReference.from_dict(subnet)
        else:
            raise ValueError('Required property \'subnet\' not present in VPNGatewayPolicyMode JSON')
        if (vpc := _dict.get('vpc')) is not None:
            args['vpc'] = VPCReference.from_dict(vpc)
        else:
            raise ValueError('Required property \'vpc\' not present in VPNGatewayPolicyMode JSON')
        if (mode := _dict.get('mode')) is not None:
            args['mode'] = 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.

    :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 SubnetIdentity subnet:
    :param str mode: (optional) Policy mode VPN gateway.
    """

    def __init__(
        self,
        subnet: 'SubnetIdentity',
        *,
        name: Optional[str] = None,
        resource_group: Optional['ResourceGroupIdentity'] = None,
        mode: Optional[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 := _dict.get('name')) is not None:
            args['name'] = name
        if (resource_group := _dict.get('resource_group')) is not None:
            args['resource_group'] = resource_group
        if (subnet := _dict.get('subnet')) is not None:
            args['subnet'] = subnet
        else:
            raise ValueError('Required property \'subnet\' not present in VPNGatewayPrototypeVPNGatewayPolicyModePrototype JSON')
        if (mode := _dict.get('mode')) is not None:
            args['mode'] = 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.

    :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 SubnetIdentity subnet:
    :param str mode: (optional) Route mode VPN gateway.
    """

    def __init__(
        self,
        subnet: 'SubnetIdentity',
        *,
        name: Optional[str] = None,
        resource_group: Optional['ResourceGroupIdentity'] = None,
        mode: Optional[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 := _dict.get('name')) is not None:
            args['name'] = name
        if (resource_group := _dict.get('resource_group')) is not None:
            args['resource_group'] = resource_group
        if (subnet := _dict.get('subnet')) is not None:
            args['subnet'] = subnet
        else:
            raise ValueError('Required property \'subnet\' not present in VPNGatewayPrototypeVPNGatewayRouteModePrototype JSON')
        if (mode := _dict.get('mode')) is not None:
            args['mode'] = 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.

    :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 CRN for this VPN gateway.
    :param List[VPNGatewayHealthReason] health_reasons: The reasons for the current
          `health_state` (if any).
    :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 gateway.
    :param str id: The unique identifier for this VPN gateway.
    :param List[VPNGatewayLifecycleReason] lifecycle_reasons: The reasons for the
          current `lifecycle_state` (if any).
    :param str lifecycle_state: The lifecycle state of the VPN gateway.
    :param List[VPNGatewayMember] members: The members for the VPN gateway.
    :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.
    """

    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 CRN for this VPN gateway.
        :param List[VPNGatewayHealthReason] health_reasons: The reasons for the
               current `health_state` (if any).
        :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 gateway.
        :param str id: The unique identifier for this VPN gateway.
        :param List[VPNGatewayLifecycleReason] lifecycle_reasons: The reasons for
               the current `lifecycle_state` (if any).
        :param str lifecycle_state: The lifecycle state of the VPN gateway.
        :param List[VPNGatewayMember] members: The members for the VPN gateway.
        :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 := _dict.get('connections')) is not None:
            args['connections'] = [VPNGatewayConnectionReference.from_dict(v) for v in connections]
        else:
            raise ValueError('Required property \'connections\' not present in VPNGatewayRouteMode JSON')
        if (created_at := _dict.get('created_at')) is not None:
            args['created_at'] = string_to_datetime(created_at)
        else:
            raise ValueError('Required property \'created_at\' not present in VPNGatewayRouteMode JSON')
        if (crn := _dict.get('crn')) is not None:
            args['crn'] = crn
        else:
            raise ValueError('Required property \'crn\' not present in VPNGatewayRouteMode JSON')
        if (health_reasons := _dict.get('health_reasons')) is not None:
            args['health_reasons'] = [VPNGatewayHealthReason.from_dict(v) for v in health_reasons]
        else:
            raise ValueError('Required property \'health_reasons\' not present in VPNGatewayRouteMode JSON')
        if (health_state := _dict.get('health_state')) is not None:
            args['health_state'] = health_state
        else:
            raise ValueError('Required property \'health_state\' not present in VPNGatewayRouteMode JSON')
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in VPNGatewayRouteMode JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in VPNGatewayRouteMode JSON')
        if (lifecycle_reasons := _dict.get('lifecycle_reasons')) is not None:
            args['lifecycle_reasons'] = [VPNGatewayLifecycleReason.from_dict(v) for v in lifecycle_reasons]
        else:
            raise ValueError('Required property \'lifecycle_reasons\' not present in VPNGatewayRouteMode JSON')
        if (lifecycle_state := _dict.get('lifecycle_state')) is not None:
            args['lifecycle_state'] = lifecycle_state
        else:
            raise ValueError('Required property \'lifecycle_state\' not present in VPNGatewayRouteMode JSON')
        if (members := _dict.get('members')) is not None:
            args['members'] = [VPNGatewayMember.from_dict(v) for v in members]
        else:
            raise ValueError('Required property \'members\' not present in VPNGatewayRouteMode JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in VPNGatewayRouteMode JSON')
        if (resource_group := _dict.get('resource_group')) is not None:
            args['resource_group'] = ResourceGroupReference.from_dict(resource_group)
        else:
            raise ValueError('Required property \'resource_group\' not present in VPNGatewayRouteMode JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = resource_type
        else:
            raise ValueError('Required property \'resource_type\' not present in VPNGatewayRouteMode JSON')
        if (subnet := _dict.get('subnet')) is not None:
            args['subnet'] = SubnetReference.from_dict(subnet)
        else:
            raise ValueError('Required property \'subnet\' not present in VPNGatewayRouteMode JSON')
        if (vpc := _dict.get('vpc')) is not None:
            args['vpc'] = VPCReference.from_dict(vpc)
        else:
            raise ValueError('Required property \'vpc\' not present in VPNGatewayRouteMode JSON')
        if (mode := _dict.get('mode')) is not None:
            args['mode'] = 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.

    :param str method: The type of authentication.
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :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.
    """

    def __init__(
        self,
        method: str,
        client_ca: 'CertificateInstanceReference',
        *,
        crl: Optional[str] = None,
    ) -> None:
        """
        Initialize a VPNServerAuthenticationByCertificate object.

        :param str method: The type of authentication.
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :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 := _dict.get('method')) is not None:
            args['method'] = method
        else:
            raise ValueError('Required property \'method\' not present in VPNServerAuthenticationByCertificate JSON')
        if (client_ca := _dict.get('client_ca')) is not None:
            args['client_ca'] = CertificateInstanceReference.from_dict(client_ca)
        else:
            raise ValueError('Required property \'client_ca\' not present in VPNServerAuthenticationByCertificate JSON')
        if (crl := _dict.get('crl')) is not None:
            args['crl'] = 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.
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        CERTIFICATE = 'certificate'
        USERNAME = 'username'



class VPNServerAuthenticationByUsername(VPNServerAuthentication):
    """
    VPNServerAuthenticationByUsername.

    :param str method: The type of authentication.
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :param 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.
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :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 := _dict.get('method')) is not None:
            args['method'] = method
        else:
            raise ValueError('Required property \'method\' not present in VPNServerAuthenticationByUsername JSON')
        if (identity_provider := _dict.get('identity_provider')) is not None:
            args['identity_provider'] = 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.
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        CERTIFICATE = 'certificate'
        USERNAME = 'username'



class VPNServerAuthenticationByUsernameIdProviderByIAM(VPNServerAuthenticationByUsernameIdProvider):
    """
    VPNServerAuthenticationByUsernameIdProviderByIAM.

    :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 may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    """

    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 may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        """
        # 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 := _dict.get('provider_type')) is not None:
            args['provider_type'] = 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 may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        IAM = 'iam'



class VPNServerAuthenticationPrototypeVPNServerAuthenticationByCertificatePrototype(VPNServerAuthenticationPrototype):
    """
    VPNServerAuthenticationPrototypeVPNServerAuthenticationByCertificatePrototype.

    :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.
    """

    def __init__(
        self,
        method: str,
        client_ca: 'CertificateInstanceIdentity',
        *,
        crl: Optional[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 := _dict.get('method')) is not None:
            args['method'] = method
        else:
            raise ValueError('Required property \'method\' not present in VPNServerAuthenticationPrototypeVPNServerAuthenticationByCertificatePrototype JSON')
        if (client_ca := _dict.get('client_ca')) is not None:
            args['client_ca'] = client_ca
        else:
            raise ValueError('Required property \'client_ca\' not present in VPNServerAuthenticationPrototypeVPNServerAuthenticationByCertificatePrototype JSON')
        if (crl := _dict.get('crl')) is not None:
            args['crl'] = 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.

    :param str method: The type of authentication.
    :param 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 := _dict.get('method')) is not None:
            args['method'] = method
        else:
            raise ValueError('Required property \'method\' not present in VPNServerAuthenticationPrototypeVPNServerAuthenticationByUsernamePrototype JSON')
        if (identity_provider := _dict.get('identity_provider')) is not None:
            args['identity_provider'] = 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 VirtualNetworkInterfaceIPPrototypeReservedIPIdentityVirtualNetworkInterfaceIPsContext(VirtualNetworkInterfaceIPPrototype):
    """
    Identifies a reserved IP by a unique property. The reserved IP must be currently
    unbound and in the primary IP's subnet.

    """

    def __init__(
        self,
    ) -> None:
        """
        Initialize a VirtualNetworkInterfaceIPPrototypeReservedIPIdentityVirtualNetworkInterfaceIPsContext object.

        """
        # pylint: disable=super-init-not-called
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['VirtualNetworkInterfaceIPPrototypeReservedIPIdentityVirtualNetworkInterfaceIPsContextById', 'VirtualNetworkInterfaceIPPrototypeReservedIPIdentityVirtualNetworkInterfaceIPsContextByHref'])
        )
        raise Exception(msg)


class VirtualNetworkInterfaceIPPrototypeReservedIPPrototypeVirtualNetworkInterfaceIPsContext(VirtualNetworkInterfaceIPPrototype):
    """
    The prototype for a new reserved IP. Must be in the primary IP's subnet.

    :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.
    """

    def __init__(
        self,
        *,
        address: Optional[str] = None,
        auto_delete: Optional[bool] = None,
        name: Optional[str] = None,
    ) -> None:
        """
        Initialize a VirtualNetworkInterfaceIPPrototypeReservedIPPrototypeVirtualNetworkInterfaceIPsContext 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) -> 'VirtualNetworkInterfaceIPPrototypeReservedIPPrototypeVirtualNetworkInterfaceIPsContext':
        """Initialize a VirtualNetworkInterfaceIPPrototypeReservedIPPrototypeVirtualNetworkInterfaceIPsContext object from a json dictionary."""
        args = {}
        if (address := _dict.get('address')) is not None:
            args['address'] = address
        if (auto_delete := _dict.get('auto_delete')) is not None:
            args['auto_delete'] = auto_delete
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VirtualNetworkInterfaceIPPrototypeReservedIPPrototypeVirtualNetworkInterfaceIPsContext object from 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 VirtualNetworkInterfaceIPPrototypeReservedIPPrototypeVirtualNetworkInterfaceIPsContext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VirtualNetworkInterfaceIPPrototypeReservedIPPrototypeVirtualNetworkInterfaceIPsContext') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VirtualNetworkInterfaceIPPrototypeReservedIPPrototypeVirtualNetworkInterfaceIPsContext') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


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.

    :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.
    """

    def __init__(
        self,
        *,
        address: Optional[str] = None,
        auto_delete: Optional[bool] = None,
        name: Optional[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 := _dict.get('address')) is not None:
            args['address'] = address
        if (auto_delete := _dict.get('auto_delete')) is not None:
            args['auto_delete'] = auto_delete
        if (name := _dict.get('name')) is not None:
            args['name'] = 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 VirtualNetworkInterfaceTargetBareMetalServerNetworkAttachmentReferenceVirtualNetworkInterfaceContext(VirtualNetworkInterfaceTarget):
    """
    VirtualNetworkInterfaceTargetBareMetalServerNetworkAttachmentReferenceVirtualNetworkInterfaceContext.

    :param str href: The URL for this bare metal server network attachment.
    :param str id: The unique identifier for this bare metal server network
          attachment.
    :param str name: The name for this bare metal server network attachment. The
          name is unique across all network attachments for the bare metal server.
    :param str resource_type: The resource type.
    """

    def __init__(
        self,
        href: str,
        id: str,
        name: str,
        resource_type: str,
    ) -> None:
        """
        Initialize a VirtualNetworkInterfaceTargetBareMetalServerNetworkAttachmentReferenceVirtualNetworkInterfaceContext object.

        :param str href: The URL for this bare metal server network attachment.
        :param str id: The unique identifier for this bare metal server network
               attachment.
        :param str name: The name for this bare metal server network attachment.
               The name is unique across all network attachments for the bare metal
               server.
        :param str resource_type: The resource type.
        """
        # pylint: disable=super-init-not-called
        self.href = href
        self.id = id
        self.name = name
        self.resource_type = resource_type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VirtualNetworkInterfaceTargetBareMetalServerNetworkAttachmentReferenceVirtualNetworkInterfaceContext':
        """Initialize a VirtualNetworkInterfaceTargetBareMetalServerNetworkAttachmentReferenceVirtualNetworkInterfaceContext object from a json dictionary."""
        args = {}
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in VirtualNetworkInterfaceTargetBareMetalServerNetworkAttachmentReferenceVirtualNetworkInterfaceContext JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in VirtualNetworkInterfaceTargetBareMetalServerNetworkAttachmentReferenceVirtualNetworkInterfaceContext JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in VirtualNetworkInterfaceTargetBareMetalServerNetworkAttachmentReferenceVirtualNetworkInterfaceContext JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = resource_type
        else:
            raise ValueError('Required property \'resource_type\' not present in VirtualNetworkInterfaceTargetBareMetalServerNetworkAttachmentReferenceVirtualNetworkInterfaceContext JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VirtualNetworkInterfaceTargetBareMetalServerNetworkAttachmentReferenceVirtualNetworkInterfaceContext object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'resource_type') and self.resource_type is not None:
            _dict['resource_type'] = self.resource_type
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VirtualNetworkInterfaceTargetBareMetalServerNetworkAttachmentReferenceVirtualNetworkInterfaceContext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VirtualNetworkInterfaceTargetBareMetalServerNetworkAttachmentReferenceVirtualNetworkInterfaceContext') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VirtualNetworkInterfaceTargetBareMetalServerNetworkAttachmentReferenceVirtualNetworkInterfaceContext') -> 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_NETWORK_ATTACHMENT = 'bare_metal_server_network_attachment'



class VirtualNetworkInterfaceTargetInstanceNetworkAttachmentReferenceVirtualNetworkInterfaceContext(VirtualNetworkInterfaceTarget):
    """
    VirtualNetworkInterfaceTargetInstanceNetworkAttachmentReferenceVirtualNetworkInterfaceContext.

    :param str href: The URL for this instance network attachment.
    :param str id: The unique identifier for this instance network attachment.
    :param str name: The name for this instance network attachment. The name is
          unique across all network attachments for the instance.
    :param str resource_type: The resource type.
    """

    def __init__(
        self,
        href: str,
        id: str,
        name: str,
        resource_type: str,
    ) -> None:
        """
        Initialize a VirtualNetworkInterfaceTargetInstanceNetworkAttachmentReferenceVirtualNetworkInterfaceContext object.

        :param str href: The URL for this instance network attachment.
        :param str id: The unique identifier for this instance network attachment.
        :param str name: The name for this instance network attachment. The name is
               unique across all network attachments for the instance.
        :param str resource_type: The resource type.
        """
        # pylint: disable=super-init-not-called
        self.href = href
        self.id = id
        self.name = name
        self.resource_type = resource_type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VirtualNetworkInterfaceTargetInstanceNetworkAttachmentReferenceVirtualNetworkInterfaceContext':
        """Initialize a VirtualNetworkInterfaceTargetInstanceNetworkAttachmentReferenceVirtualNetworkInterfaceContext object from a json dictionary."""
        args = {}
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in VirtualNetworkInterfaceTargetInstanceNetworkAttachmentReferenceVirtualNetworkInterfaceContext JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in VirtualNetworkInterfaceTargetInstanceNetworkAttachmentReferenceVirtualNetworkInterfaceContext JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in VirtualNetworkInterfaceTargetInstanceNetworkAttachmentReferenceVirtualNetworkInterfaceContext JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = resource_type
        else:
            raise ValueError('Required property \'resource_type\' not present in VirtualNetworkInterfaceTargetInstanceNetworkAttachmentReferenceVirtualNetworkInterfaceContext JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VirtualNetworkInterfaceTargetInstanceNetworkAttachmentReferenceVirtualNetworkInterfaceContext object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'resource_type') and self.resource_type is not None:
            _dict['resource_type'] = self.resource_type
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VirtualNetworkInterfaceTargetInstanceNetworkAttachmentReferenceVirtualNetworkInterfaceContext object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VirtualNetworkInterfaceTargetInstanceNetworkAttachmentReferenceVirtualNetworkInterfaceContext') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VirtualNetworkInterfaceTargetInstanceNetworkAttachmentReferenceVirtualNetworkInterfaceContext') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ResourceTypeEnum(str, Enum):
        """
        The resource type.
        """

        INSTANCE_NETWORK_ATTACHMENT = 'instance_network_attachment'



class VirtualNetworkInterfaceTargetShareMountTargetReference(VirtualNetworkInterfaceTarget):
    """
    VirtualNetworkInterfaceTargetShareMountTargetReference.

    :param Deleted deleted: (optional) If present, this property indicates the
          referenced resource has been deleted, and provides
          some supplementary information.
    :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.
    """

    def __init__(
        self,
        href: str,
        id: str,
        name: str,
        resource_type: str,
        *,
        deleted: Optional['Deleted'] = 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 Deleted 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 := _dict.get('deleted')) is not None:
            args['deleted'] = Deleted.from_dict(deleted)
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in VirtualNetworkInterfaceTargetShareMountTargetReference JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in VirtualNetworkInterfaceTargetShareMountTargetReference JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in VirtualNetworkInterfaceTargetShareMountTargetReference JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = 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.

    :param int iops: (optional) The maximum I/O operations per second (IOPS) to use
          for this volume. If specified, the `family` of the volume profile must be
          `custom` or `defined_performance`.
    :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 VolumeProfileIdentity profile: The
          [profile](https://cloud.ibm.com/docs/vpc?topic=vpc-block-storage-profiles) to
          use for this volume.
    :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.
    """

    def __init__(
        self,
        profile: 'VolumeProfileIdentity',
        *,
        iops: Optional[int] = None,
        name: Optional[str] = None,
        resource_group: Optional['ResourceGroupIdentity'] = None,
        user_tags: Optional[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. If specified, the `family` of the volume profile must
               be `custom` or `defined_performance`.
        :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.

    :param 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 := _dict.get('crn')) is not None:
            args['crn'] = 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.

    :param 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 := _dict.get('href')) is not None:
            args['href'] = 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.

    :param 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 := _dict.get('id')) is not None:
            args['id'] = 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 VolumeProfileBootCapacityDependentRange(VolumeProfileBootCapacity):
    """
    The permitted total capacity (in gigabytes) of a boot volume with this profile depends
    on its configuration.

    :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.
    """

    def __init__(
        self,
        max: int,
        min: int,
        step: int,
        type: str,
    ) -> None:
        """
        Initialize a VolumeProfileBootCapacityDependentRange 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) -> 'VolumeProfileBootCapacityDependentRange':
        """Initialize a VolumeProfileBootCapacityDependentRange object from a json dictionary."""
        args = {}
        if (max := _dict.get('max')) is not None:
            args['max'] = max
        else:
            raise ValueError('Required property \'max\' not present in VolumeProfileBootCapacityDependentRange JSON')
        if (min := _dict.get('min')) is not None:
            args['min'] = min
        else:
            raise ValueError('Required property \'min\' not present in VolumeProfileBootCapacityDependentRange JSON')
        if (step := _dict.get('step')) is not None:
            args['step'] = step
        else:
            raise ValueError('Required property \'step\' not present in VolumeProfileBootCapacityDependentRange JSON')
        if (type := _dict.get('type')) is not None:
            args['type'] = type
        else:
            raise ValueError('Required property \'type\' not present in VolumeProfileBootCapacityDependentRange JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VolumeProfileBootCapacityDependentRange object from 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 VolumeProfileBootCapacityDependentRange object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VolumeProfileBootCapacityDependentRange') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VolumeProfileBootCapacityDependentRange') -> 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_RANGE = 'dependent_range'



class VolumeProfileBootCapacityEnum(VolumeProfileBootCapacity):
    """
    The permitted total capacities (in gigabytes) of a boot volume with this profile.

    :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.
    """

    def __init__(
        self,
        default: int,
        type: str,
        values: List[int],
    ) -> None:
        """
        Initialize a VolumeProfileBootCapacityEnum 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) -> 'VolumeProfileBootCapacityEnum':
        """Initialize a VolumeProfileBootCapacityEnum object from a json dictionary."""
        args = {}
        if (default := _dict.get('default')) is not None:
            args['default'] = default
        else:
            raise ValueError('Required property \'default\' not present in VolumeProfileBootCapacityEnum JSON')
        if (type := _dict.get('type')) is not None:
            args['type'] = type
        else:
            raise ValueError('Required property \'type\' not present in VolumeProfileBootCapacityEnum JSON')
        if (values := _dict.get('values')) is not None:
            args['values'] = values
        else:
            raise ValueError('Required property \'values\' not present in VolumeProfileBootCapacityEnum JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VolumeProfileBootCapacityEnum object from 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 VolumeProfileBootCapacityEnum object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VolumeProfileBootCapacityEnum') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VolumeProfileBootCapacityEnum') -> 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 VolumeProfileBootCapacityFixed(VolumeProfileBootCapacity):
    """
    The permitted total capacity (in gigabytes) of a boot volume with this profile is
    fixed.

    :param str type: The type for this profile field.
    :param int value: The value for this profile field.
    """

    def __init__(
        self,
        type: str,
        value: int,
    ) -> None:
        """
        Initialize a VolumeProfileBootCapacityFixed 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) -> 'VolumeProfileBootCapacityFixed':
        """Initialize a VolumeProfileBootCapacityFixed object from a json dictionary."""
        args = {}
        if (type := _dict.get('type')) is not None:
            args['type'] = type
        else:
            raise ValueError('Required property \'type\' not present in VolumeProfileBootCapacityFixed JSON')
        if (value := _dict.get('value')) is not None:
            args['value'] = value
        else:
            raise ValueError('Required property \'value\' not present in VolumeProfileBootCapacityFixed JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VolumeProfileBootCapacityFixed object from 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 VolumeProfileBootCapacityFixed object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VolumeProfileBootCapacityFixed') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VolumeProfileBootCapacityFixed') -> 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 VolumeProfileBootCapacityRange(VolumeProfileBootCapacity):
    """
    The permitted total capacity range (in gigabytes) of a boot volume with this profile.

    :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.
    """

    def __init__(
        self,
        default: int,
        max: int,
        min: int,
        step: int,
        type: str,
    ) -> None:
        """
        Initialize a VolumeProfileBootCapacityRange 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) -> 'VolumeProfileBootCapacityRange':
        """Initialize a VolumeProfileBootCapacityRange object from a json dictionary."""
        args = {}
        if (default := _dict.get('default')) is not None:
            args['default'] = default
        else:
            raise ValueError('Required property \'default\' not present in VolumeProfileBootCapacityRange JSON')
        if (max := _dict.get('max')) is not None:
            args['max'] = max
        else:
            raise ValueError('Required property \'max\' not present in VolumeProfileBootCapacityRange JSON')
        if (min := _dict.get('min')) is not None:
            args['min'] = min
        else:
            raise ValueError('Required property \'min\' not present in VolumeProfileBootCapacityRange JSON')
        if (step := _dict.get('step')) is not None:
            args['step'] = step
        else:
            raise ValueError('Required property \'step\' not present in VolumeProfileBootCapacityRange JSON')
        if (type := _dict.get('type')) is not None:
            args['type'] = type
        else:
            raise ValueError('Required property \'type\' not present in VolumeProfileBootCapacityRange JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VolumeProfileBootCapacityRange object from 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 VolumeProfileBootCapacityRange object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VolumeProfileBootCapacityRange') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VolumeProfileBootCapacityRange') -> 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 VolumeProfileCapacityDependentRange(VolumeProfileCapacity):
    """
    The permitted total capacity (in gigabytes) of a data volume with this profile depends
    on its configuration.

    :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.
    """

    def __init__(
        self,
        max: int,
        min: int,
        step: int,
        type: str,
    ) -> None:
        """
        Initialize a VolumeProfileCapacityDependentRange 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) -> 'VolumeProfileCapacityDependentRange':
        """Initialize a VolumeProfileCapacityDependentRange object from a json dictionary."""
        args = {}
        if (max := _dict.get('max')) is not None:
            args['max'] = max
        else:
            raise ValueError('Required property \'max\' not present in VolumeProfileCapacityDependentRange JSON')
        if (min := _dict.get('min')) is not None:
            args['min'] = min
        else:
            raise ValueError('Required property \'min\' not present in VolumeProfileCapacityDependentRange JSON')
        if (step := _dict.get('step')) is not None:
            args['step'] = step
        else:
            raise ValueError('Required property \'step\' not present in VolumeProfileCapacityDependentRange JSON')
        if (type := _dict.get('type')) is not None:
            args['type'] = type
        else:
            raise ValueError('Required property \'type\' not present in VolumeProfileCapacityDependentRange JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VolumeProfileCapacityDependentRange object from 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 VolumeProfileCapacityDependentRange object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VolumeProfileCapacityDependentRange') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VolumeProfileCapacityDependentRange') -> 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_RANGE = 'dependent_range'



class VolumeProfileCapacityEnum(VolumeProfileCapacity):
    """
    The permitted total capacities (in gigabytes) of a data volume with this profile.

    :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.
    """

    def __init__(
        self,
        default: int,
        type: str,
        values: List[int],
    ) -> None:
        """
        Initialize a VolumeProfileCapacityEnum 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) -> 'VolumeProfileCapacityEnum':
        """Initialize a VolumeProfileCapacityEnum object from a json dictionary."""
        args = {}
        if (default := _dict.get('default')) is not None:
            args['default'] = default
        else:
            raise ValueError('Required property \'default\' not present in VolumeProfileCapacityEnum JSON')
        if (type := _dict.get('type')) is not None:
            args['type'] = type
        else:
            raise ValueError('Required property \'type\' not present in VolumeProfileCapacityEnum JSON')
        if (values := _dict.get('values')) is not None:
            args['values'] = values
        else:
            raise ValueError('Required property \'values\' not present in VolumeProfileCapacityEnum JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VolumeProfileCapacityEnum object from 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 VolumeProfileCapacityEnum object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VolumeProfileCapacityEnum') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VolumeProfileCapacityEnum') -> 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 VolumeProfileCapacityFixed(VolumeProfileCapacity):
    """
    The permitted total capacity (in gigabytes) of a data volume with this profile is
    fixed.

    :param str type: The type for this profile field.
    :param int value: The value for this profile field.
    """

    def __init__(
        self,
        type: str,
        value: int,
    ) -> None:
        """
        Initialize a VolumeProfileCapacityFixed 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) -> 'VolumeProfileCapacityFixed':
        """Initialize a VolumeProfileCapacityFixed object from a json dictionary."""
        args = {}
        if (type := _dict.get('type')) is not None:
            args['type'] = type
        else:
            raise ValueError('Required property \'type\' not present in VolumeProfileCapacityFixed JSON')
        if (value := _dict.get('value')) is not None:
            args['value'] = value
        else:
            raise ValueError('Required property \'value\' not present in VolumeProfileCapacityFixed JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VolumeProfileCapacityFixed object from 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 VolumeProfileCapacityFixed object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VolumeProfileCapacityFixed') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VolumeProfileCapacityFixed') -> 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 VolumeProfileCapacityRange(VolumeProfileCapacity):
    """
    The permitted total capacity range (in gigabytes) of a data volume with this profile.

    :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.
    """

    def __init__(
        self,
        default: int,
        max: int,
        min: int,
        step: int,
        type: str,
    ) -> None:
        """
        Initialize a VolumeProfileCapacityRange 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) -> 'VolumeProfileCapacityRange':
        """Initialize a VolumeProfileCapacityRange object from a json dictionary."""
        args = {}
        if (default := _dict.get('default')) is not None:
            args['default'] = default
        else:
            raise ValueError('Required property \'default\' not present in VolumeProfileCapacityRange JSON')
        if (max := _dict.get('max')) is not None:
            args['max'] = max
        else:
            raise ValueError('Required property \'max\' not present in VolumeProfileCapacityRange JSON')
        if (min := _dict.get('min')) is not None:
            args['min'] = min
        else:
            raise ValueError('Required property \'min\' not present in VolumeProfileCapacityRange JSON')
        if (step := _dict.get('step')) is not None:
            args['step'] = step
        else:
            raise ValueError('Required property \'step\' not present in VolumeProfileCapacityRange JSON')
        if (type := _dict.get('type')) is not None:
            args['type'] = type
        else:
            raise ValueError('Required property \'type\' not present in VolumeProfileCapacityRange JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VolumeProfileCapacityRange object from 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 VolumeProfileCapacityRange object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VolumeProfileCapacityRange') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VolumeProfileCapacityRange') -> 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 VolumeProfileIOPSDependentRange(VolumeProfileIOPS):
    """
    The permitted IOPS range of a volume with this profile depends on its configuration.

    :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.
    """

    def __init__(
        self,
        max: int,
        min: int,
        step: int,
        type: str,
    ) -> None:
        """
        Initialize a VolumeProfileIOPSDependentRange 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) -> 'VolumeProfileIOPSDependentRange':
        """Initialize a VolumeProfileIOPSDependentRange object from a json dictionary."""
        args = {}
        if (max := _dict.get('max')) is not None:
            args['max'] = max
        else:
            raise ValueError('Required property \'max\' not present in VolumeProfileIOPSDependentRange JSON')
        if (min := _dict.get('min')) is not None:
            args['min'] = min
        else:
            raise ValueError('Required property \'min\' not present in VolumeProfileIOPSDependentRange JSON')
        if (step := _dict.get('step')) is not None:
            args['step'] = step
        else:
            raise ValueError('Required property \'step\' not present in VolumeProfileIOPSDependentRange JSON')
        if (type := _dict.get('type')) is not None:
            args['type'] = type
        else:
            raise ValueError('Required property \'type\' not present in VolumeProfileIOPSDependentRange JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VolumeProfileIOPSDependentRange object from 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 VolumeProfileIOPSDependentRange object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VolumeProfileIOPSDependentRange') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VolumeProfileIOPSDependentRange') -> 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_RANGE = 'dependent_range'



class VolumeProfileIOPSEnum(VolumeProfileIOPS):
    """
    The permitted IOPS values of a volume with this profile.

    :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.
    """

    def __init__(
        self,
        default: int,
        type: str,
        values: List[int],
    ) -> None:
        """
        Initialize a VolumeProfileIOPSEnum 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) -> 'VolumeProfileIOPSEnum':
        """Initialize a VolumeProfileIOPSEnum object from a json dictionary."""
        args = {}
        if (default := _dict.get('default')) is not None:
            args['default'] = default
        else:
            raise ValueError('Required property \'default\' not present in VolumeProfileIOPSEnum JSON')
        if (type := _dict.get('type')) is not None:
            args['type'] = type
        else:
            raise ValueError('Required property \'type\' not present in VolumeProfileIOPSEnum JSON')
        if (values := _dict.get('values')) is not None:
            args['values'] = values
        else:
            raise ValueError('Required property \'values\' not present in VolumeProfileIOPSEnum JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VolumeProfileIOPSEnum object from 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 VolumeProfileIOPSEnum object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VolumeProfileIOPSEnum') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VolumeProfileIOPSEnum') -> 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 VolumeProfileIOPSFixed(VolumeProfileIOPS):
    """
    The permitted IOPS of a volume with this profile is fixed.

    :param str type: The type for this profile field.
    :param int value: The value for this profile field.
    """

    def __init__(
        self,
        type: str,
        value: int,
    ) -> None:
        """
        Initialize a VolumeProfileIOPSFixed 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) -> 'VolumeProfileIOPSFixed':
        """Initialize a VolumeProfileIOPSFixed object from a json dictionary."""
        args = {}
        if (type := _dict.get('type')) is not None:
            args['type'] = type
        else:
            raise ValueError('Required property \'type\' not present in VolumeProfileIOPSFixed JSON')
        if (value := _dict.get('value')) is not None:
            args['value'] = value
        else:
            raise ValueError('Required property \'value\' not present in VolumeProfileIOPSFixed JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VolumeProfileIOPSFixed object from 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 VolumeProfileIOPSFixed object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VolumeProfileIOPSFixed') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VolumeProfileIOPSFixed') -> 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 VolumeProfileIOPSRange(VolumeProfileIOPS):
    """
    The permitted IOPS range of a volume with this profile.

    :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.
    """

    def __init__(
        self,
        default: int,
        max: int,
        min: int,
        step: int,
        type: str,
    ) -> None:
        """
        Initialize a VolumeProfileIOPSRange 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) -> 'VolumeProfileIOPSRange':
        """Initialize a VolumeProfileIOPSRange object from a json dictionary."""
        args = {}
        if (default := _dict.get('default')) is not None:
            args['default'] = default
        else:
            raise ValueError('Required property \'default\' not present in VolumeProfileIOPSRange JSON')
        if (max := _dict.get('max')) is not None:
            args['max'] = max
        else:
            raise ValueError('Required property \'max\' not present in VolumeProfileIOPSRange JSON')
        if (min := _dict.get('min')) is not None:
            args['min'] = min
        else:
            raise ValueError('Required property \'min\' not present in VolumeProfileIOPSRange JSON')
        if (step := _dict.get('step')) is not None:
            args['step'] = step
        else:
            raise ValueError('Required property \'step\' not present in VolumeProfileIOPSRange JSON')
        if (type := _dict.get('type')) is not None:
            args['type'] = type
        else:
            raise ValueError('Required property \'type\' not present in VolumeProfileIOPSRange JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VolumeProfileIOPSRange object from 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 VolumeProfileIOPSRange object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VolumeProfileIOPSRange') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VolumeProfileIOPSRange') -> 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 VolumeProfileIdentityByHref(VolumeProfileIdentity):
    """
    VolumeProfileIdentityByHref.

    :param 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 := _dict.get('href')) is not None:
            args['href'] = 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.

    :param 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 := _dict.get('name')) is not None:
            args['name'] = 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.

    :param int iops: (optional) The maximum I/O operations per second (IOPS) to use
          for this volume. If specified, the `family` of the volume profile must be
          `custom` or `defined_performance`.
    :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 VolumeProfileIdentity profile: The
          [profile](https://cloud.ibm.com/docs/vpc?topic=vpc-block-storage-profiles) to
          use for this volume.
    :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 ZoneIdentity zone: The zone this volume will reside in.
    :param int capacity: The capacity to use for the volume (in gigabytes). The
          specified value must be within the `capacity` range of the volume's profile.
    :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`.
    """

    def __init__(
        self,
        profile: 'VolumeProfileIdentity',
        zone: 'ZoneIdentity',
        capacity: int,
        *,
        iops: Optional[int] = None,
        name: Optional[str] = None,
        resource_group: Optional['ResourceGroupIdentity'] = None,
        user_tags: Optional[List[str]] = None,
        encryption_key: Optional['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 value must be within the `capacity` range of the volume's
               profile.
        :param int iops: (optional) The maximum I/O operations per second (IOPS) to
               use for this volume. If specified, the `family` of the volume profile must
               be `custom` or `defined_performance`.
        :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 := _dict.get('iops')) is not None:
            args['iops'] = iops
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        if (profile := _dict.get('profile')) is not None:
            args['profile'] = profile
        else:
            raise ValueError('Required property \'profile\' not present in VolumePrototypeVolumeByCapacity JSON')
        if (resource_group := _dict.get('resource_group')) is not None:
            args['resource_group'] = resource_group
        if (user_tags := _dict.get('user_tags')) is not None:
            args['user_tags'] = user_tags
        if (zone := _dict.get('zone')) is not None:
            args['zone'] = zone
        else:
            raise ValueError('Required property \'zone\' not present in VolumePrototypeVolumeByCapacity JSON')
        if (capacity := _dict.get('capacity')) is not None:
            args['capacity'] = capacity
        else:
            raise ValueError('Required property \'capacity\' not present in VolumePrototypeVolumeByCapacity JSON')
        if (encryption_key := _dict.get('encryption_key')) is not None:
            args['encryption_key'] = 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.

    :param int iops: (optional) The maximum I/O operations per second (IOPS) to use
          for this volume. If specified, the `family` of the volume profile must be
          `custom` or `defined_performance`.
    :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 VolumeProfileIdentity profile: The
          [profile](https://cloud.ibm.com/docs/vpc?topic=vpc-block-storage-profiles) to
          use for this volume.
    :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 ZoneIdentity zone: The zone this volume will reside in.
    :param int capacity: (optional) The capacity to use for the volume (in
          gigabytes). The specified value must be at least the snapshot's
          `minimum_capacity`, and must be within the `capacity` range of the volume's
          profile.
          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 SnapshotIdentity source_snapshot: The snapshot to use as a source for the
          volume's data.
          The specified snapshot may be in a different account, subject to IAM policies.
    """

    def __init__(
        self,
        profile: 'VolumeProfileIdentity',
        zone: 'ZoneIdentity',
        source_snapshot: 'SnapshotIdentity',
        *,
        iops: Optional[int] = None,
        name: Optional[str] = None,
        resource_group: Optional['ResourceGroupIdentity'] = None,
        user_tags: Optional[List[str]] = None,
        capacity: Optional[int] = None,
        encryption_key: Optional['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 to use as a source
               for the volume's data.
               The specified snapshot may be in a different account, subject to IAM
               policies.
        :param int iops: (optional) The maximum I/O operations per second (IOPS) to
               use for this volume. If specified, the `family` of the volume profile must
               be `custom` or `defined_performance`.
        :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). The specified value must be at least the snapshot's
               `minimum_capacity`, and must be within the `capacity` range of the volume's
               profile.
               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 := _dict.get('iops')) is not None:
            args['iops'] = iops
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        if (profile := _dict.get('profile')) is not None:
            args['profile'] = profile
        else:
            raise ValueError('Required property \'profile\' not present in VolumePrototypeVolumeBySourceSnapshot JSON')
        if (resource_group := _dict.get('resource_group')) is not None:
            args['resource_group'] = resource_group
        if (user_tags := _dict.get('user_tags')) is not None:
            args['user_tags'] = user_tags
        if (zone := _dict.get('zone')) is not None:
            args['zone'] = zone
        else:
            raise ValueError('Required property \'zone\' not present in VolumePrototypeVolumeBySourceSnapshot JSON')
        if (capacity := _dict.get('capacity')) is not None:
            args['capacity'] = capacity
        if (encryption_key := _dict.get('encryption_key')) is not None:
            args['encryption_key'] = encryption_key
        if (source_snapshot := _dict.get('source_snapshot')) is not None:
            args['source_snapshot'] = 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.

    :param 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 := _dict.get('href')) is not None:
            args['href'] = 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.

    :param 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 := _dict.get('name')) is not None:
            args['name'] = 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.

    :param 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 := _dict.get('crn')) is not None:
            args['crn'] = 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 BareMetalServerNetworkAttachmentPrototypeVirtualNetworkInterfaceVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByCRN(BareMetalServerNetworkAttachmentPrototypeVirtualNetworkInterfaceVirtualNetworkInterfaceIdentity):
    """
    BareMetalServerNetworkAttachmentPrototypeVirtualNetworkInterfaceVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByCRN.

    :param str crn: The CRN for this virtual network interface.
    """

    def __init__(
        self,
        crn: str,
    ) -> None:
        """
        Initialize a BareMetalServerNetworkAttachmentPrototypeVirtualNetworkInterfaceVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByCRN object.

        :param str crn: The CRN for this virtual network interface.
        """
        # pylint: disable=super-init-not-called
        self.crn = crn

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'BareMetalServerNetworkAttachmentPrototypeVirtualNetworkInterfaceVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByCRN':
        """Initialize a BareMetalServerNetworkAttachmentPrototypeVirtualNetworkInterfaceVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByCRN object from a json dictionary."""
        args = {}
        if (crn := _dict.get('crn')) is not None:
            args['crn'] = crn
        else:
            raise ValueError('Required property \'crn\' not present in BareMetalServerNetworkAttachmentPrototypeVirtualNetworkInterfaceVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByCRN JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a BareMetalServerNetworkAttachmentPrototypeVirtualNetworkInterfaceVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByCRN object from 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 BareMetalServerNetworkAttachmentPrototypeVirtualNetworkInterfaceVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByCRN object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'BareMetalServerNetworkAttachmentPrototypeVirtualNetworkInterfaceVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByCRN') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'BareMetalServerNetworkAttachmentPrototypeVirtualNetworkInterfaceVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByCRN') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class BareMetalServerNetworkAttachmentPrototypeVirtualNetworkInterfaceVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByHref(BareMetalServerNetworkAttachmentPrototypeVirtualNetworkInterfaceVirtualNetworkInterfaceIdentity):
    """
    BareMetalServerNetworkAttachmentPrototypeVirtualNetworkInterfaceVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByHref.

    :param str href: The URL for this virtual network interface.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a BareMetalServerNetworkAttachmentPrototypeVirtualNetworkInterfaceVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByHref object.

        :param str href: The URL for this virtual network interface.
        """
        # pylint: disable=super-init-not-called
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'BareMetalServerNetworkAttachmentPrototypeVirtualNetworkInterfaceVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByHref':
        """Initialize a BareMetalServerNetworkAttachmentPrototypeVirtualNetworkInterfaceVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByHref object from a json dictionary."""
        args = {}
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in BareMetalServerNetworkAttachmentPrototypeVirtualNetworkInterfaceVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByHref JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a BareMetalServerNetworkAttachmentPrototypeVirtualNetworkInterfaceVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByHref object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this BareMetalServerNetworkAttachmentPrototypeVirtualNetworkInterfaceVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'BareMetalServerNetworkAttachmentPrototypeVirtualNetworkInterfaceVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByHref') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'BareMetalServerNetworkAttachmentPrototypeVirtualNetworkInterfaceVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByHref') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class BareMetalServerNetworkAttachmentPrototypeVirtualNetworkInterfaceVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityById(BareMetalServerNetworkAttachmentPrototypeVirtualNetworkInterfaceVirtualNetworkInterfaceIdentity):
    """
    BareMetalServerNetworkAttachmentPrototypeVirtualNetworkInterfaceVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityById.

    :param str id: The unique identifier for this virtual network interface.
    """

    def __init__(
        self,
        id: str,
    ) -> None:
        """
        Initialize a BareMetalServerNetworkAttachmentPrototypeVirtualNetworkInterfaceVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityById object.

        :param str id: The unique identifier for this virtual network interface.
        """
        # pylint: disable=super-init-not-called
        self.id = id

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'BareMetalServerNetworkAttachmentPrototypeVirtualNetworkInterfaceVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityById':
        """Initialize a BareMetalServerNetworkAttachmentPrototypeVirtualNetworkInterfaceVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityById object from a json dictionary."""
        args = {}
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in BareMetalServerNetworkAttachmentPrototypeVirtualNetworkInterfaceVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityById JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a BareMetalServerNetworkAttachmentPrototypeVirtualNetworkInterfaceVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityById object from 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 BareMetalServerNetworkAttachmentPrototypeVirtualNetworkInterfaceVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityById object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'BareMetalServerNetworkAttachmentPrototypeVirtualNetworkInterfaceVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityById') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'BareMetalServerNetworkAttachmentPrototypeVirtualNetworkInterfaceVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityById') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class ClusterNetworkInterfacePrimaryIPPrototypeClusterNetworkSubnetReservedIPIdentityClusterNetworkInterfacePrimaryIPContextByHref(ClusterNetworkInterfacePrimaryIPPrototypeClusterNetworkSubnetReservedIPIdentityClusterNetworkInterfacePrimaryIPContext):
    """
    ClusterNetworkInterfacePrimaryIPPrototypeClusterNetworkSubnetReservedIPIdentityClusterNetworkInterfacePrimaryIPContextByHref.

    :param str href: The URL for this cluster network subnet reserved IP.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a ClusterNetworkInterfacePrimaryIPPrototypeClusterNetworkSubnetReservedIPIdentityClusterNetworkInterfacePrimaryIPContextByHref object.

        :param str href: The URL for this cluster network subnet reserved IP.
        """
        # pylint: disable=super-init-not-called
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ClusterNetworkInterfacePrimaryIPPrototypeClusterNetworkSubnetReservedIPIdentityClusterNetworkInterfacePrimaryIPContextByHref':
        """Initialize a ClusterNetworkInterfacePrimaryIPPrototypeClusterNetworkSubnetReservedIPIdentityClusterNetworkInterfacePrimaryIPContextByHref object from a json dictionary."""
        args = {}
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in ClusterNetworkInterfacePrimaryIPPrototypeClusterNetworkSubnetReservedIPIdentityClusterNetworkInterfacePrimaryIPContextByHref JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ClusterNetworkInterfacePrimaryIPPrototypeClusterNetworkSubnetReservedIPIdentityClusterNetworkInterfacePrimaryIPContextByHref object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this ClusterNetworkInterfacePrimaryIPPrototypeClusterNetworkSubnetReservedIPIdentityClusterNetworkInterfacePrimaryIPContextByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ClusterNetworkInterfacePrimaryIPPrototypeClusterNetworkSubnetReservedIPIdentityClusterNetworkInterfacePrimaryIPContextByHref') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ClusterNetworkInterfacePrimaryIPPrototypeClusterNetworkSubnetReservedIPIdentityClusterNetworkInterfacePrimaryIPContextByHref') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class ClusterNetworkInterfacePrimaryIPPrototypeClusterNetworkSubnetReservedIPIdentityClusterNetworkInterfacePrimaryIPContextById(ClusterNetworkInterfacePrimaryIPPrototypeClusterNetworkSubnetReservedIPIdentityClusterNetworkInterfacePrimaryIPContext):
    """
    ClusterNetworkInterfacePrimaryIPPrototypeClusterNetworkSubnetReservedIPIdentityClusterNetworkInterfacePrimaryIPContextById.

    :param str id: The unique identifier for this cluster network subnet reserved
          IP.
    """

    def __init__(
        self,
        id: str,
    ) -> None:
        """
        Initialize a ClusterNetworkInterfacePrimaryIPPrototypeClusterNetworkSubnetReservedIPIdentityClusterNetworkInterfacePrimaryIPContextById object.

        :param str id: The unique identifier for this cluster network subnet
               reserved IP.
        """
        # pylint: disable=super-init-not-called
        self.id = id

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ClusterNetworkInterfacePrimaryIPPrototypeClusterNetworkSubnetReservedIPIdentityClusterNetworkInterfacePrimaryIPContextById':
        """Initialize a ClusterNetworkInterfacePrimaryIPPrototypeClusterNetworkSubnetReservedIPIdentityClusterNetworkInterfacePrimaryIPContextById object from a json dictionary."""
        args = {}
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in ClusterNetworkInterfacePrimaryIPPrototypeClusterNetworkSubnetReservedIPIdentityClusterNetworkInterfacePrimaryIPContextById JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ClusterNetworkInterfacePrimaryIPPrototypeClusterNetworkSubnetReservedIPIdentityClusterNetworkInterfacePrimaryIPContextById object from 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 ClusterNetworkInterfacePrimaryIPPrototypeClusterNetworkSubnetReservedIPIdentityClusterNetworkInterfacePrimaryIPContextById object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ClusterNetworkInterfacePrimaryIPPrototypeClusterNetworkSubnetReservedIPIdentityClusterNetworkInterfacePrimaryIPContextById') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ClusterNetworkInterfacePrimaryIPPrototypeClusterNetworkSubnetReservedIPIdentityClusterNetworkInterfacePrimaryIPContextById') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class EndpointGatewayReservedIPReservedIPIdentityByHref(EndpointGatewayReservedIPReservedIPIdentity):
    """
    EndpointGatewayReservedIPReservedIPIdentityByHref.

    :param 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 := _dict.get('href')) is not None:
            args['href'] = 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.

    :param 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 := _dict.get('id')) is not None:
            args['id'] = 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 FloatingIPTargetPatchBareMetalServerNetworkInterfaceIdentityBareMetalServerNetworkInterfaceIdentityByHref(FloatingIPTargetPatchBareMetalServerNetworkInterfaceIdentity):
    """
    FloatingIPTargetPatchBareMetalServerNetworkInterfaceIdentityBareMetalServerNetworkInterfaceIdentityByHref.

    :param str href: The URL for this bare metal server network interface.
          If this bare metal server has network attachments, this network interface is a
          [read-only
          representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
          of its corresponding network attachment.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a FloatingIPTargetPatchBareMetalServerNetworkInterfaceIdentityBareMetalServerNetworkInterfaceIdentityByHref object.

        :param str href: The URL for this bare metal server network interface.
               If this bare metal server has network attachments, this network interface
               is a
               [read-only
               representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
               of its corresponding network attachment.
        """
        # 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 := _dict.get('href')) is not None:
            args['href'] = 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.

    :param str id: The unique identifier for this bare metal server network
          interface.
          If this bare metal server has network attachments, this network interface is a
          [read-only
          representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
          of its corresponding network attachment and its attached virtual network
          interface, and the identifier is that of the corresponding network attachment.
    """

    def __init__(
        self,
        id: str,
    ) -> None:
        """
        Initialize a FloatingIPTargetPatchBareMetalServerNetworkInterfaceIdentityBareMetalServerNetworkInterfaceIdentityById object.

        :param str id: The unique identifier for this bare metal server network
               interface.
               If this bare metal server has network attachments, this network interface
               is a
               [read-only
               representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
               of its corresponding network attachment and its attached virtual network
               interface, and the identifier is that of the corresponding network
               attachment.
        """
        # 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 := _dict.get('id')) is not None:
            args['id'] = 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.

    :param str href: The URL for this instance network interface.
          If this instance has network attachments, this network interface is a
          [read-only
          representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
          of its corresponding network attachment.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a FloatingIPTargetPatchNetworkInterfaceIdentityNetworkInterfaceIdentityByHref object.

        :param str href: The URL for this instance network interface.
               If this instance has network attachments, this network interface is a
               [read-only
               representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
               of its corresponding network attachment.
        """
        # 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 := _dict.get('href')) is not None:
            args['href'] = 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.

    :param str id: The unique identifier for this instance network interface.
          If this instance has network attachments, this network interface is a
          [read-only
          representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
          of its corresponding network attachment and its attached virtual network
          interface, and the identifier is that of the corresponding network attachment.
    """

    def __init__(
        self,
        id: str,
    ) -> None:
        """
        Initialize a FloatingIPTargetPatchNetworkInterfaceIdentityNetworkInterfaceIdentityById object.

        :param str id: The unique identifier for this instance network interface.
               If this instance has network attachments, this network interface is a
               [read-only
               representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
               of its corresponding network attachment and its attached virtual network
               interface, and the identifier is that of the corresponding network
               attachment.
        """
        # 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 := _dict.get('id')) is not None:
            args['id'] = 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 FloatingIPTargetPatchVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByCRN(FloatingIPTargetPatchVirtualNetworkInterfaceIdentity):
    """
    FloatingIPTargetPatchVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByCRN.

    :param str crn: The CRN for this virtual network interface.
    """

    def __init__(
        self,
        crn: str,
    ) -> None:
        """
        Initialize a FloatingIPTargetPatchVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByCRN object.

        :param str crn: The CRN for this virtual network interface.
        """
        # pylint: disable=super-init-not-called
        self.crn = crn

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'FloatingIPTargetPatchVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByCRN':
        """Initialize a FloatingIPTargetPatchVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByCRN object from a json dictionary."""
        args = {}
        if (crn := _dict.get('crn')) is not None:
            args['crn'] = crn
        else:
            raise ValueError('Required property \'crn\' not present in FloatingIPTargetPatchVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByCRN JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a FloatingIPTargetPatchVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByCRN object from 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 FloatingIPTargetPatchVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByCRN object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'FloatingIPTargetPatchVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByCRN') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'FloatingIPTargetPatchVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByCRN') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class FloatingIPTargetPatchVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByHref(FloatingIPTargetPatchVirtualNetworkInterfaceIdentity):
    """
    FloatingIPTargetPatchVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByHref.

    :param str href: The URL for this virtual network interface.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a FloatingIPTargetPatchVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByHref object.

        :param str href: The URL for this virtual network interface.
        """
        # pylint: disable=super-init-not-called
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'FloatingIPTargetPatchVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByHref':
        """Initialize a FloatingIPTargetPatchVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByHref object from a json dictionary."""
        args = {}
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in FloatingIPTargetPatchVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByHref JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a FloatingIPTargetPatchVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByHref object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this FloatingIPTargetPatchVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'FloatingIPTargetPatchVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByHref') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'FloatingIPTargetPatchVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByHref') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class FloatingIPTargetPatchVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityById(FloatingIPTargetPatchVirtualNetworkInterfaceIdentity):
    """
    FloatingIPTargetPatchVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityById.

    :param str id: The unique identifier for this virtual network interface.
    """

    def __init__(
        self,
        id: str,
    ) -> None:
        """
        Initialize a FloatingIPTargetPatchVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityById object.

        :param str id: The unique identifier for this virtual network interface.
        """
        # pylint: disable=super-init-not-called
        self.id = id

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'FloatingIPTargetPatchVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityById':
        """Initialize a FloatingIPTargetPatchVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityById object from a json dictionary."""
        args = {}
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in FloatingIPTargetPatchVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityById JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a FloatingIPTargetPatchVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityById object from 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 FloatingIPTargetPatchVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityById object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'FloatingIPTargetPatchVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityById') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'FloatingIPTargetPatchVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityById') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class FloatingIPTargetPrototypeBareMetalServerNetworkInterfaceIdentityBareMetalServerNetworkInterfaceIdentityByHref(FloatingIPTargetPrototypeBareMetalServerNetworkInterfaceIdentity):
    """
    FloatingIPTargetPrototypeBareMetalServerNetworkInterfaceIdentityBareMetalServerNetworkInterfaceIdentityByHref.

    :param str href: The URL for this bare metal server network interface.
          If this bare metal server has network attachments, this network interface is a
          [read-only
          representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
          of its corresponding network attachment.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a FloatingIPTargetPrototypeBareMetalServerNetworkInterfaceIdentityBareMetalServerNetworkInterfaceIdentityByHref object.

        :param str href: The URL for this bare metal server network interface.
               If this bare metal server has network attachments, this network interface
               is a
               [read-only
               representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
               of its corresponding network attachment.
        """
        # 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 := _dict.get('href')) is not None:
            args['href'] = 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.

    :param str id: The unique identifier for this bare metal server network
          interface.
          If this bare metal server has network attachments, this network interface is a
          [read-only
          representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
          of its corresponding network attachment and its attached virtual network
          interface, and the identifier is that of the corresponding network attachment.
    """

    def __init__(
        self,
        id: str,
    ) -> None:
        """
        Initialize a FloatingIPTargetPrototypeBareMetalServerNetworkInterfaceIdentityBareMetalServerNetworkInterfaceIdentityById object.

        :param str id: The unique identifier for this bare metal server network
               interface.
               If this bare metal server has network attachments, this network interface
               is a
               [read-only
               representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
               of its corresponding network attachment and its attached virtual network
               interface, and the identifier is that of the corresponding network
               attachment.
        """
        # 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 := _dict.get('id')) is not None:
            args['id'] = 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.

    :param str href: The URL for this instance network interface.
          If this instance has network attachments, this network interface is a
          [read-only
          representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
          of its corresponding network attachment.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a FloatingIPTargetPrototypeNetworkInterfaceIdentityNetworkInterfaceIdentityByHref object.

        :param str href: The URL for this instance network interface.
               If this instance has network attachments, this network interface is a
               [read-only
               representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
               of its corresponding network attachment.
        """
        # 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 := _dict.get('href')) is not None:
            args['href'] = 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.

    :param str id: The unique identifier for this instance network interface.
          If this instance has network attachments, this network interface is a
          [read-only
          representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
          of its corresponding network attachment and its attached virtual network
          interface, and the identifier is that of the corresponding network attachment.
    """

    def __init__(
        self,
        id: str,
    ) -> None:
        """
        Initialize a FloatingIPTargetPrototypeNetworkInterfaceIdentityNetworkInterfaceIdentityById object.

        :param str id: The unique identifier for this instance network interface.
               If this instance has network attachments, this network interface is a
               [read-only
               representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
               of its corresponding network attachment and its attached virtual network
               interface, and the identifier is that of the corresponding network
               attachment.
        """
        # 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 := _dict.get('id')) is not None:
            args['id'] = 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 FloatingIPTargetPrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByCRN(FloatingIPTargetPrototypeVirtualNetworkInterfaceIdentity):
    """
    FloatingIPTargetPrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByCRN.

    :param str crn: The CRN for this virtual network interface.
    """

    def __init__(
        self,
        crn: str,
    ) -> None:
        """
        Initialize a FloatingIPTargetPrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByCRN object.

        :param str crn: The CRN for this virtual network interface.
        """
        # pylint: disable=super-init-not-called
        self.crn = crn

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'FloatingIPTargetPrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByCRN':
        """Initialize a FloatingIPTargetPrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByCRN object from a json dictionary."""
        args = {}
        if (crn := _dict.get('crn')) is not None:
            args['crn'] = crn
        else:
            raise ValueError('Required property \'crn\' not present in FloatingIPTargetPrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByCRN JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a FloatingIPTargetPrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByCRN object from 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 FloatingIPTargetPrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByCRN object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'FloatingIPTargetPrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByCRN') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'FloatingIPTargetPrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByCRN') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class FloatingIPTargetPrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByHref(FloatingIPTargetPrototypeVirtualNetworkInterfaceIdentity):
    """
    FloatingIPTargetPrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByHref.

    :param str href: The URL for this virtual network interface.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a FloatingIPTargetPrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByHref object.

        :param str href: The URL for this virtual network interface.
        """
        # pylint: disable=super-init-not-called
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'FloatingIPTargetPrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByHref':
        """Initialize a FloatingIPTargetPrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByHref object from a json dictionary."""
        args = {}
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in FloatingIPTargetPrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByHref JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a FloatingIPTargetPrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByHref object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this FloatingIPTargetPrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'FloatingIPTargetPrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByHref') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'FloatingIPTargetPrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByHref') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class FloatingIPTargetPrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityById(FloatingIPTargetPrototypeVirtualNetworkInterfaceIdentity):
    """
    FloatingIPTargetPrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityById.

    :param str id: The unique identifier for this virtual network interface.
    """

    def __init__(
        self,
        id: str,
    ) -> None:
        """
        Initialize a FloatingIPTargetPrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityById object.

        :param str id: The unique identifier for this virtual network interface.
        """
        # pylint: disable=super-init-not-called
        self.id = id

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'FloatingIPTargetPrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityById':
        """Initialize a FloatingIPTargetPrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityById object from a json dictionary."""
        args = {}
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in FloatingIPTargetPrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityById JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a FloatingIPTargetPrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityById object from 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 FloatingIPTargetPrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityById object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'FloatingIPTargetPrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityById') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'FloatingIPTargetPrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityById') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class FlowLogCollectorTargetPrototypeInstanceIdentityInstanceIdentityByCRN(FlowLogCollectorTargetPrototypeInstanceIdentity):
    """
    FlowLogCollectorTargetPrototypeInstanceIdentityInstanceIdentityByCRN.

    :param 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 := _dict.get('crn')) is not None:
            args['crn'] = 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.

    :param 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 := _dict.get('href')) is not None:
            args['href'] = 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.

    :param 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 := _dict.get('id')) is not None:
            args['id'] = 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 FlowLogCollectorTargetPrototypeInstanceNetworkAttachmentIdentityInstanceNetworkAttachmentIdentityByHref(FlowLogCollectorTargetPrototypeInstanceNetworkAttachmentIdentity):
    """
    FlowLogCollectorTargetPrototypeInstanceNetworkAttachmentIdentityInstanceNetworkAttachmentIdentityByHref.

    :param str href: The URL for this instance network attachment.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a FlowLogCollectorTargetPrototypeInstanceNetworkAttachmentIdentityInstanceNetworkAttachmentIdentityByHref object.

        :param str href: The URL for this instance network attachment.
        """
        # pylint: disable=super-init-not-called
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'FlowLogCollectorTargetPrototypeInstanceNetworkAttachmentIdentityInstanceNetworkAttachmentIdentityByHref':
        """Initialize a FlowLogCollectorTargetPrototypeInstanceNetworkAttachmentIdentityInstanceNetworkAttachmentIdentityByHref object from a json dictionary."""
        args = {}
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in FlowLogCollectorTargetPrototypeInstanceNetworkAttachmentIdentityInstanceNetworkAttachmentIdentityByHref JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a FlowLogCollectorTargetPrototypeInstanceNetworkAttachmentIdentityInstanceNetworkAttachmentIdentityByHref object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this FlowLogCollectorTargetPrototypeInstanceNetworkAttachmentIdentityInstanceNetworkAttachmentIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'FlowLogCollectorTargetPrototypeInstanceNetworkAttachmentIdentityInstanceNetworkAttachmentIdentityByHref') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'FlowLogCollectorTargetPrototypeInstanceNetworkAttachmentIdentityInstanceNetworkAttachmentIdentityByHref') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class FlowLogCollectorTargetPrototypeInstanceNetworkAttachmentIdentityInstanceNetworkAttachmentIdentityById(FlowLogCollectorTargetPrototypeInstanceNetworkAttachmentIdentity):
    """
    FlowLogCollectorTargetPrototypeInstanceNetworkAttachmentIdentityInstanceNetworkAttachmentIdentityById.

    :param str id: The unique identifier for this instance network attachment.
    """

    def __init__(
        self,
        id: str,
    ) -> None:
        """
        Initialize a FlowLogCollectorTargetPrototypeInstanceNetworkAttachmentIdentityInstanceNetworkAttachmentIdentityById object.

        :param str id: The unique identifier for this instance network attachment.
        """
        # pylint: disable=super-init-not-called
        self.id = id

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'FlowLogCollectorTargetPrototypeInstanceNetworkAttachmentIdentityInstanceNetworkAttachmentIdentityById':
        """Initialize a FlowLogCollectorTargetPrototypeInstanceNetworkAttachmentIdentityInstanceNetworkAttachmentIdentityById object from a json dictionary."""
        args = {}
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in FlowLogCollectorTargetPrototypeInstanceNetworkAttachmentIdentityInstanceNetworkAttachmentIdentityById JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a FlowLogCollectorTargetPrototypeInstanceNetworkAttachmentIdentityInstanceNetworkAttachmentIdentityById object from 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 FlowLogCollectorTargetPrototypeInstanceNetworkAttachmentIdentityInstanceNetworkAttachmentIdentityById object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'FlowLogCollectorTargetPrototypeInstanceNetworkAttachmentIdentityInstanceNetworkAttachmentIdentityById') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'FlowLogCollectorTargetPrototypeInstanceNetworkAttachmentIdentityInstanceNetworkAttachmentIdentityById') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class FlowLogCollectorTargetPrototypeNetworkInterfaceIdentityNetworkInterfaceIdentityByHref(FlowLogCollectorTargetPrototypeNetworkInterfaceIdentity):
    """
    FlowLogCollectorTargetPrototypeNetworkInterfaceIdentityNetworkInterfaceIdentityByHref.

    :param str href: The URL for this instance network interface.
          If this instance has network attachments, this network interface is a
          [read-only
          representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
          of its corresponding network attachment.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a FlowLogCollectorTargetPrototypeNetworkInterfaceIdentityNetworkInterfaceIdentityByHref object.

        :param str href: The URL for this instance network interface.
               If this instance has network attachments, this network interface is a
               [read-only
               representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
               of its corresponding network attachment.
        """
        # 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 := _dict.get('href')) is not None:
            args['href'] = 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.

    :param str id: The unique identifier for this instance network interface.
          If this instance has network attachments, this network interface is a
          [read-only
          representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
          of its corresponding network attachment and its attached virtual network
          interface, and the identifier is that of the corresponding network attachment.
    """

    def __init__(
        self,
        id: str,
    ) -> None:
        """
        Initialize a FlowLogCollectorTargetPrototypeNetworkInterfaceIdentityNetworkInterfaceIdentityById object.

        :param str id: The unique identifier for this instance network interface.
               If this instance has network attachments, this network interface is a
               [read-only
               representation](https://cloud.ibm.com/docs/vpc?topic=vpc-vni-about#vni-old-api-clients)
               of its corresponding network attachment and its attached virtual network
               interface, and the identifier is that of the corresponding network
               attachment.
        """
        # 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 := _dict.get('id')) is not None:
            args['id'] = 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.

    :param 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 := _dict.get('crn')) is not None:
            args['crn'] = 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.

    :param 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 := _dict.get('href')) is not None:
            args['href'] = 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.

    :param 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 := _dict.get('id')) is not None:
            args['id'] = 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.

    :param 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 := _dict.get('crn')) is not None:
            args['crn'] = 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.

    :param 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 := _dict.get('href')) is not None:
            args['href'] = 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.

    :param 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 := _dict.get('id')) is not None:
            args['id'] = 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 FlowLogCollectorTargetPrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByCRN(FlowLogCollectorTargetPrototypeVirtualNetworkInterfaceIdentity):
    """
    FlowLogCollectorTargetPrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByCRN.

    :param str crn: The CRN for this virtual network interface.
    """

    def __init__(
        self,
        crn: str,
    ) -> None:
        """
        Initialize a FlowLogCollectorTargetPrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByCRN object.

        :param str crn: The CRN for this virtual network interface.
        """
        # pylint: disable=super-init-not-called
        self.crn = crn

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'FlowLogCollectorTargetPrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByCRN':
        """Initialize a FlowLogCollectorTargetPrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByCRN object from a json dictionary."""
        args = {}
        if (crn := _dict.get('crn')) is not None:
            args['crn'] = crn
        else:
            raise ValueError('Required property \'crn\' not present in FlowLogCollectorTargetPrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByCRN JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a FlowLogCollectorTargetPrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByCRN object from 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 FlowLogCollectorTargetPrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByCRN object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'FlowLogCollectorTargetPrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByCRN') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'FlowLogCollectorTargetPrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByCRN') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class FlowLogCollectorTargetPrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByHref(FlowLogCollectorTargetPrototypeVirtualNetworkInterfaceIdentity):
    """
    FlowLogCollectorTargetPrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByHref.

    :param str href: The URL for this virtual network interface.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a FlowLogCollectorTargetPrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByHref object.

        :param str href: The URL for this virtual network interface.
        """
        # pylint: disable=super-init-not-called
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'FlowLogCollectorTargetPrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByHref':
        """Initialize a FlowLogCollectorTargetPrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByHref object from a json dictionary."""
        args = {}
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in FlowLogCollectorTargetPrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByHref JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a FlowLogCollectorTargetPrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByHref object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this FlowLogCollectorTargetPrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'FlowLogCollectorTargetPrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByHref') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'FlowLogCollectorTargetPrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByHref') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class FlowLogCollectorTargetPrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityById(FlowLogCollectorTargetPrototypeVirtualNetworkInterfaceIdentity):
    """
    FlowLogCollectorTargetPrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityById.

    :param str id: The unique identifier for this virtual network interface.
    """

    def __init__(
        self,
        id: str,
    ) -> None:
        """
        Initialize a FlowLogCollectorTargetPrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityById object.

        :param str id: The unique identifier for this virtual network interface.
        """
        # pylint: disable=super-init-not-called
        self.id = id

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'FlowLogCollectorTargetPrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityById':
        """Initialize a FlowLogCollectorTargetPrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityById object from a json dictionary."""
        args = {}
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in FlowLogCollectorTargetPrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityById JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a FlowLogCollectorTargetPrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityById object from 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 FlowLogCollectorTargetPrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityById object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'FlowLogCollectorTargetPrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityById') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'FlowLogCollectorTargetPrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityById') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceClusterNetworkAttachmentPrototypeClusterNetworkInterfaceClusterNetworkInterfaceIdentityClusterNetworkInterfaceIdentityByHref(InstanceClusterNetworkAttachmentPrototypeClusterNetworkInterfaceClusterNetworkInterfaceIdentity):
    """
    InstanceClusterNetworkAttachmentPrototypeClusterNetworkInterfaceClusterNetworkInterfaceIdentityClusterNetworkInterfaceIdentityByHref.

    :param str href: The URL for this cluster network interface.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a InstanceClusterNetworkAttachmentPrototypeClusterNetworkInterfaceClusterNetworkInterfaceIdentityClusterNetworkInterfaceIdentityByHref object.

        :param str href: The URL for this cluster network interface.
        """
        # pylint: disable=super-init-not-called
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceClusterNetworkAttachmentPrototypeClusterNetworkInterfaceClusterNetworkInterfaceIdentityClusterNetworkInterfaceIdentityByHref':
        """Initialize a InstanceClusterNetworkAttachmentPrototypeClusterNetworkInterfaceClusterNetworkInterfaceIdentityClusterNetworkInterfaceIdentityByHref object from a json dictionary."""
        args = {}
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in InstanceClusterNetworkAttachmentPrototypeClusterNetworkInterfaceClusterNetworkInterfaceIdentityClusterNetworkInterfaceIdentityByHref JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceClusterNetworkAttachmentPrototypeClusterNetworkInterfaceClusterNetworkInterfaceIdentityClusterNetworkInterfaceIdentityByHref object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceClusterNetworkAttachmentPrototypeClusterNetworkInterfaceClusterNetworkInterfaceIdentityClusterNetworkInterfaceIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceClusterNetworkAttachmentPrototypeClusterNetworkInterfaceClusterNetworkInterfaceIdentityClusterNetworkInterfaceIdentityByHref') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceClusterNetworkAttachmentPrototypeClusterNetworkInterfaceClusterNetworkInterfaceIdentityClusterNetworkInterfaceIdentityByHref') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceClusterNetworkAttachmentPrototypeClusterNetworkInterfaceClusterNetworkInterfaceIdentityClusterNetworkInterfaceIdentityById(InstanceClusterNetworkAttachmentPrototypeClusterNetworkInterfaceClusterNetworkInterfaceIdentity):
    """
    InstanceClusterNetworkAttachmentPrototypeClusterNetworkInterfaceClusterNetworkInterfaceIdentityClusterNetworkInterfaceIdentityById.

    :param str id: The unique identifier for this cluster network interface.
    """

    def __init__(
        self,
        id: str,
    ) -> None:
        """
        Initialize a InstanceClusterNetworkAttachmentPrototypeClusterNetworkInterfaceClusterNetworkInterfaceIdentityClusterNetworkInterfaceIdentityById object.

        :param str id: The unique identifier for this cluster network interface.
        """
        # pylint: disable=super-init-not-called
        self.id = id

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceClusterNetworkAttachmentPrototypeClusterNetworkInterfaceClusterNetworkInterfaceIdentityClusterNetworkInterfaceIdentityById':
        """Initialize a InstanceClusterNetworkAttachmentPrototypeClusterNetworkInterfaceClusterNetworkInterfaceIdentityClusterNetworkInterfaceIdentityById object from a json dictionary."""
        args = {}
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in InstanceClusterNetworkAttachmentPrototypeClusterNetworkInterfaceClusterNetworkInterfaceIdentityClusterNetworkInterfaceIdentityById JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceClusterNetworkAttachmentPrototypeClusterNetworkInterfaceClusterNetworkInterfaceIdentityClusterNetworkInterfaceIdentityById object from 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 InstanceClusterNetworkAttachmentPrototypeClusterNetworkInterfaceClusterNetworkInterfaceIdentityClusterNetworkInterfaceIdentityById object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceClusterNetworkAttachmentPrototypeClusterNetworkInterfaceClusterNetworkInterfaceIdentityClusterNetworkInterfaceIdentityById') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceClusterNetworkAttachmentPrototypeClusterNetworkInterfaceClusterNetworkInterfaceIdentityClusterNetworkInterfaceIdentityById') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceGroupManagerActionPrototypeScheduledActionPrototypeByCronSpec(InstanceGroupManagerActionPrototypeScheduledActionPrototype):
    """
    InstanceGroupManagerActionPrototypeScheduledActionPrototypeByCronSpec.

    :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.
    """

    def __init__(
        self,
        *,
        name: Optional[str] = None,
        cron_spec: Optional[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.

    :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.
    """

    def __init__(
        self,
        *,
        name: Optional[str] = None,
        run_at: Optional[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.

    :param bool auto_delete: Indicates whether this scheduled action will be
          automatically deleted after it has completed and `auto_delete_timeout` hours
          have passed.
    :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.
    :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
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :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.
    :param 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: Optional[str] = None,
        last_applied_at: Optional[datetime] = None,
        next_run_at: Optional[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.
        :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.
        :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
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :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 := _dict.get('auto_delete')) is not None:
            args['auto_delete'] = auto_delete
        else:
            raise ValueError('Required property \'auto_delete\' not present in InstanceGroupManagerActionScheduledActionGroupTarget JSON')
        if (auto_delete_timeout := _dict.get('auto_delete_timeout')) is not None:
            args['auto_delete_timeout'] = auto_delete_timeout
        else:
            raise ValueError('Required property \'auto_delete_timeout\' not present in InstanceGroupManagerActionScheduledActionGroupTarget JSON')
        if (created_at := _dict.get('created_at')) is not None:
            args['created_at'] = string_to_datetime(created_at)
        else:
            raise ValueError('Required property \'created_at\' not present in InstanceGroupManagerActionScheduledActionGroupTarget JSON')
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in InstanceGroupManagerActionScheduledActionGroupTarget JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in InstanceGroupManagerActionScheduledActionGroupTarget JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in InstanceGroupManagerActionScheduledActionGroupTarget JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = resource_type
        else:
            raise ValueError('Required property \'resource_type\' not present in InstanceGroupManagerActionScheduledActionGroupTarget JSON')
        if (status := _dict.get('status')) is not None:
            args['status'] = status
        else:
            raise ValueError('Required property \'status\' not present in InstanceGroupManagerActionScheduledActionGroupTarget JSON')
        if (updated_at := _dict.get('updated_at')) is not None:
            args['updated_at'] = string_to_datetime(updated_at)
        else:
            raise ValueError('Required property \'updated_at\' not present in InstanceGroupManagerActionScheduledActionGroupTarget JSON')
        if (action_type := _dict.get('action_type')) is not None:
            args['action_type'] = action_type
        else:
            raise ValueError('Required property \'action_type\' not present in InstanceGroupManagerActionScheduledActionGroupTarget JSON')
        if (cron_spec := _dict.get('cron_spec')) is not None:
            args['cron_spec'] = cron_spec
        if (last_applied_at := _dict.get('last_applied_at')) is not None:
            args['last_applied_at'] = string_to_datetime(last_applied_at)
        if (next_run_at := _dict.get('next_run_at')) is not None:
            args['next_run_at'] = string_to_datetime(next_run_at)
        if (group := _dict.get('group')) is not None:
            args['group'] = InstanceGroupManagerScheduledActionGroup.from_dict(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
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        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.

    :param bool auto_delete: Indicates whether this scheduled action will be
          automatically deleted after it has completed and `auto_delete_timeout` hours
          have passed.
    :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.
    :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
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :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.
    :param 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: Optional[str] = None,
        last_applied_at: Optional[datetime] = None,
        next_run_at: Optional[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.
        :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.
        :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
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :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 := _dict.get('auto_delete')) is not None:
            args['auto_delete'] = auto_delete
        else:
            raise ValueError('Required property \'auto_delete\' not present in InstanceGroupManagerActionScheduledActionManagerTarget JSON')
        if (auto_delete_timeout := _dict.get('auto_delete_timeout')) is not None:
            args['auto_delete_timeout'] = auto_delete_timeout
        else:
            raise ValueError('Required property \'auto_delete_timeout\' not present in InstanceGroupManagerActionScheduledActionManagerTarget JSON')
        if (created_at := _dict.get('created_at')) is not None:
            args['created_at'] = string_to_datetime(created_at)
        else:
            raise ValueError('Required property \'created_at\' not present in InstanceGroupManagerActionScheduledActionManagerTarget JSON')
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in InstanceGroupManagerActionScheduledActionManagerTarget JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in InstanceGroupManagerActionScheduledActionManagerTarget JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in InstanceGroupManagerActionScheduledActionManagerTarget JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = resource_type
        else:
            raise ValueError('Required property \'resource_type\' not present in InstanceGroupManagerActionScheduledActionManagerTarget JSON')
        if (status := _dict.get('status')) is not None:
            args['status'] = status
        else:
            raise ValueError('Required property \'status\' not present in InstanceGroupManagerActionScheduledActionManagerTarget JSON')
        if (updated_at := _dict.get('updated_at')) is not None:
            args['updated_at'] = string_to_datetime(updated_at)
        else:
            raise ValueError('Required property \'updated_at\' not present in InstanceGroupManagerActionScheduledActionManagerTarget JSON')
        if (action_type := _dict.get('action_type')) is not None:
            args['action_type'] = action_type
        else:
            raise ValueError('Required property \'action_type\' not present in InstanceGroupManagerActionScheduledActionManagerTarget JSON')
        if (cron_spec := _dict.get('cron_spec')) is not None:
            args['cron_spec'] = cron_spec
        if (last_applied_at := _dict.get('last_applied_at')) is not None:
            args['last_applied_at'] = string_to_datetime(last_applied_at)
        if (next_run_at := _dict.get('next_run_at')) is not None:
            args['next_run_at'] = string_to_datetime(next_run_at)
        if (manager := _dict.get('manager')) is not None:
            args['manager'] = 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
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        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.

    :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.
    :param str href: The URL for this instance group manager.
    """

    def __init__(
        self,
        href: str,
        *,
        max_membership_count: Optional[int] = None,
        min_membership_count: Optional[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 := _dict.get('max_membership_count')) is not None:
            args['max_membership_count'] = max_membership_count
        if (min_membership_count := _dict.get('min_membership_count')) is not None:
            args['min_membership_count'] = min_membership_count
        if (href := _dict.get('href')) is not None:
            args['href'] = 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.

    :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.
    :param str id: The unique identifier for this instance group manager.
    """

    def __init__(
        self,
        id: str,
        *,
        max_membership_count: Optional[int] = None,
        min_membership_count: Optional[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 := _dict.get('max_membership_count')) is not None:
            args['max_membership_count'] = max_membership_count
        if (min_membership_count := _dict.get('min_membership_count')) is not None:
            args['min_membership_count'] = min_membership_count
        if (id := _dict.get('id')) is not None:
            args['id'] = 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 InstanceNetworkAttachmentPrototypeVirtualNetworkInterfaceVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByCRN(InstanceNetworkAttachmentPrototypeVirtualNetworkInterfaceVirtualNetworkInterfaceIdentity):
    """
    InstanceNetworkAttachmentPrototypeVirtualNetworkInterfaceVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByCRN.

    :param str crn: The CRN for this virtual network interface.
    """

    def __init__(
        self,
        crn: str,
    ) -> None:
        """
        Initialize a InstanceNetworkAttachmentPrototypeVirtualNetworkInterfaceVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByCRN object.

        :param str crn: The CRN for this virtual network interface.
        """
        # pylint: disable=super-init-not-called
        self.crn = crn

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceNetworkAttachmentPrototypeVirtualNetworkInterfaceVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByCRN':
        """Initialize a InstanceNetworkAttachmentPrototypeVirtualNetworkInterfaceVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByCRN object from a json dictionary."""
        args = {}
        if (crn := _dict.get('crn')) is not None:
            args['crn'] = crn
        else:
            raise ValueError('Required property \'crn\' not present in InstanceNetworkAttachmentPrototypeVirtualNetworkInterfaceVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByCRN JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceNetworkAttachmentPrototypeVirtualNetworkInterfaceVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByCRN object from 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 InstanceNetworkAttachmentPrototypeVirtualNetworkInterfaceVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByCRN object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceNetworkAttachmentPrototypeVirtualNetworkInterfaceVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByCRN') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceNetworkAttachmentPrototypeVirtualNetworkInterfaceVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByCRN') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceNetworkAttachmentPrototypeVirtualNetworkInterfaceVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByHref(InstanceNetworkAttachmentPrototypeVirtualNetworkInterfaceVirtualNetworkInterfaceIdentity):
    """
    InstanceNetworkAttachmentPrototypeVirtualNetworkInterfaceVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByHref.

    :param str href: The URL for this virtual network interface.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a InstanceNetworkAttachmentPrototypeVirtualNetworkInterfaceVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByHref object.

        :param str href: The URL for this virtual network interface.
        """
        # pylint: disable=super-init-not-called
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceNetworkAttachmentPrototypeVirtualNetworkInterfaceVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByHref':
        """Initialize a InstanceNetworkAttachmentPrototypeVirtualNetworkInterfaceVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByHref object from a json dictionary."""
        args = {}
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in InstanceNetworkAttachmentPrototypeVirtualNetworkInterfaceVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByHref JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceNetworkAttachmentPrototypeVirtualNetworkInterfaceVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByHref object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceNetworkAttachmentPrototypeVirtualNetworkInterfaceVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceNetworkAttachmentPrototypeVirtualNetworkInterfaceVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByHref') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceNetworkAttachmentPrototypeVirtualNetworkInterfaceVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByHref') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstanceNetworkAttachmentPrototypeVirtualNetworkInterfaceVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityById(InstanceNetworkAttachmentPrototypeVirtualNetworkInterfaceVirtualNetworkInterfaceIdentity):
    """
    InstanceNetworkAttachmentPrototypeVirtualNetworkInterfaceVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityById.

    :param str id: The unique identifier for this virtual network interface.
    """

    def __init__(
        self,
        id: str,
    ) -> None:
        """
        Initialize a InstanceNetworkAttachmentPrototypeVirtualNetworkInterfaceVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityById object.

        :param str id: The unique identifier for this virtual network interface.
        """
        # pylint: disable=super-init-not-called
        self.id = id

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceNetworkAttachmentPrototypeVirtualNetworkInterfaceVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityById':
        """Initialize a InstanceNetworkAttachmentPrototypeVirtualNetworkInterfaceVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityById object from a json dictionary."""
        args = {}
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in InstanceNetworkAttachmentPrototypeVirtualNetworkInterfaceVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityById JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceNetworkAttachmentPrototypeVirtualNetworkInterfaceVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityById object from 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 InstanceNetworkAttachmentPrototypeVirtualNetworkInterfaceVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityById object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceNetworkAttachmentPrototypeVirtualNetworkInterfaceVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityById') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceNetworkAttachmentPrototypeVirtualNetworkInterfaceVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityById') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class InstancePlacementTargetPatchDedicatedHostGroupIdentityDedicatedHostGroupIdentityByCRN(InstancePlacementTargetPatchDedicatedHostGroupIdentity):
    """
    InstancePlacementTargetPatchDedicatedHostGroupIdentityDedicatedHostGroupIdentityByCRN.

    :param 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 := _dict.get('crn')) is not None:
            args['crn'] = 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.

    :param 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 := _dict.get('href')) is not None:
            args['href'] = 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.

    :param 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 := _dict.get('id')) is not None:
            args['id'] = 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.

    :param 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 := _dict.get('crn')) is not None:
            args['crn'] = 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.

    :param 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 := _dict.get('href')) is not None:
            args['href'] = 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.

    :param 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 := _dict.get('id')) is not None:
            args['id'] = 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.

    :param 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 := _dict.get('crn')) is not None:
            args['crn'] = 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.

    :param 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 := _dict.get('href')) is not None:
            args['href'] = 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.

    :param 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 := _dict.get('id')) is not None:
            args['id'] = 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.

    :param 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 := _dict.get('crn')) is not None:
            args['crn'] = 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.

    :param 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 := _dict.get('href')) is not None:
            args['href'] = 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.

    :param 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 := _dict.get('id')) is not None:
            args['id'] = 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.

    :param 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 := _dict.get('crn')) is not None:
            args['crn'] = 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.

    :param 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 := _dict.get('href')) is not None:
            args['href'] = 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.

    :param 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 := _dict.get('id')) is not None:
            args['id'] = 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 InstancePrototypeInstanceByCatalogOfferingInstanceByCatalogOfferingInstanceByNetworkAttachment(InstancePrototypeInstanceByCatalogOffering):
    """
    InstancePrototypeInstanceByCatalogOfferingInstanceByCatalogOfferingInstanceByNetworkAttachment.

    :param InstanceAvailabilityPolicyPrototype availability_policy: (optional) The
          availability policy to use for this virtual server instance.
    :param List[InstanceClusterNetworkAttachmentPrototypeInstanceContext]
          cluster_network_attachments: (optional) The cluster network attachments to
          create for this virtual server instance. A cluster network attachment represents
          a device that is connected to a cluster network. The number of network
          attachments must match one of the values from the instance profile's
          `cluster_network_attachment_count` before the instance can be started.
    :param str confidential_compute_mode: (optional) The confidential compute mode
          to use for this virtual server instance.
          If unspecified, the default confidential compute mode from the profile will be
          used.
    :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 bool enable_secure_boot: (optional) Indicates whether secure boot is
          enabled for this virtual server instance.
          If unspecified, the default secure boot mode from the profile will be used.
    :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.
          If specified, `reservation_affinity.policy` must be `disabled`.
    :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 InstanceReservationAffinityPrototype reservation_affinity: (optional)
    :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
          attachments or instance network interfaces.
    :param VolumeAttachmentPrototypeInstanceByImageContext boot_volume_attachment:
          (optional) The boot volume attachment to create for the virtual server instance.
    :param InstanceCatalogOfferingPrototype catalog_offering:
    :param ZoneIdentity zone: The zone this virtual server instance will reside in.
    :param List[InstanceNetworkAttachmentPrototype] network_attachments: (optional)
          The additional network attachments to create for the virtual server instance.
    :param InstanceNetworkAttachmentPrototype primary_network_attachment: The
          primary network attachment to create for the virtual server instance.
    """

    def __init__(
        self,
        catalog_offering: 'InstanceCatalogOfferingPrototype',
        zone: 'ZoneIdentity',
        primary_network_attachment: 'InstanceNetworkAttachmentPrototype',
        *,
        availability_policy: Optional['InstanceAvailabilityPolicyPrototype'] = None,
        cluster_network_attachments: Optional[List['InstanceClusterNetworkAttachmentPrototypeInstanceContext']] = None,
        confidential_compute_mode: Optional[str] = None,
        default_trusted_profile: Optional['InstanceDefaultTrustedProfilePrototype'] = None,
        enable_secure_boot: Optional[bool] = None,
        keys: Optional[List['KeyIdentity']] = None,
        metadata_service: Optional['InstanceMetadataServicePrototype'] = None,
        name: Optional[str] = None,
        placement_target: Optional['InstancePlacementTargetPrototype'] = None,
        profile: Optional['InstanceProfileIdentity'] = None,
        reservation_affinity: Optional['InstanceReservationAffinityPrototype'] = None,
        resource_group: Optional['ResourceGroupIdentity'] = None,
        total_volume_bandwidth: Optional[int] = None,
        user_data: Optional[str] = None,
        volume_attachments: Optional[List['VolumeAttachmentPrototype']] = None,
        vpc: Optional['VPCIdentity'] = None,
        boot_volume_attachment: Optional['VolumeAttachmentPrototypeInstanceByImageContext'] = None,
        network_attachments: Optional[List['InstanceNetworkAttachmentPrototype']] = None,
    ) -> None:
        """
        Initialize a InstancePrototypeInstanceByCatalogOfferingInstanceByCatalogOfferingInstanceByNetworkAttachment object.

        :param InstanceCatalogOfferingPrototype catalog_offering:
        :param ZoneIdentity zone: The zone this virtual server instance will reside
               in.
        :param InstanceNetworkAttachmentPrototype primary_network_attachment: The
               primary network attachment to create for the virtual server instance.
        :param InstanceAvailabilityPolicyPrototype availability_policy: (optional)
               The availability policy to use for this virtual server instance.
        :param List[InstanceClusterNetworkAttachmentPrototypeInstanceContext]
               cluster_network_attachments: (optional) The cluster network attachments to
               create for this virtual server instance. A cluster network attachment
               represents a device that is connected to a cluster network. The number of
               network attachments must match one of the values from the instance
               profile's `cluster_network_attachment_count` before the instance can be
               started.
        :param str confidential_compute_mode: (optional) The confidential compute
               mode to use for this virtual server instance.
               If unspecified, the default confidential compute mode from the profile will
               be used.
        :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 bool enable_secure_boot: (optional) Indicates whether secure boot is
               enabled for this virtual server instance.
               If unspecified, the default secure boot mode from the profile will be used.
        :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.
               If specified, `reservation_affinity.policy` must be `disabled`.
        :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 InstanceReservationAffinityPrototype reservation_affinity:
               (optional)
        :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
               attachments or instance network interfaces.
        :param VolumeAttachmentPrototypeInstanceByImageContext
               boot_volume_attachment: (optional) The boot volume attachment to create for
               the virtual server instance.
        :param List[InstanceNetworkAttachmentPrototype] network_attachments:
               (optional) The additional network attachments to create for the virtual
               server instance.
        """
        # pylint: disable=super-init-not-called
        self.availability_policy = availability_policy
        self.cluster_network_attachments = cluster_network_attachments
        self.confidential_compute_mode = confidential_compute_mode
        self.default_trusted_profile = default_trusted_profile
        self.enable_secure_boot = enable_secure_boot
        self.keys = keys
        self.metadata_service = metadata_service
        self.name = name
        self.placement_target = placement_target
        self.profile = profile
        self.reservation_affinity = reservation_affinity
        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.zone = zone
        self.network_attachments = network_attachments
        self.primary_network_attachment = primary_network_attachment

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstancePrototypeInstanceByCatalogOfferingInstanceByCatalogOfferingInstanceByNetworkAttachment':
        """Initialize a InstancePrototypeInstanceByCatalogOfferingInstanceByCatalogOfferingInstanceByNetworkAttachment object from a json dictionary."""
        args = {}
        if (availability_policy := _dict.get('availability_policy')) is not None:
            args['availability_policy'] = InstanceAvailabilityPolicyPrototype.from_dict(availability_policy)
        if (cluster_network_attachments := _dict.get('cluster_network_attachments')) is not None:
            args['cluster_network_attachments'] = [InstanceClusterNetworkAttachmentPrototypeInstanceContext.from_dict(v) for v in cluster_network_attachments]
        if (confidential_compute_mode := _dict.get('confidential_compute_mode')) is not None:
            args['confidential_compute_mode'] = confidential_compute_mode
        if (default_trusted_profile := _dict.get('default_trusted_profile')) is not None:
            args['default_trusted_profile'] = InstanceDefaultTrustedProfilePrototype.from_dict(default_trusted_profile)
        if (enable_secure_boot := _dict.get('enable_secure_boot')) is not None:
            args['enable_secure_boot'] = enable_secure_boot
        if (keys := _dict.get('keys')) is not None:
            args['keys'] = keys
        if (metadata_service := _dict.get('metadata_service')) is not None:
            args['metadata_service'] = InstanceMetadataServicePrototype.from_dict(metadata_service)
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        if (placement_target := _dict.get('placement_target')) is not None:
            args['placement_target'] = placement_target
        if (profile := _dict.get('profile')) is not None:
            args['profile'] = profile
        if (reservation_affinity := _dict.get('reservation_affinity')) is not None:
            args['reservation_affinity'] = InstanceReservationAffinityPrototype.from_dict(reservation_affinity)
        if (resource_group := _dict.get('resource_group')) is not None:
            args['resource_group'] = resource_group
        if (total_volume_bandwidth := _dict.get('total_volume_bandwidth')) is not None:
            args['total_volume_bandwidth'] = total_volume_bandwidth
        if (user_data := _dict.get('user_data')) is not None:
            args['user_data'] = user_data
        if (volume_attachments := _dict.get('volume_attachments')) is not None:
            args['volume_attachments'] = [VolumeAttachmentPrototype.from_dict(v) for v in volume_attachments]
        if (vpc := _dict.get('vpc')) is not None:
            args['vpc'] = vpc
        if (boot_volume_attachment := _dict.get('boot_volume_attachment')) is not None:
            args['boot_volume_attachment'] = VolumeAttachmentPrototypeInstanceByImageContext.from_dict(boot_volume_attachment)
        if (catalog_offering := _dict.get('catalog_offering')) is not None:
            args['catalog_offering'] = catalog_offering
        else:
            raise ValueError('Required property \'catalog_offering\' not present in InstancePrototypeInstanceByCatalogOfferingInstanceByCatalogOfferingInstanceByNetworkAttachment JSON')
        if (zone := _dict.get('zone')) is not None:
            args['zone'] = zone
        else:
            raise ValueError('Required property \'zone\' not present in InstancePrototypeInstanceByCatalogOfferingInstanceByCatalogOfferingInstanceByNetworkAttachment JSON')
        if (network_attachments := _dict.get('network_attachments')) is not None:
            args['network_attachments'] = [InstanceNetworkAttachmentPrototype.from_dict(v) for v in network_attachments]
        if (primary_network_attachment := _dict.get('primary_network_attachment')) is not None:
            args['primary_network_attachment'] = InstanceNetworkAttachmentPrototype.from_dict(primary_network_attachment)
        else:
            raise ValueError('Required property \'primary_network_attachment\' not present in InstancePrototypeInstanceByCatalogOfferingInstanceByCatalogOfferingInstanceByNetworkAttachment JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstancePrototypeInstanceByCatalogOfferingInstanceByCatalogOfferingInstanceByNetworkAttachment object from 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, 'cluster_network_attachments') and self.cluster_network_attachments is not None:
            cluster_network_attachments_list = []
            for v in self.cluster_network_attachments:
                if isinstance(v, dict):
                    cluster_network_attachments_list.append(v)
                else:
                    cluster_network_attachments_list.append(v.to_dict())
            _dict['cluster_network_attachments'] = cluster_network_attachments_list
        if hasattr(self, 'confidential_compute_mode') and self.confidential_compute_mode is not None:
            _dict['confidential_compute_mode'] = self.confidential_compute_mode
        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, 'enable_secure_boot') and self.enable_secure_boot is not None:
            _dict['enable_secure_boot'] = self.enable_secure_boot
        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, 'reservation_affinity') and self.reservation_affinity is not None:
            if isinstance(self.reservation_affinity, dict):
                _dict['reservation_affinity'] = self.reservation_affinity
            else:
                _dict['reservation_affinity'] = self.reservation_affinity.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, '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, 'network_attachments') and self.network_attachments is not None:
            network_attachments_list = []
            for v in self.network_attachments:
                if isinstance(v, dict):
                    network_attachments_list.append(v)
                else:
                    network_attachments_list.append(v.to_dict())
            _dict['network_attachments'] = network_attachments_list
        if hasattr(self, 'primary_network_attachment') and self.primary_network_attachment is not None:
            if isinstance(self.primary_network_attachment, dict):
                _dict['primary_network_attachment'] = self.primary_network_attachment
            else:
                _dict['primary_network_attachment'] = self.primary_network_attachment.to_dict()
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstancePrototypeInstanceByCatalogOfferingInstanceByCatalogOfferingInstanceByNetworkAttachment object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstancePrototypeInstanceByCatalogOfferingInstanceByCatalogOfferingInstanceByNetworkAttachment') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstancePrototypeInstanceByCatalogOfferingInstanceByCatalogOfferingInstanceByNetworkAttachment') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ConfidentialComputeModeEnum(str, Enum):
        """
        The confidential compute mode to use for this virtual server instance.
        If unspecified, the default confidential compute mode from the profile will be
        used.
        """

        DISABLED = 'disabled'
        SGX = 'sgx'



class InstancePrototypeInstanceByCatalogOfferingInstanceByCatalogOfferingInstanceByNetworkInterface(InstancePrototypeInstanceByCatalogOffering):
    """
    InstancePrototypeInstanceByCatalogOfferingInstanceByCatalogOfferingInstanceByNetworkInterface.

    :param InstanceAvailabilityPolicyPrototype availability_policy: (optional) The
          availability policy to use for this virtual server instance.
    :param List[InstanceClusterNetworkAttachmentPrototypeInstanceContext]
          cluster_network_attachments: (optional) The cluster network attachments to
          create for this virtual server instance. A cluster network attachment represents
          a device that is connected to a cluster network. The number of network
          attachments must match one of the values from the instance profile's
          `cluster_network_attachment_count` before the instance can be started.
    :param str confidential_compute_mode: (optional) The confidential compute mode
          to use for this virtual server instance.
          If unspecified, the default confidential compute mode from the profile will be
          used.
    :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 bool enable_secure_boot: (optional) Indicates whether secure boot is
          enabled for this virtual server instance.
          If unspecified, the default secure boot mode from the profile will be used.
    :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.
          If specified, `reservation_affinity.policy` must be `disabled`.
    :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 InstanceReservationAffinityPrototype reservation_affinity: (optional)
    :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
          attachments or instance network interfaces.
    :param VolumeAttachmentPrototypeInstanceByImageContext boot_volume_attachment:
          (optional) The boot volume attachment to create for the virtual server instance.
    :param InstanceCatalogOfferingPrototype catalog_offering:
    :param ZoneIdentity zone: The zone this virtual server instance will reside in.
    :param List[NetworkInterfacePrototype] network_interfaces: (optional) The
          additional instance network interfaces to create.
    :param NetworkInterfacePrototype primary_network_interface: The primary instance
          network interface to create.
    """

    def __init__(
        self,
        catalog_offering: 'InstanceCatalogOfferingPrototype',
        zone: 'ZoneIdentity',
        primary_network_interface: 'NetworkInterfacePrototype',
        *,
        availability_policy: Optional['InstanceAvailabilityPolicyPrototype'] = None,
        cluster_network_attachments: Optional[List['InstanceClusterNetworkAttachmentPrototypeInstanceContext']] = None,
        confidential_compute_mode: Optional[str] = None,
        default_trusted_profile: Optional['InstanceDefaultTrustedProfilePrototype'] = None,
        enable_secure_boot: Optional[bool] = None,
        keys: Optional[List['KeyIdentity']] = None,
        metadata_service: Optional['InstanceMetadataServicePrototype'] = None,
        name: Optional[str] = None,
        placement_target: Optional['InstancePlacementTargetPrototype'] = None,
        profile: Optional['InstanceProfileIdentity'] = None,
        reservation_affinity: Optional['InstanceReservationAffinityPrototype'] = None,
        resource_group: Optional['ResourceGroupIdentity'] = None,
        total_volume_bandwidth: Optional[int] = None,
        user_data: Optional[str] = None,
        volume_attachments: Optional[List['VolumeAttachmentPrototype']] = None,
        vpc: Optional['VPCIdentity'] = None,
        boot_volume_attachment: Optional['VolumeAttachmentPrototypeInstanceByImageContext'] = None,
        network_interfaces: Optional[List['NetworkInterfacePrototype']] = None,
    ) -> None:
        """
        Initialize a InstancePrototypeInstanceByCatalogOfferingInstanceByCatalogOfferingInstanceByNetworkInterface object.

        :param InstanceCatalogOfferingPrototype catalog_offering:
        :param ZoneIdentity zone: The zone this virtual server instance will reside
               in.
        :param NetworkInterfacePrototype primary_network_interface: The primary
               instance network interface to create.
        :param InstanceAvailabilityPolicyPrototype availability_policy: (optional)
               The availability policy to use for this virtual server instance.
        :param List[InstanceClusterNetworkAttachmentPrototypeInstanceContext]
               cluster_network_attachments: (optional) The cluster network attachments to
               create for this virtual server instance. A cluster network attachment
               represents a device that is connected to a cluster network. The number of
               network attachments must match one of the values from the instance
               profile's `cluster_network_attachment_count` before the instance can be
               started.
        :param str confidential_compute_mode: (optional) The confidential compute
               mode to use for this virtual server instance.
               If unspecified, the default confidential compute mode from the profile will
               be used.
        :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 bool enable_secure_boot: (optional) Indicates whether secure boot is
               enabled for this virtual server instance.
               If unspecified, the default secure boot mode from the profile will be used.
        :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.
               If specified, `reservation_affinity.policy` must be `disabled`.
        :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 InstanceReservationAffinityPrototype reservation_affinity:
               (optional)
        :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
               attachments or 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.cluster_network_attachments = cluster_network_attachments
        self.confidential_compute_mode = confidential_compute_mode
        self.default_trusted_profile = default_trusted_profile
        self.enable_secure_boot = enable_secure_boot
        self.keys = keys
        self.metadata_service = metadata_service
        self.name = name
        self.placement_target = placement_target
        self.profile = profile
        self.reservation_affinity = reservation_affinity
        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.zone = zone
        self.network_interfaces = network_interfaces
        self.primary_network_interface = primary_network_interface

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstancePrototypeInstanceByCatalogOfferingInstanceByCatalogOfferingInstanceByNetworkInterface':
        """Initialize a InstancePrototypeInstanceByCatalogOfferingInstanceByCatalogOfferingInstanceByNetworkInterface object from a json dictionary."""
        args = {}
        if (availability_policy := _dict.get('availability_policy')) is not None:
            args['availability_policy'] = InstanceAvailabilityPolicyPrototype.from_dict(availability_policy)
        if (cluster_network_attachments := _dict.get('cluster_network_attachments')) is not None:
            args['cluster_network_attachments'] = [InstanceClusterNetworkAttachmentPrototypeInstanceContext.from_dict(v) for v in cluster_network_attachments]
        if (confidential_compute_mode := _dict.get('confidential_compute_mode')) is not None:
            args['confidential_compute_mode'] = confidential_compute_mode
        if (default_trusted_profile := _dict.get('default_trusted_profile')) is not None:
            args['default_trusted_profile'] = InstanceDefaultTrustedProfilePrototype.from_dict(default_trusted_profile)
        if (enable_secure_boot := _dict.get('enable_secure_boot')) is not None:
            args['enable_secure_boot'] = enable_secure_boot
        if (keys := _dict.get('keys')) is not None:
            args['keys'] = keys
        if (metadata_service := _dict.get('metadata_service')) is not None:
            args['metadata_service'] = InstanceMetadataServicePrototype.from_dict(metadata_service)
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        if (placement_target := _dict.get('placement_target')) is not None:
            args['placement_target'] = placement_target
        if (profile := _dict.get('profile')) is not None:
            args['profile'] = profile
        if (reservation_affinity := _dict.get('reservation_affinity')) is not None:
            args['reservation_affinity'] = InstanceReservationAffinityPrototype.from_dict(reservation_affinity)
        if (resource_group := _dict.get('resource_group')) is not None:
            args['resource_group'] = resource_group
        if (total_volume_bandwidth := _dict.get('total_volume_bandwidth')) is not None:
            args['total_volume_bandwidth'] = total_volume_bandwidth
        if (user_data := _dict.get('user_data')) is not None:
            args['user_data'] = user_data
        if (volume_attachments := _dict.get('volume_attachments')) is not None:
            args['volume_attachments'] = [VolumeAttachmentPrototype.from_dict(v) for v in volume_attachments]
        if (vpc := _dict.get('vpc')) is not None:
            args['vpc'] = vpc
        if (boot_volume_attachment := _dict.get('boot_volume_attachment')) is not None:
            args['boot_volume_attachment'] = VolumeAttachmentPrototypeInstanceByImageContext.from_dict(boot_volume_attachment)
        if (catalog_offering := _dict.get('catalog_offering')) is not None:
            args['catalog_offering'] = catalog_offering
        else:
            raise ValueError('Required property \'catalog_offering\' not present in InstancePrototypeInstanceByCatalogOfferingInstanceByCatalogOfferingInstanceByNetworkInterface JSON')
        if (zone := _dict.get('zone')) is not None:
            args['zone'] = zone
        else:
            raise ValueError('Required property \'zone\' not present in InstancePrototypeInstanceByCatalogOfferingInstanceByCatalogOfferingInstanceByNetworkInterface JSON')
        if (network_interfaces := _dict.get('network_interfaces')) is not None:
            args['network_interfaces'] = [NetworkInterfacePrototype.from_dict(v) for v in network_interfaces]
        if (primary_network_interface := _dict.get('primary_network_interface')) is not None:
            args['primary_network_interface'] = NetworkInterfacePrototype.from_dict(primary_network_interface)
        else:
            raise ValueError('Required property \'primary_network_interface\' not present in InstancePrototypeInstanceByCatalogOfferingInstanceByCatalogOfferingInstanceByNetworkInterface JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstancePrototypeInstanceByCatalogOfferingInstanceByCatalogOfferingInstanceByNetworkInterface object from 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, 'cluster_network_attachments') and self.cluster_network_attachments is not None:
            cluster_network_attachments_list = []
            for v in self.cluster_network_attachments:
                if isinstance(v, dict):
                    cluster_network_attachments_list.append(v)
                else:
                    cluster_network_attachments_list.append(v.to_dict())
            _dict['cluster_network_attachments'] = cluster_network_attachments_list
        if hasattr(self, 'confidential_compute_mode') and self.confidential_compute_mode is not None:
            _dict['confidential_compute_mode'] = self.confidential_compute_mode
        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, 'enable_secure_boot') and self.enable_secure_boot is not None:
            _dict['enable_secure_boot'] = self.enable_secure_boot
        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, 'reservation_affinity') and self.reservation_affinity is not None:
            if isinstance(self.reservation_affinity, dict):
                _dict['reservation_affinity'] = self.reservation_affinity
            else:
                _dict['reservation_affinity'] = self.reservation_affinity.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, '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, '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()
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstancePrototypeInstanceByCatalogOfferingInstanceByCatalogOfferingInstanceByNetworkInterface object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstancePrototypeInstanceByCatalogOfferingInstanceByCatalogOfferingInstanceByNetworkInterface') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstancePrototypeInstanceByCatalogOfferingInstanceByCatalogOfferingInstanceByNetworkInterface') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ConfidentialComputeModeEnum(str, Enum):
        """
        The confidential compute mode to use for this virtual server instance.
        If unspecified, the default confidential compute mode from the profile will be
        used.
        """

        DISABLED = 'disabled'
        SGX = 'sgx'



class InstancePrototypeInstanceByImageInstanceByImageInstanceByNetworkAttachment(InstancePrototypeInstanceByImage):
    """
    InstancePrototypeInstanceByImageInstanceByImageInstanceByNetworkAttachment.

    :param InstanceAvailabilityPolicyPrototype availability_policy: (optional) The
          availability policy to use for this virtual server instance.
    :param List[InstanceClusterNetworkAttachmentPrototypeInstanceContext]
          cluster_network_attachments: (optional) The cluster network attachments to
          create for this virtual server instance. A cluster network attachment represents
          a device that is connected to a cluster network. The number of network
          attachments must match one of the values from the instance profile's
          `cluster_network_attachment_count` before the instance can be started.
    :param str confidential_compute_mode: (optional) The confidential compute mode
          to use for this virtual server instance.
          If unspecified, the default confidential compute mode from the profile will be
          used.
    :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 bool enable_secure_boot: (optional) Indicates whether secure boot is
          enabled for this virtual server instance.
          If unspecified, the default secure boot mode from the profile will be used.
    :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.
          If specified, `reservation_affinity.policy` must be `disabled`.
    :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 InstanceReservationAffinityPrototype reservation_affinity: (optional)
    :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
          attachments or instance network interfaces.
    :param VolumeAttachmentPrototypeInstanceByImageContext boot_volume_attachment:
          (optional) The boot volume attachment to create for the virtual server instance.
    :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 List[InstanceNetworkAttachmentPrototype] network_attachments: (optional)
          The additional network attachments to create for the virtual server instance.
    :param InstanceNetworkAttachmentPrototype primary_network_attachment: The
          primary network attachment to create for the virtual server instance.
    """

    def __init__(
        self,
        image: 'ImageIdentity',
        zone: 'ZoneIdentity',
        primary_network_attachment: 'InstanceNetworkAttachmentPrototype',
        *,
        availability_policy: Optional['InstanceAvailabilityPolicyPrototype'] = None,
        cluster_network_attachments: Optional[List['InstanceClusterNetworkAttachmentPrototypeInstanceContext']] = None,
        confidential_compute_mode: Optional[str] = None,
        default_trusted_profile: Optional['InstanceDefaultTrustedProfilePrototype'] = None,
        enable_secure_boot: Optional[bool] = None,
        keys: Optional[List['KeyIdentity']] = None,
        metadata_service: Optional['InstanceMetadataServicePrototype'] = None,
        name: Optional[str] = None,
        placement_target: Optional['InstancePlacementTargetPrototype'] = None,
        profile: Optional['InstanceProfileIdentity'] = None,
        reservation_affinity: Optional['InstanceReservationAffinityPrototype'] = None,
        resource_group: Optional['ResourceGroupIdentity'] = None,
        total_volume_bandwidth: Optional[int] = None,
        user_data: Optional[str] = None,
        volume_attachments: Optional[List['VolumeAttachmentPrototype']] = None,
        vpc: Optional['VPCIdentity'] = None,
        boot_volume_attachment: Optional['VolumeAttachmentPrototypeInstanceByImageContext'] = None,
        network_attachments: Optional[List['InstanceNetworkAttachmentPrototype']] = None,
    ) -> None:
        """
        Initialize a InstancePrototypeInstanceByImageInstanceByImageInstanceByNetworkAttachment object.

        :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 InstanceNetworkAttachmentPrototype primary_network_attachment: The
               primary network attachment to create for the virtual server instance.
        :param InstanceAvailabilityPolicyPrototype availability_policy: (optional)
               The availability policy to use for this virtual server instance.
        :param List[InstanceClusterNetworkAttachmentPrototypeInstanceContext]
               cluster_network_attachments: (optional) The cluster network attachments to
               create for this virtual server instance. A cluster network attachment
               represents a device that is connected to a cluster network. The number of
               network attachments must match one of the values from the instance
               profile's `cluster_network_attachment_count` before the instance can be
               started.
        :param str confidential_compute_mode: (optional) The confidential compute
               mode to use for this virtual server instance.
               If unspecified, the default confidential compute mode from the profile will
               be used.
        :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 bool enable_secure_boot: (optional) Indicates whether secure boot is
               enabled for this virtual server instance.
               If unspecified, the default secure boot mode from the profile will be used.
        :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.
               If specified, `reservation_affinity.policy` must be `disabled`.
        :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 InstanceReservationAffinityPrototype reservation_affinity:
               (optional)
        :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
               attachments or instance network interfaces.
        :param VolumeAttachmentPrototypeInstanceByImageContext
               boot_volume_attachment: (optional) The boot volume attachment to create for
               the virtual server instance.
        :param List[InstanceNetworkAttachmentPrototype] network_attachments:
               (optional) The additional network attachments to create for the virtual
               server instance.
        """
        # pylint: disable=super-init-not-called
        self.availability_policy = availability_policy
        self.cluster_network_attachments = cluster_network_attachments
        self.confidential_compute_mode = confidential_compute_mode
        self.default_trusted_profile = default_trusted_profile
        self.enable_secure_boot = enable_secure_boot
        self.keys = keys
        self.metadata_service = metadata_service
        self.name = name
        self.placement_target = placement_target
        self.profile = profile
        self.reservation_affinity = reservation_affinity
        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.zone = zone
        self.network_attachments = network_attachments
        self.primary_network_attachment = primary_network_attachment

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstancePrototypeInstanceByImageInstanceByImageInstanceByNetworkAttachment':
        """Initialize a InstancePrototypeInstanceByImageInstanceByImageInstanceByNetworkAttachment object from a json dictionary."""
        args = {}
        if (availability_policy := _dict.get('availability_policy')) is not None:
            args['availability_policy'] = InstanceAvailabilityPolicyPrototype.from_dict(availability_policy)
        if (cluster_network_attachments := _dict.get('cluster_network_attachments')) is not None:
            args['cluster_network_attachments'] = [InstanceClusterNetworkAttachmentPrototypeInstanceContext.from_dict(v) for v in cluster_network_attachments]
        if (confidential_compute_mode := _dict.get('confidential_compute_mode')) is not None:
            args['confidential_compute_mode'] = confidential_compute_mode
        if (default_trusted_profile := _dict.get('default_trusted_profile')) is not None:
            args['default_trusted_profile'] = InstanceDefaultTrustedProfilePrototype.from_dict(default_trusted_profile)
        if (enable_secure_boot := _dict.get('enable_secure_boot')) is not None:
            args['enable_secure_boot'] = enable_secure_boot
        if (keys := _dict.get('keys')) is not None:
            args['keys'] = keys
        if (metadata_service := _dict.get('metadata_service')) is not None:
            args['metadata_service'] = InstanceMetadataServicePrototype.from_dict(metadata_service)
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        if (placement_target := _dict.get('placement_target')) is not None:
            args['placement_target'] = placement_target
        if (profile := _dict.get('profile')) is not None:
            args['profile'] = profile
        if (reservation_affinity := _dict.get('reservation_affinity')) is not None:
            args['reservation_affinity'] = InstanceReservationAffinityPrototype.from_dict(reservation_affinity)
        if (resource_group := _dict.get('resource_group')) is not None:
            args['resource_group'] = resource_group
        if (total_volume_bandwidth := _dict.get('total_volume_bandwidth')) is not None:
            args['total_volume_bandwidth'] = total_volume_bandwidth
        if (user_data := _dict.get('user_data')) is not None:
            args['user_data'] = user_data
        if (volume_attachments := _dict.get('volume_attachments')) is not None:
            args['volume_attachments'] = [VolumeAttachmentPrototype.from_dict(v) for v in volume_attachments]
        if (vpc := _dict.get('vpc')) is not None:
            args['vpc'] = vpc
        if (boot_volume_attachment := _dict.get('boot_volume_attachment')) is not None:
            args['boot_volume_attachment'] = VolumeAttachmentPrototypeInstanceByImageContext.from_dict(boot_volume_attachment)
        if (image := _dict.get('image')) is not None:
            args['image'] = image
        else:
            raise ValueError('Required property \'image\' not present in InstancePrototypeInstanceByImageInstanceByImageInstanceByNetworkAttachment JSON')
        if (zone := _dict.get('zone')) is not None:
            args['zone'] = zone
        else:
            raise ValueError('Required property \'zone\' not present in InstancePrototypeInstanceByImageInstanceByImageInstanceByNetworkAttachment JSON')
        if (network_attachments := _dict.get('network_attachments')) is not None:
            args['network_attachments'] = [InstanceNetworkAttachmentPrototype.from_dict(v) for v in network_attachments]
        if (primary_network_attachment := _dict.get('primary_network_attachment')) is not None:
            args['primary_network_attachment'] = InstanceNetworkAttachmentPrototype.from_dict(primary_network_attachment)
        else:
            raise ValueError('Required property \'primary_network_attachment\' not present in InstancePrototypeInstanceByImageInstanceByImageInstanceByNetworkAttachment JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstancePrototypeInstanceByImageInstanceByImageInstanceByNetworkAttachment object from 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, 'cluster_network_attachments') and self.cluster_network_attachments is not None:
            cluster_network_attachments_list = []
            for v in self.cluster_network_attachments:
                if isinstance(v, dict):
                    cluster_network_attachments_list.append(v)
                else:
                    cluster_network_attachments_list.append(v.to_dict())
            _dict['cluster_network_attachments'] = cluster_network_attachments_list
        if hasattr(self, 'confidential_compute_mode') and self.confidential_compute_mode is not None:
            _dict['confidential_compute_mode'] = self.confidential_compute_mode
        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, 'enable_secure_boot') and self.enable_secure_boot is not None:
            _dict['enable_secure_boot'] = self.enable_secure_boot
        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, 'reservation_affinity') and self.reservation_affinity is not None:
            if isinstance(self.reservation_affinity, dict):
                _dict['reservation_affinity'] = self.reservation_affinity
            else:
                _dict['reservation_affinity'] = self.reservation_affinity.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, '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, 'network_attachments') and self.network_attachments is not None:
            network_attachments_list = []
            for v in self.network_attachments:
                if isinstance(v, dict):
                    network_attachments_list.append(v)
                else:
                    network_attachments_list.append(v.to_dict())
            _dict['network_attachments'] = network_attachments_list
        if hasattr(self, 'primary_network_attachment') and self.primary_network_attachment is not None:
            if isinstance(self.primary_network_attachment, dict):
                _dict['primary_network_attachment'] = self.primary_network_attachment
            else:
                _dict['primary_network_attachment'] = self.primary_network_attachment.to_dict()
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstancePrototypeInstanceByImageInstanceByImageInstanceByNetworkAttachment object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstancePrototypeInstanceByImageInstanceByImageInstanceByNetworkAttachment') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstancePrototypeInstanceByImageInstanceByImageInstanceByNetworkAttachment') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ConfidentialComputeModeEnum(str, Enum):
        """
        The confidential compute mode to use for this virtual server instance.
        If unspecified, the default confidential compute mode from the profile will be
        used.
        """

        DISABLED = 'disabled'
        SGX = 'sgx'



class InstancePrototypeInstanceByImageInstanceByImageInstanceByNetworkInterface(InstancePrototypeInstanceByImage):
    """
    InstancePrototypeInstanceByImageInstanceByImageInstanceByNetworkInterface.

    :param InstanceAvailabilityPolicyPrototype availability_policy: (optional) The
          availability policy to use for this virtual server instance.
    :param List[InstanceClusterNetworkAttachmentPrototypeInstanceContext]
          cluster_network_attachments: (optional) The cluster network attachments to
          create for this virtual server instance. A cluster network attachment represents
          a device that is connected to a cluster network. The number of network
          attachments must match one of the values from the instance profile's
          `cluster_network_attachment_count` before the instance can be started.
    :param str confidential_compute_mode: (optional) The confidential compute mode
          to use for this virtual server instance.
          If unspecified, the default confidential compute mode from the profile will be
          used.
    :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 bool enable_secure_boot: (optional) Indicates whether secure boot is
          enabled for this virtual server instance.
          If unspecified, the default secure boot mode from the profile will be used.
    :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.
          If specified, `reservation_affinity.policy` must be `disabled`.
    :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 InstanceReservationAffinityPrototype reservation_affinity: (optional)
    :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
          attachments or instance network interfaces.
    :param VolumeAttachmentPrototypeInstanceByImageContext boot_volume_attachment:
          (optional) The boot volume attachment to create for the virtual server instance.
    :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 List[NetworkInterfacePrototype] network_interfaces: (optional) The
          additional instance network interfaces to create.
    :param NetworkInterfacePrototype primary_network_interface: The primary instance
          network interface to create.
    """

    def __init__(
        self,
        image: 'ImageIdentity',
        zone: 'ZoneIdentity',
        primary_network_interface: 'NetworkInterfacePrototype',
        *,
        availability_policy: Optional['InstanceAvailabilityPolicyPrototype'] = None,
        cluster_network_attachments: Optional[List['InstanceClusterNetworkAttachmentPrototypeInstanceContext']] = None,
        confidential_compute_mode: Optional[str] = None,
        default_trusted_profile: Optional['InstanceDefaultTrustedProfilePrototype'] = None,
        enable_secure_boot: Optional[bool] = None,
        keys: Optional[List['KeyIdentity']] = None,
        metadata_service: Optional['InstanceMetadataServicePrototype'] = None,
        name: Optional[str] = None,
        placement_target: Optional['InstancePlacementTargetPrototype'] = None,
        profile: Optional['InstanceProfileIdentity'] = None,
        reservation_affinity: Optional['InstanceReservationAffinityPrototype'] = None,
        resource_group: Optional['ResourceGroupIdentity'] = None,
        total_volume_bandwidth: Optional[int] = None,
        user_data: Optional[str] = None,
        volume_attachments: Optional[List['VolumeAttachmentPrototype']] = None,
        vpc: Optional['VPCIdentity'] = None,
        boot_volume_attachment: Optional['VolumeAttachmentPrototypeInstanceByImageContext'] = None,
        network_interfaces: Optional[List['NetworkInterfacePrototype']] = None,
    ) -> None:
        """
        Initialize a InstancePrototypeInstanceByImageInstanceByImageInstanceByNetworkInterface object.

        :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 NetworkInterfacePrototype primary_network_interface: The primary
               instance network interface to create.
        :param InstanceAvailabilityPolicyPrototype availability_policy: (optional)
               The availability policy to use for this virtual server instance.
        :param List[InstanceClusterNetworkAttachmentPrototypeInstanceContext]
               cluster_network_attachments: (optional) The cluster network attachments to
               create for this virtual server instance. A cluster network attachment
               represents a device that is connected to a cluster network. The number of
               network attachments must match one of the values from the instance
               profile's `cluster_network_attachment_count` before the instance can be
               started.
        :param str confidential_compute_mode: (optional) The confidential compute
               mode to use for this virtual server instance.
               If unspecified, the default confidential compute mode from the profile will
               be used.
        :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 bool enable_secure_boot: (optional) Indicates whether secure boot is
               enabled for this virtual server instance.
               If unspecified, the default secure boot mode from the profile will be used.
        :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.
               If specified, `reservation_affinity.policy` must be `disabled`.
        :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 InstanceReservationAffinityPrototype reservation_affinity:
               (optional)
        :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
               attachments or 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.cluster_network_attachments = cluster_network_attachments
        self.confidential_compute_mode = confidential_compute_mode
        self.default_trusted_profile = default_trusted_profile
        self.enable_secure_boot = enable_secure_boot
        self.keys = keys
        self.metadata_service = metadata_service
        self.name = name
        self.placement_target = placement_target
        self.profile = profile
        self.reservation_affinity = reservation_affinity
        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.zone = zone
        self.network_interfaces = network_interfaces
        self.primary_network_interface = primary_network_interface

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstancePrototypeInstanceByImageInstanceByImageInstanceByNetworkInterface':
        """Initialize a InstancePrototypeInstanceByImageInstanceByImageInstanceByNetworkInterface object from a json dictionary."""
        args = {}
        if (availability_policy := _dict.get('availability_policy')) is not None:
            args['availability_policy'] = InstanceAvailabilityPolicyPrototype.from_dict(availability_policy)
        if (cluster_network_attachments := _dict.get('cluster_network_attachments')) is not None:
            args['cluster_network_attachments'] = [InstanceClusterNetworkAttachmentPrototypeInstanceContext.from_dict(v) for v in cluster_network_attachments]
        if (confidential_compute_mode := _dict.get('confidential_compute_mode')) is not None:
            args['confidential_compute_mode'] = confidential_compute_mode
        if (default_trusted_profile := _dict.get('default_trusted_profile')) is not None:
            args['default_trusted_profile'] = InstanceDefaultTrustedProfilePrototype.from_dict(default_trusted_profile)
        if (enable_secure_boot := _dict.get('enable_secure_boot')) is not None:
            args['enable_secure_boot'] = enable_secure_boot
        if (keys := _dict.get('keys')) is not None:
            args['keys'] = keys
        if (metadata_service := _dict.get('metadata_service')) is not None:
            args['metadata_service'] = InstanceMetadataServicePrototype.from_dict(metadata_service)
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        if (placement_target := _dict.get('placement_target')) is not None:
            args['placement_target'] = placement_target
        if (profile := _dict.get('profile')) is not None:
            args['profile'] = profile
        if (reservation_affinity := _dict.get('reservation_affinity')) is not None:
            args['reservation_affinity'] = InstanceReservationAffinityPrototype.from_dict(reservation_affinity)
        if (resource_group := _dict.get('resource_group')) is not None:
            args['resource_group'] = resource_group
        if (total_volume_bandwidth := _dict.get('total_volume_bandwidth')) is not None:
            args['total_volume_bandwidth'] = total_volume_bandwidth
        if (user_data := _dict.get('user_data')) is not None:
            args['user_data'] = user_data
        if (volume_attachments := _dict.get('volume_attachments')) is not None:
            args['volume_attachments'] = [VolumeAttachmentPrototype.from_dict(v) for v in volume_attachments]
        if (vpc := _dict.get('vpc')) is not None:
            args['vpc'] = vpc
        if (boot_volume_attachment := _dict.get('boot_volume_attachment')) is not None:
            args['boot_volume_attachment'] = VolumeAttachmentPrototypeInstanceByImageContext.from_dict(boot_volume_attachment)
        if (image := _dict.get('image')) is not None:
            args['image'] = image
        else:
            raise ValueError('Required property \'image\' not present in InstancePrototypeInstanceByImageInstanceByImageInstanceByNetworkInterface JSON')
        if (zone := _dict.get('zone')) is not None:
            args['zone'] = zone
        else:
            raise ValueError('Required property \'zone\' not present in InstancePrototypeInstanceByImageInstanceByImageInstanceByNetworkInterface JSON')
        if (network_interfaces := _dict.get('network_interfaces')) is not None:
            args['network_interfaces'] = [NetworkInterfacePrototype.from_dict(v) for v in network_interfaces]
        if (primary_network_interface := _dict.get('primary_network_interface')) is not None:
            args['primary_network_interface'] = NetworkInterfacePrototype.from_dict(primary_network_interface)
        else:
            raise ValueError('Required property \'primary_network_interface\' not present in InstancePrototypeInstanceByImageInstanceByImageInstanceByNetworkInterface JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstancePrototypeInstanceByImageInstanceByImageInstanceByNetworkInterface object from 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, 'cluster_network_attachments') and self.cluster_network_attachments is not None:
            cluster_network_attachments_list = []
            for v in self.cluster_network_attachments:
                if isinstance(v, dict):
                    cluster_network_attachments_list.append(v)
                else:
                    cluster_network_attachments_list.append(v.to_dict())
            _dict['cluster_network_attachments'] = cluster_network_attachments_list
        if hasattr(self, 'confidential_compute_mode') and self.confidential_compute_mode is not None:
            _dict['confidential_compute_mode'] = self.confidential_compute_mode
        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, 'enable_secure_boot') and self.enable_secure_boot is not None:
            _dict['enable_secure_boot'] = self.enable_secure_boot
        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, 'reservation_affinity') and self.reservation_affinity is not None:
            if isinstance(self.reservation_affinity, dict):
                _dict['reservation_affinity'] = self.reservation_affinity
            else:
                _dict['reservation_affinity'] = self.reservation_affinity.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, '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, '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()
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstancePrototypeInstanceByImageInstanceByImageInstanceByNetworkInterface object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstancePrototypeInstanceByImageInstanceByImageInstanceByNetworkInterface') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstancePrototypeInstanceByImageInstanceByImageInstanceByNetworkInterface') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ConfidentialComputeModeEnum(str, Enum):
        """
        The confidential compute mode to use for this virtual server instance.
        If unspecified, the default confidential compute mode from the profile will be
        used.
        """

        DISABLED = 'disabled'
        SGX = 'sgx'



class InstancePrototypeInstanceBySourceSnapshotInstanceBySourceSnapshotInstanceByNetworkAttachment(InstancePrototypeInstanceBySourceSnapshot):
    """
    InstancePrototypeInstanceBySourceSnapshotInstanceBySourceSnapshotInstanceByNetworkAttachment.

    :param InstanceAvailabilityPolicyPrototype availability_policy: (optional) The
          availability policy to use for this virtual server instance.
    :param List[InstanceClusterNetworkAttachmentPrototypeInstanceContext]
          cluster_network_attachments: (optional) The cluster network attachments to
          create for this virtual server instance. A cluster network attachment represents
          a device that is connected to a cluster network. The number of network
          attachments must match one of the values from the instance profile's
          `cluster_network_attachment_count` before the instance can be started.
    :param str confidential_compute_mode: (optional) The confidential compute mode
          to use for this virtual server instance.
          If unspecified, the default confidential compute mode from the profile will be
          used.
    :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 bool enable_secure_boot: (optional) Indicates whether secure boot is
          enabled for this virtual server instance.
          If unspecified, the default secure boot mode from the profile will be used.
    :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.
          If specified, `reservation_affinity.policy` must be `disabled`.
    :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 InstanceReservationAffinityPrototype reservation_affinity: (optional)
    :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
          attachments or instance network interfaces.
    :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 List[InstanceNetworkAttachmentPrototype] network_attachments: (optional)
          The additional network attachments to create for the virtual server instance.
    :param InstanceNetworkAttachmentPrototype primary_network_attachment: The
          primary network attachment to create for the virtual server instance.
    """

    def __init__(
        self,
        boot_volume_attachment: 'VolumeAttachmentPrototypeInstanceBySourceSnapshotContext',
        zone: 'ZoneIdentity',
        primary_network_attachment: 'InstanceNetworkAttachmentPrototype',
        *,
        availability_policy: Optional['InstanceAvailabilityPolicyPrototype'] = None,
        cluster_network_attachments: Optional[List['InstanceClusterNetworkAttachmentPrototypeInstanceContext']] = None,
        confidential_compute_mode: Optional[str] = None,
        default_trusted_profile: Optional['InstanceDefaultTrustedProfilePrototype'] = None,
        enable_secure_boot: Optional[bool] = None,
        keys: Optional[List['KeyIdentity']] = None,
        metadata_service: Optional['InstanceMetadataServicePrototype'] = None,
        name: Optional[str] = None,
        placement_target: Optional['InstancePlacementTargetPrototype'] = None,
        profile: Optional['InstanceProfileIdentity'] = None,
        reservation_affinity: Optional['InstanceReservationAffinityPrototype'] = None,
        resource_group: Optional['ResourceGroupIdentity'] = None,
        total_volume_bandwidth: Optional[int] = None,
        user_data: Optional[str] = None,
        volume_attachments: Optional[List['VolumeAttachmentPrototype']] = None,
        vpc: Optional['VPCIdentity'] = None,
        network_attachments: Optional[List['InstanceNetworkAttachmentPrototype']] = None,
    ) -> None:
        """
        Initialize a InstancePrototypeInstanceBySourceSnapshotInstanceBySourceSnapshotInstanceByNetworkAttachment object.

        :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 InstanceNetworkAttachmentPrototype primary_network_attachment: The
               primary network attachment to create for the virtual server instance.
        :param InstanceAvailabilityPolicyPrototype availability_policy: (optional)
               The availability policy to use for this virtual server instance.
        :param List[InstanceClusterNetworkAttachmentPrototypeInstanceContext]
               cluster_network_attachments: (optional) The cluster network attachments to
               create for this virtual server instance. A cluster network attachment
               represents a device that is connected to a cluster network. The number of
               network attachments must match one of the values from the instance
               profile's `cluster_network_attachment_count` before the instance can be
               started.
        :param str confidential_compute_mode: (optional) The confidential compute
               mode to use for this virtual server instance.
               If unspecified, the default confidential compute mode from the profile will
               be used.
        :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 bool enable_secure_boot: (optional) Indicates whether secure boot is
               enabled for this virtual server instance.
               If unspecified, the default secure boot mode from the profile will be used.
        :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.
               If specified, `reservation_affinity.policy` must be `disabled`.
        :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 InstanceReservationAffinityPrototype reservation_affinity:
               (optional)
        :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
               attachments or instance network interfaces.
        :param List[InstanceNetworkAttachmentPrototype] network_attachments:
               (optional) The additional network attachments to create for the virtual
               server instance.
        """
        # pylint: disable=super-init-not-called
        self.availability_policy = availability_policy
        self.cluster_network_attachments = cluster_network_attachments
        self.confidential_compute_mode = confidential_compute_mode
        self.default_trusted_profile = default_trusted_profile
        self.enable_secure_boot = enable_secure_boot
        self.keys = keys
        self.metadata_service = metadata_service
        self.name = name
        self.placement_target = placement_target
        self.profile = profile
        self.reservation_affinity = reservation_affinity
        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.zone = zone
        self.network_attachments = network_attachments
        self.primary_network_attachment = primary_network_attachment

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstancePrototypeInstanceBySourceSnapshotInstanceBySourceSnapshotInstanceByNetworkAttachment':
        """Initialize a InstancePrototypeInstanceBySourceSnapshotInstanceBySourceSnapshotInstanceByNetworkAttachment object from a json dictionary."""
        args = {}
        if (availability_policy := _dict.get('availability_policy')) is not None:
            args['availability_policy'] = InstanceAvailabilityPolicyPrototype.from_dict(availability_policy)
        if (cluster_network_attachments := _dict.get('cluster_network_attachments')) is not None:
            args['cluster_network_attachments'] = [InstanceClusterNetworkAttachmentPrototypeInstanceContext.from_dict(v) for v in cluster_network_attachments]
        if (confidential_compute_mode := _dict.get('confidential_compute_mode')) is not None:
            args['confidential_compute_mode'] = confidential_compute_mode
        if (default_trusted_profile := _dict.get('default_trusted_profile')) is not None:
            args['default_trusted_profile'] = InstanceDefaultTrustedProfilePrototype.from_dict(default_trusted_profile)
        if (enable_secure_boot := _dict.get('enable_secure_boot')) is not None:
            args['enable_secure_boot'] = enable_secure_boot
        if (keys := _dict.get('keys')) is not None:
            args['keys'] = keys
        if (metadata_service := _dict.get('metadata_service')) is not None:
            args['metadata_service'] = InstanceMetadataServicePrototype.from_dict(metadata_service)
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        if (placement_target := _dict.get('placement_target')) is not None:
            args['placement_target'] = placement_target
        if (profile := _dict.get('profile')) is not None:
            args['profile'] = profile
        if (reservation_affinity := _dict.get('reservation_affinity')) is not None:
            args['reservation_affinity'] = InstanceReservationAffinityPrototype.from_dict(reservation_affinity)
        if (resource_group := _dict.get('resource_group')) is not None:
            args['resource_group'] = resource_group
        if (total_volume_bandwidth := _dict.get('total_volume_bandwidth')) is not None:
            args['total_volume_bandwidth'] = total_volume_bandwidth
        if (user_data := _dict.get('user_data')) is not None:
            args['user_data'] = user_data
        if (volume_attachments := _dict.get('volume_attachments')) is not None:
            args['volume_attachments'] = [VolumeAttachmentPrototype.from_dict(v) for v in volume_attachments]
        if (vpc := _dict.get('vpc')) is not None:
            args['vpc'] = vpc
        if (boot_volume_attachment := _dict.get('boot_volume_attachment')) is not None:
            args['boot_volume_attachment'] = VolumeAttachmentPrototypeInstanceBySourceSnapshotContext.from_dict(boot_volume_attachment)
        else:
            raise ValueError('Required property \'boot_volume_attachment\' not present in InstancePrototypeInstanceBySourceSnapshotInstanceBySourceSnapshotInstanceByNetworkAttachment JSON')
        if (zone := _dict.get('zone')) is not None:
            args['zone'] = zone
        else:
            raise ValueError('Required property \'zone\' not present in InstancePrototypeInstanceBySourceSnapshotInstanceBySourceSnapshotInstanceByNetworkAttachment JSON')
        if (network_attachments := _dict.get('network_attachments')) is not None:
            args['network_attachments'] = [InstanceNetworkAttachmentPrototype.from_dict(v) for v in network_attachments]
        if (primary_network_attachment := _dict.get('primary_network_attachment')) is not None:
            args['primary_network_attachment'] = InstanceNetworkAttachmentPrototype.from_dict(primary_network_attachment)
        else:
            raise ValueError('Required property \'primary_network_attachment\' not present in InstancePrototypeInstanceBySourceSnapshotInstanceBySourceSnapshotInstanceByNetworkAttachment JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstancePrototypeInstanceBySourceSnapshotInstanceBySourceSnapshotInstanceByNetworkAttachment object from 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, 'cluster_network_attachments') and self.cluster_network_attachments is not None:
            cluster_network_attachments_list = []
            for v in self.cluster_network_attachments:
                if isinstance(v, dict):
                    cluster_network_attachments_list.append(v)
                else:
                    cluster_network_attachments_list.append(v.to_dict())
            _dict['cluster_network_attachments'] = cluster_network_attachments_list
        if hasattr(self, 'confidential_compute_mode') and self.confidential_compute_mode is not None:
            _dict['confidential_compute_mode'] = self.confidential_compute_mode
        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, 'enable_secure_boot') and self.enable_secure_boot is not None:
            _dict['enable_secure_boot'] = self.enable_secure_boot
        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, 'reservation_affinity') and self.reservation_affinity is not None:
            if isinstance(self.reservation_affinity, dict):
                _dict['reservation_affinity'] = self.reservation_affinity
            else:
                _dict['reservation_affinity'] = self.reservation_affinity.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, '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, 'network_attachments') and self.network_attachments is not None:
            network_attachments_list = []
            for v in self.network_attachments:
                if isinstance(v, dict):
                    network_attachments_list.append(v)
                else:
                    network_attachments_list.append(v.to_dict())
            _dict['network_attachments'] = network_attachments_list
        if hasattr(self, 'primary_network_attachment') and self.primary_network_attachment is not None:
            if isinstance(self.primary_network_attachment, dict):
                _dict['primary_network_attachment'] = self.primary_network_attachment
            else:
                _dict['primary_network_attachment'] = self.primary_network_attachment.to_dict()
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstancePrototypeInstanceBySourceSnapshotInstanceBySourceSnapshotInstanceByNetworkAttachment object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstancePrototypeInstanceBySourceSnapshotInstanceBySourceSnapshotInstanceByNetworkAttachment') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstancePrototypeInstanceBySourceSnapshotInstanceBySourceSnapshotInstanceByNetworkAttachment') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ConfidentialComputeModeEnum(str, Enum):
        """
        The confidential compute mode to use for this virtual server instance.
        If unspecified, the default confidential compute mode from the profile will be
        used.
        """

        DISABLED = 'disabled'
        SGX = 'sgx'



class InstancePrototypeInstanceBySourceSnapshotInstanceBySourceSnapshotInstanceByNetworkInterface(InstancePrototypeInstanceBySourceSnapshot):
    """
    InstancePrototypeInstanceBySourceSnapshotInstanceBySourceSnapshotInstanceByNetworkInterface.

    :param InstanceAvailabilityPolicyPrototype availability_policy: (optional) The
          availability policy to use for this virtual server instance.
    :param List[InstanceClusterNetworkAttachmentPrototypeInstanceContext]
          cluster_network_attachments: (optional) The cluster network attachments to
          create for this virtual server instance. A cluster network attachment represents
          a device that is connected to a cluster network. The number of network
          attachments must match one of the values from the instance profile's
          `cluster_network_attachment_count` before the instance can be started.
    :param str confidential_compute_mode: (optional) The confidential compute mode
          to use for this virtual server instance.
          If unspecified, the default confidential compute mode from the profile will be
          used.
    :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 bool enable_secure_boot: (optional) Indicates whether secure boot is
          enabled for this virtual server instance.
          If unspecified, the default secure boot mode from the profile will be used.
    :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.
          If specified, `reservation_affinity.policy` must be `disabled`.
    :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 InstanceReservationAffinityPrototype reservation_affinity: (optional)
    :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
          attachments or instance network interfaces.
    :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 List[NetworkInterfacePrototype] network_interfaces: (optional) The
          additional instance network interfaces to create.
    :param NetworkInterfacePrototype primary_network_interface: The primary instance
          network interface to create.
    """

    def __init__(
        self,
        boot_volume_attachment: 'VolumeAttachmentPrototypeInstanceBySourceSnapshotContext',
        zone: 'ZoneIdentity',
        primary_network_interface: 'NetworkInterfacePrototype',
        *,
        availability_policy: Optional['InstanceAvailabilityPolicyPrototype'] = None,
        cluster_network_attachments: Optional[List['InstanceClusterNetworkAttachmentPrototypeInstanceContext']] = None,
        confidential_compute_mode: Optional[str] = None,
        default_trusted_profile: Optional['InstanceDefaultTrustedProfilePrototype'] = None,
        enable_secure_boot: Optional[bool] = None,
        keys: Optional[List['KeyIdentity']] = None,
        metadata_service: Optional['InstanceMetadataServicePrototype'] = None,
        name: Optional[str] = None,
        placement_target: Optional['InstancePlacementTargetPrototype'] = None,
        profile: Optional['InstanceProfileIdentity'] = None,
        reservation_affinity: Optional['InstanceReservationAffinityPrototype'] = None,
        resource_group: Optional['ResourceGroupIdentity'] = None,
        total_volume_bandwidth: Optional[int] = None,
        user_data: Optional[str] = None,
        volume_attachments: Optional[List['VolumeAttachmentPrototype']] = None,
        vpc: Optional['VPCIdentity'] = None,
        network_interfaces: Optional[List['NetworkInterfacePrototype']] = None,
    ) -> None:
        """
        Initialize a InstancePrototypeInstanceBySourceSnapshotInstanceBySourceSnapshotInstanceByNetworkInterface object.

        :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 NetworkInterfacePrototype primary_network_interface: The primary
               instance network interface to create.
        :param InstanceAvailabilityPolicyPrototype availability_policy: (optional)
               The availability policy to use for this virtual server instance.
        :param List[InstanceClusterNetworkAttachmentPrototypeInstanceContext]
               cluster_network_attachments: (optional) The cluster network attachments to
               create for this virtual server instance. A cluster network attachment
               represents a device that is connected to a cluster network. The number of
               network attachments must match one of the values from the instance
               profile's `cluster_network_attachment_count` before the instance can be
               started.
        :param str confidential_compute_mode: (optional) The confidential compute
               mode to use for this virtual server instance.
               If unspecified, the default confidential compute mode from the profile will
               be used.
        :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 bool enable_secure_boot: (optional) Indicates whether secure boot is
               enabled for this virtual server instance.
               If unspecified, the default secure boot mode from the profile will be used.
        :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.
               If specified, `reservation_affinity.policy` must be `disabled`.
        :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 InstanceReservationAffinityPrototype reservation_affinity:
               (optional)
        :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
               attachments or 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.cluster_network_attachments = cluster_network_attachments
        self.confidential_compute_mode = confidential_compute_mode
        self.default_trusted_profile = default_trusted_profile
        self.enable_secure_boot = enable_secure_boot
        self.keys = keys
        self.metadata_service = metadata_service
        self.name = name
        self.placement_target = placement_target
        self.profile = profile
        self.reservation_affinity = reservation_affinity
        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.zone = zone
        self.network_interfaces = network_interfaces
        self.primary_network_interface = primary_network_interface

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstancePrototypeInstanceBySourceSnapshotInstanceBySourceSnapshotInstanceByNetworkInterface':
        """Initialize a InstancePrototypeInstanceBySourceSnapshotInstanceBySourceSnapshotInstanceByNetworkInterface object from a json dictionary."""
        args = {}
        if (availability_policy := _dict.get('availability_policy')) is not None:
            args['availability_policy'] = InstanceAvailabilityPolicyPrototype.from_dict(availability_policy)
        if (cluster_network_attachments := _dict.get('cluster_network_attachments')) is not None:
            args['cluster_network_attachments'] = [InstanceClusterNetworkAttachmentPrototypeInstanceContext.from_dict(v) for v in cluster_network_attachments]
        if (confidential_compute_mode := _dict.get('confidential_compute_mode')) is not None:
            args['confidential_compute_mode'] = confidential_compute_mode
        if (default_trusted_profile := _dict.get('default_trusted_profile')) is not None:
            args['default_trusted_profile'] = InstanceDefaultTrustedProfilePrototype.from_dict(default_trusted_profile)
        if (enable_secure_boot := _dict.get('enable_secure_boot')) is not None:
            args['enable_secure_boot'] = enable_secure_boot
        if (keys := _dict.get('keys')) is not None:
            args['keys'] = keys
        if (metadata_service := _dict.get('metadata_service')) is not None:
            args['metadata_service'] = InstanceMetadataServicePrototype.from_dict(metadata_service)
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        if (placement_target := _dict.get('placement_target')) is not None:
            args['placement_target'] = placement_target
        if (profile := _dict.get('profile')) is not None:
            args['profile'] = profile
        if (reservation_affinity := _dict.get('reservation_affinity')) is not None:
            args['reservation_affinity'] = InstanceReservationAffinityPrototype.from_dict(reservation_affinity)
        if (resource_group := _dict.get('resource_group')) is not None:
            args['resource_group'] = resource_group
        if (total_volume_bandwidth := _dict.get('total_volume_bandwidth')) is not None:
            args['total_volume_bandwidth'] = total_volume_bandwidth
        if (user_data := _dict.get('user_data')) is not None:
            args['user_data'] = user_data
        if (volume_attachments := _dict.get('volume_attachments')) is not None:
            args['volume_attachments'] = [VolumeAttachmentPrototype.from_dict(v) for v in volume_attachments]
        if (vpc := _dict.get('vpc')) is not None:
            args['vpc'] = vpc
        if (boot_volume_attachment := _dict.get('boot_volume_attachment')) is not None:
            args['boot_volume_attachment'] = VolumeAttachmentPrototypeInstanceBySourceSnapshotContext.from_dict(boot_volume_attachment)
        else:
            raise ValueError('Required property \'boot_volume_attachment\' not present in InstancePrototypeInstanceBySourceSnapshotInstanceBySourceSnapshotInstanceByNetworkInterface JSON')
        if (zone := _dict.get('zone')) is not None:
            args['zone'] = zone
        else:
            raise ValueError('Required property \'zone\' not present in InstancePrototypeInstanceBySourceSnapshotInstanceBySourceSnapshotInstanceByNetworkInterface JSON')
        if (network_interfaces := _dict.get('network_interfaces')) is not None:
            args['network_interfaces'] = [NetworkInterfacePrototype.from_dict(v) for v in network_interfaces]
        if (primary_network_interface := _dict.get('primary_network_interface')) is not None:
            args['primary_network_interface'] = NetworkInterfacePrototype.from_dict(primary_network_interface)
        else:
            raise ValueError('Required property \'primary_network_interface\' not present in InstancePrototypeInstanceBySourceSnapshotInstanceBySourceSnapshotInstanceByNetworkInterface JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstancePrototypeInstanceBySourceSnapshotInstanceBySourceSnapshotInstanceByNetworkInterface object from 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, 'cluster_network_attachments') and self.cluster_network_attachments is not None:
            cluster_network_attachments_list = []
            for v in self.cluster_network_attachments:
                if isinstance(v, dict):
                    cluster_network_attachments_list.append(v)
                else:
                    cluster_network_attachments_list.append(v.to_dict())
            _dict['cluster_network_attachments'] = cluster_network_attachments_list
        if hasattr(self, 'confidential_compute_mode') and self.confidential_compute_mode is not None:
            _dict['confidential_compute_mode'] = self.confidential_compute_mode
        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, 'enable_secure_boot') and self.enable_secure_boot is not None:
            _dict['enable_secure_boot'] = self.enable_secure_boot
        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, 'reservation_affinity') and self.reservation_affinity is not None:
            if isinstance(self.reservation_affinity, dict):
                _dict['reservation_affinity'] = self.reservation_affinity
            else:
                _dict['reservation_affinity'] = self.reservation_affinity.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, '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, '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()
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstancePrototypeInstanceBySourceSnapshotInstanceBySourceSnapshotInstanceByNetworkInterface object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstancePrototypeInstanceBySourceSnapshotInstanceBySourceSnapshotInstanceByNetworkInterface') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstancePrototypeInstanceBySourceSnapshotInstanceBySourceSnapshotInstanceByNetworkInterface') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ConfidentialComputeModeEnum(str, Enum):
        """
        The confidential compute mode to use for this virtual server instance.
        If unspecified, the default confidential compute mode from the profile will be
        used.
        """

        DISABLED = 'disabled'
        SGX = 'sgx'



class InstancePrototypeInstanceByVolumeInstanceByVolumeInstanceByNetworkAttachment(InstancePrototypeInstanceByVolume):
    """
    InstancePrototypeInstanceByVolumeInstanceByVolumeInstanceByNetworkAttachment.

    :param InstanceAvailabilityPolicyPrototype availability_policy: (optional) The
          availability policy to use for this virtual server instance.
    :param List[InstanceClusterNetworkAttachmentPrototypeInstanceContext]
          cluster_network_attachments: (optional) The cluster network attachments to
          create for this virtual server instance. A cluster network attachment represents
          a device that is connected to a cluster network. The number of network
          attachments must match one of the values from the instance profile's
          `cluster_network_attachment_count` before the instance can be started.
    :param str confidential_compute_mode: (optional) The confidential compute mode
          to use for this virtual server instance.
          If unspecified, the default confidential compute mode from the profile will be
          used.
    :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 bool enable_secure_boot: (optional) Indicates whether secure boot is
          enabled for this virtual server instance.
          If unspecified, the default secure boot mode from the profile will be used.
    :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.
          If specified, `reservation_affinity.policy` must be `disabled`.
    :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 InstanceReservationAffinityPrototype reservation_affinity: (optional)
    :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
          attachments or instance network interfaces.
    :param VolumeAttachmentPrototypeInstanceByVolumeContext boot_volume_attachment:
          The boot volume attachment for the virtual server instance.
    :param ZoneIdentity zone: The zone this virtual server instance will reside in.
    :param List[InstanceNetworkAttachmentPrototype] network_attachments: (optional)
          The additional network attachments to create for the virtual server instance.
    :param InstanceNetworkAttachmentPrototype primary_network_attachment: The
          primary network attachment to create for the virtual server instance.
    """

    def __init__(
        self,
        boot_volume_attachment: 'VolumeAttachmentPrototypeInstanceByVolumeContext',
        zone: 'ZoneIdentity',
        primary_network_attachment: 'InstanceNetworkAttachmentPrototype',
        *,
        availability_policy: Optional['InstanceAvailabilityPolicyPrototype'] = None,
        cluster_network_attachments: Optional[List['InstanceClusterNetworkAttachmentPrototypeInstanceContext']] = None,
        confidential_compute_mode: Optional[str] = None,
        default_trusted_profile: Optional['InstanceDefaultTrustedProfilePrototype'] = None,
        enable_secure_boot: Optional[bool] = None,
        keys: Optional[List['KeyIdentity']] = None,
        metadata_service: Optional['InstanceMetadataServicePrototype'] = None,
        name: Optional[str] = None,
        placement_target: Optional['InstancePlacementTargetPrototype'] = None,
        profile: Optional['InstanceProfileIdentity'] = None,
        reservation_affinity: Optional['InstanceReservationAffinityPrototype'] = None,
        resource_group: Optional['ResourceGroupIdentity'] = None,
        total_volume_bandwidth: Optional[int] = None,
        user_data: Optional[str] = None,
        volume_attachments: Optional[List['VolumeAttachmentPrototype']] = None,
        vpc: Optional['VPCIdentity'] = None,
        network_attachments: Optional[List['InstanceNetworkAttachmentPrototype']] = None,
    ) -> None:
        """
        Initialize a InstancePrototypeInstanceByVolumeInstanceByVolumeInstanceByNetworkAttachment object.

        :param VolumeAttachmentPrototypeInstanceByVolumeContext
               boot_volume_attachment: The boot volume attachment for the virtual server
               instance.
        :param ZoneIdentity zone: The zone this virtual server instance will reside
               in.
        :param InstanceNetworkAttachmentPrototype primary_network_attachment: The
               primary network attachment to create for the virtual server instance.
        :param InstanceAvailabilityPolicyPrototype availability_policy: (optional)
               The availability policy to use for this virtual server instance.
        :param List[InstanceClusterNetworkAttachmentPrototypeInstanceContext]
               cluster_network_attachments: (optional) The cluster network attachments to
               create for this virtual server instance. A cluster network attachment
               represents a device that is connected to a cluster network. The number of
               network attachments must match one of the values from the instance
               profile's `cluster_network_attachment_count` before the instance can be
               started.
        :param str confidential_compute_mode: (optional) The confidential compute
               mode to use for this virtual server instance.
               If unspecified, the default confidential compute mode from the profile will
               be used.
        :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 bool enable_secure_boot: (optional) Indicates whether secure boot is
               enabled for this virtual server instance.
               If unspecified, the default secure boot mode from the profile will be used.
        :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.
               If specified, `reservation_affinity.policy` must be `disabled`.
        :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 InstanceReservationAffinityPrototype reservation_affinity:
               (optional)
        :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
               attachments or instance network interfaces.
        :param List[InstanceNetworkAttachmentPrototype] network_attachments:
               (optional) The additional network attachments to create for the virtual
               server instance.
        """
        # pylint: disable=super-init-not-called
        self.availability_policy = availability_policy
        self.cluster_network_attachments = cluster_network_attachments
        self.confidential_compute_mode = confidential_compute_mode
        self.default_trusted_profile = default_trusted_profile
        self.enable_secure_boot = enable_secure_boot
        self.keys = keys
        self.metadata_service = metadata_service
        self.name = name
        self.placement_target = placement_target
        self.profile = profile
        self.reservation_affinity = reservation_affinity
        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.zone = zone
        self.network_attachments = network_attachments
        self.primary_network_attachment = primary_network_attachment

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstancePrototypeInstanceByVolumeInstanceByVolumeInstanceByNetworkAttachment':
        """Initialize a InstancePrototypeInstanceByVolumeInstanceByVolumeInstanceByNetworkAttachment object from a json dictionary."""
        args = {}
        if (availability_policy := _dict.get('availability_policy')) is not None:
            args['availability_policy'] = InstanceAvailabilityPolicyPrototype.from_dict(availability_policy)
        if (cluster_network_attachments := _dict.get('cluster_network_attachments')) is not None:
            args['cluster_network_attachments'] = [InstanceClusterNetworkAttachmentPrototypeInstanceContext.from_dict(v) for v in cluster_network_attachments]
        if (confidential_compute_mode := _dict.get('confidential_compute_mode')) is not None:
            args['confidential_compute_mode'] = confidential_compute_mode
        if (default_trusted_profile := _dict.get('default_trusted_profile')) is not None:
            args['default_trusted_profile'] = InstanceDefaultTrustedProfilePrototype.from_dict(default_trusted_profile)
        if (enable_secure_boot := _dict.get('enable_secure_boot')) is not None:
            args['enable_secure_boot'] = enable_secure_boot
        if (keys := _dict.get('keys')) is not None:
            args['keys'] = keys
        if (metadata_service := _dict.get('metadata_service')) is not None:
            args['metadata_service'] = InstanceMetadataServicePrototype.from_dict(metadata_service)
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        if (placement_target := _dict.get('placement_target')) is not None:
            args['placement_target'] = placement_target
        if (profile := _dict.get('profile')) is not None:
            args['profile'] = profile
        if (reservation_affinity := _dict.get('reservation_affinity')) is not None:
            args['reservation_affinity'] = InstanceReservationAffinityPrototype.from_dict(reservation_affinity)
        if (resource_group := _dict.get('resource_group')) is not None:
            args['resource_group'] = resource_group
        if (total_volume_bandwidth := _dict.get('total_volume_bandwidth')) is not None:
            args['total_volume_bandwidth'] = total_volume_bandwidth
        if (user_data := _dict.get('user_data')) is not None:
            args['user_data'] = user_data
        if (volume_attachments := _dict.get('volume_attachments')) is not None:
            args['volume_attachments'] = [VolumeAttachmentPrototype.from_dict(v) for v in volume_attachments]
        if (vpc := _dict.get('vpc')) is not None:
            args['vpc'] = vpc
        if (boot_volume_attachment := _dict.get('boot_volume_attachment')) is not None:
            args['boot_volume_attachment'] = VolumeAttachmentPrototypeInstanceByVolumeContext.from_dict(boot_volume_attachment)
        else:
            raise ValueError('Required property \'boot_volume_attachment\' not present in InstancePrototypeInstanceByVolumeInstanceByVolumeInstanceByNetworkAttachment JSON')
        if (zone := _dict.get('zone')) is not None:
            args['zone'] = zone
        else:
            raise ValueError('Required property \'zone\' not present in InstancePrototypeInstanceByVolumeInstanceByVolumeInstanceByNetworkAttachment JSON')
        if (network_attachments := _dict.get('network_attachments')) is not None:
            args['network_attachments'] = [InstanceNetworkAttachmentPrototype.from_dict(v) for v in network_attachments]
        if (primary_network_attachment := _dict.get('primary_network_attachment')) is not None:
            args['primary_network_attachment'] = InstanceNetworkAttachmentPrototype.from_dict(primary_network_attachment)
        else:
            raise ValueError('Required property \'primary_network_attachment\' not present in InstancePrototypeInstanceByVolumeInstanceByVolumeInstanceByNetworkAttachment JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstancePrototypeInstanceByVolumeInstanceByVolumeInstanceByNetworkAttachment object from 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, 'cluster_network_attachments') and self.cluster_network_attachments is not None:
            cluster_network_attachments_list = []
            for v in self.cluster_network_attachments:
                if isinstance(v, dict):
                    cluster_network_attachments_list.append(v)
                else:
                    cluster_network_attachments_list.append(v.to_dict())
            _dict['cluster_network_attachments'] = cluster_network_attachments_list
        if hasattr(self, 'confidential_compute_mode') and self.confidential_compute_mode is not None:
            _dict['confidential_compute_mode'] = self.confidential_compute_mode
        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, 'enable_secure_boot') and self.enable_secure_boot is not None:
            _dict['enable_secure_boot'] = self.enable_secure_boot
        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, 'reservation_affinity') and self.reservation_affinity is not None:
            if isinstance(self.reservation_affinity, dict):
                _dict['reservation_affinity'] = self.reservation_affinity
            else:
                _dict['reservation_affinity'] = self.reservation_affinity.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, '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, 'network_attachments') and self.network_attachments is not None:
            network_attachments_list = []
            for v in self.network_attachments:
                if isinstance(v, dict):
                    network_attachments_list.append(v)
                else:
                    network_attachments_list.append(v.to_dict())
            _dict['network_attachments'] = network_attachments_list
        if hasattr(self, 'primary_network_attachment') and self.primary_network_attachment is not None:
            if isinstance(self.primary_network_attachment, dict):
                _dict['primary_network_attachment'] = self.primary_network_attachment
            else:
                _dict['primary_network_attachment'] = self.primary_network_attachment.to_dict()
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstancePrototypeInstanceByVolumeInstanceByVolumeInstanceByNetworkAttachment object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstancePrototypeInstanceByVolumeInstanceByVolumeInstanceByNetworkAttachment') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstancePrototypeInstanceByVolumeInstanceByVolumeInstanceByNetworkAttachment') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ConfidentialComputeModeEnum(str, Enum):
        """
        The confidential compute mode to use for this virtual server instance.
        If unspecified, the default confidential compute mode from the profile will be
        used.
        """

        DISABLED = 'disabled'
        SGX = 'sgx'



class InstancePrototypeInstanceByVolumeInstanceByVolumeInstanceByNetworkInterface(InstancePrototypeInstanceByVolume):
    """
    InstancePrototypeInstanceByVolumeInstanceByVolumeInstanceByNetworkInterface.

    :param InstanceAvailabilityPolicyPrototype availability_policy: (optional) The
          availability policy to use for this virtual server instance.
    :param List[InstanceClusterNetworkAttachmentPrototypeInstanceContext]
          cluster_network_attachments: (optional) The cluster network attachments to
          create for this virtual server instance. A cluster network attachment represents
          a device that is connected to a cluster network. The number of network
          attachments must match one of the values from the instance profile's
          `cluster_network_attachment_count` before the instance can be started.
    :param str confidential_compute_mode: (optional) The confidential compute mode
          to use for this virtual server instance.
          If unspecified, the default confidential compute mode from the profile will be
          used.
    :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 bool enable_secure_boot: (optional) Indicates whether secure boot is
          enabled for this virtual server instance.
          If unspecified, the default secure boot mode from the profile will be used.
    :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.
          If specified, `reservation_affinity.policy` must be `disabled`.
    :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 InstanceReservationAffinityPrototype reservation_affinity: (optional)
    :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
          attachments or instance network interfaces.
    :param VolumeAttachmentPrototypeInstanceByVolumeContext boot_volume_attachment:
          The boot volume attachment for the virtual server instance.
    :param ZoneIdentity zone: The zone this virtual server instance will reside in.
    :param List[NetworkInterfacePrototype] network_interfaces: (optional) The
          additional instance network interfaces to create.
    :param NetworkInterfacePrototype primary_network_interface: The primary instance
          network interface to create.
    """

    def __init__(
        self,
        boot_volume_attachment: 'VolumeAttachmentPrototypeInstanceByVolumeContext',
        zone: 'ZoneIdentity',
        primary_network_interface: 'NetworkInterfacePrototype',
        *,
        availability_policy: Optional['InstanceAvailabilityPolicyPrototype'] = None,
        cluster_network_attachments: Optional[List['InstanceClusterNetworkAttachmentPrototypeInstanceContext']] = None,
        confidential_compute_mode: Optional[str] = None,
        default_trusted_profile: Optional['InstanceDefaultTrustedProfilePrototype'] = None,
        enable_secure_boot: Optional[bool] = None,
        keys: Optional[List['KeyIdentity']] = None,
        metadata_service: Optional['InstanceMetadataServicePrototype'] = None,
        name: Optional[str] = None,
        placement_target: Optional['InstancePlacementTargetPrototype'] = None,
        profile: Optional['InstanceProfileIdentity'] = None,
        reservation_affinity: Optional['InstanceReservationAffinityPrototype'] = None,
        resource_group: Optional['ResourceGroupIdentity'] = None,
        total_volume_bandwidth: Optional[int] = None,
        user_data: Optional[str] = None,
        volume_attachments: Optional[List['VolumeAttachmentPrototype']] = None,
        vpc: Optional['VPCIdentity'] = None,
        network_interfaces: Optional[List['NetworkInterfacePrototype']] = None,
    ) -> None:
        """
        Initialize a InstancePrototypeInstanceByVolumeInstanceByVolumeInstanceByNetworkInterface object.

        :param VolumeAttachmentPrototypeInstanceByVolumeContext
               boot_volume_attachment: The boot volume attachment for the virtual server
               instance.
        :param ZoneIdentity zone: The zone this virtual server instance will reside
               in.
        :param NetworkInterfacePrototype primary_network_interface: The primary
               instance network interface to create.
        :param InstanceAvailabilityPolicyPrototype availability_policy: (optional)
               The availability policy to use for this virtual server instance.
        :param List[InstanceClusterNetworkAttachmentPrototypeInstanceContext]
               cluster_network_attachments: (optional) The cluster network attachments to
               create for this virtual server instance. A cluster network attachment
               represents a device that is connected to a cluster network. The number of
               network attachments must match one of the values from the instance
               profile's `cluster_network_attachment_count` before the instance can be
               started.
        :param str confidential_compute_mode: (optional) The confidential compute
               mode to use for this virtual server instance.
               If unspecified, the default confidential compute mode from the profile will
               be used.
        :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 bool enable_secure_boot: (optional) Indicates whether secure boot is
               enabled for this virtual server instance.
               If unspecified, the default secure boot mode from the profile will be used.
        :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.
               If specified, `reservation_affinity.policy` must be `disabled`.
        :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 InstanceReservationAffinityPrototype reservation_affinity:
               (optional)
        :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
               attachments or 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.cluster_network_attachments = cluster_network_attachments
        self.confidential_compute_mode = confidential_compute_mode
        self.default_trusted_profile = default_trusted_profile
        self.enable_secure_boot = enable_secure_boot
        self.keys = keys
        self.metadata_service = metadata_service
        self.name = name
        self.placement_target = placement_target
        self.profile = profile
        self.reservation_affinity = reservation_affinity
        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.zone = zone
        self.network_interfaces = network_interfaces
        self.primary_network_interface = primary_network_interface

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstancePrototypeInstanceByVolumeInstanceByVolumeInstanceByNetworkInterface':
        """Initialize a InstancePrototypeInstanceByVolumeInstanceByVolumeInstanceByNetworkInterface object from a json dictionary."""
        args = {}
        if (availability_policy := _dict.get('availability_policy')) is not None:
            args['availability_policy'] = InstanceAvailabilityPolicyPrototype.from_dict(availability_policy)
        if (cluster_network_attachments := _dict.get('cluster_network_attachments')) is not None:
            args['cluster_network_attachments'] = [InstanceClusterNetworkAttachmentPrototypeInstanceContext.from_dict(v) for v in cluster_network_attachments]
        if (confidential_compute_mode := _dict.get('confidential_compute_mode')) is not None:
            args['confidential_compute_mode'] = confidential_compute_mode
        if (default_trusted_profile := _dict.get('default_trusted_profile')) is not None:
            args['default_trusted_profile'] = InstanceDefaultTrustedProfilePrototype.from_dict(default_trusted_profile)
        if (enable_secure_boot := _dict.get('enable_secure_boot')) is not None:
            args['enable_secure_boot'] = enable_secure_boot
        if (keys := _dict.get('keys')) is not None:
            args['keys'] = keys
        if (metadata_service := _dict.get('metadata_service')) is not None:
            args['metadata_service'] = InstanceMetadataServicePrototype.from_dict(metadata_service)
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        if (placement_target := _dict.get('placement_target')) is not None:
            args['placement_target'] = placement_target
        if (profile := _dict.get('profile')) is not None:
            args['profile'] = profile
        if (reservation_affinity := _dict.get('reservation_affinity')) is not None:
            args['reservation_affinity'] = InstanceReservationAffinityPrototype.from_dict(reservation_affinity)
        if (resource_group := _dict.get('resource_group')) is not None:
            args['resource_group'] = resource_group
        if (total_volume_bandwidth := _dict.get('total_volume_bandwidth')) is not None:
            args['total_volume_bandwidth'] = total_volume_bandwidth
        if (user_data := _dict.get('user_data')) is not None:
            args['user_data'] = user_data
        if (volume_attachments := _dict.get('volume_attachments')) is not None:
            args['volume_attachments'] = [VolumeAttachmentPrototype.from_dict(v) for v in volume_attachments]
        if (vpc := _dict.get('vpc')) is not None:
            args['vpc'] = vpc
        if (boot_volume_attachment := _dict.get('boot_volume_attachment')) is not None:
            args['boot_volume_attachment'] = VolumeAttachmentPrototypeInstanceByVolumeContext.from_dict(boot_volume_attachment)
        else:
            raise ValueError('Required property \'boot_volume_attachment\' not present in InstancePrototypeInstanceByVolumeInstanceByVolumeInstanceByNetworkInterface JSON')
        if (zone := _dict.get('zone')) is not None:
            args['zone'] = zone
        else:
            raise ValueError('Required property \'zone\' not present in InstancePrototypeInstanceByVolumeInstanceByVolumeInstanceByNetworkInterface JSON')
        if (network_interfaces := _dict.get('network_interfaces')) is not None:
            args['network_interfaces'] = [NetworkInterfacePrototype.from_dict(v) for v in network_interfaces]
        if (primary_network_interface := _dict.get('primary_network_interface')) is not None:
            args['primary_network_interface'] = NetworkInterfacePrototype.from_dict(primary_network_interface)
        else:
            raise ValueError('Required property \'primary_network_interface\' not present in InstancePrototypeInstanceByVolumeInstanceByVolumeInstanceByNetworkInterface JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstancePrototypeInstanceByVolumeInstanceByVolumeInstanceByNetworkInterface object from 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, 'cluster_network_attachments') and self.cluster_network_attachments is not None:
            cluster_network_attachments_list = []
            for v in self.cluster_network_attachments:
                if isinstance(v, dict):
                    cluster_network_attachments_list.append(v)
                else:
                    cluster_network_attachments_list.append(v.to_dict())
            _dict['cluster_network_attachments'] = cluster_network_attachments_list
        if hasattr(self, 'confidential_compute_mode') and self.confidential_compute_mode is not None:
            _dict['confidential_compute_mode'] = self.confidential_compute_mode
        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, 'enable_secure_boot') and self.enable_secure_boot is not None:
            _dict['enable_secure_boot'] = self.enable_secure_boot
        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, 'reservation_affinity') and self.reservation_affinity is not None:
            if isinstance(self.reservation_affinity, dict):
                _dict['reservation_affinity'] = self.reservation_affinity
            else:
                _dict['reservation_affinity'] = self.reservation_affinity.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, '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, '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()
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstancePrototypeInstanceByVolumeInstanceByVolumeInstanceByNetworkInterface object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstancePrototypeInstanceByVolumeInstanceByVolumeInstanceByNetworkInterface') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstancePrototypeInstanceByVolumeInstanceByVolumeInstanceByNetworkInterface') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ConfidentialComputeModeEnum(str, Enum):
        """
        The confidential compute mode to use for this virtual server instance.
        If unspecified, the default confidential compute mode from the profile will be
        used.
        """

        DISABLED = 'disabled'
        SGX = 'sgx'



class InstanceTemplatePrototypeInstanceTemplateByCatalogOfferingInstanceTemplateByCatalogOfferingInstanceByNetworkAttachment(InstanceTemplatePrototypeInstanceTemplateByCatalogOffering):
    """
    InstanceTemplatePrototypeInstanceTemplateByCatalogOfferingInstanceTemplateByCatalogOfferingInstanceByNetworkAttachment.

    :param InstanceAvailabilityPolicyPrototype availability_policy: (optional) The
          availability policy to use for this virtual server instance.
    :param List[InstanceClusterNetworkAttachmentPrototypeInstanceContext]
          cluster_network_attachments: (optional) The cluster network attachments to
          create for this virtual server instance. A cluster network attachment represents
          a device that is connected to a cluster network. The number of network
          attachments must match one of the values from the instance profile's
          `cluster_network_attachment_count` before the instance can be started.
    :param str confidential_compute_mode: (optional) The confidential compute mode
          to use for this virtual server instance.
          If unspecified, the default confidential compute mode from the profile will be
          used.
    :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 bool enable_secure_boot: (optional) Indicates whether secure boot is
          enabled for this virtual server instance.
          If unspecified, the default secure boot mode from the profile will be used.
    :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.
          If specified, `reservation_affinity.policy` must be `disabled`.
    :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 InstanceReservationAffinityPrototype reservation_affinity: (optional)
    :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
          attachments or instance network interfaces.
    :param VolumeAttachmentPrototypeInstanceByImageContext boot_volume_attachment:
          (optional) The boot volume attachment to create for the virtual server instance.
    :param InstanceCatalogOfferingPrototype catalog_offering:
    :param ZoneIdentity zone: The zone this virtual server instance will reside in.
    :param List[InstanceNetworkAttachmentPrototype] network_attachments: (optional)
          The additional network attachments to create for the virtual server instance.
    :param InstanceNetworkAttachmentPrototype primary_network_attachment: The
          primary network attachment to create for the virtual server instance.
    """

    def __init__(
        self,
        catalog_offering: 'InstanceCatalogOfferingPrototype',
        zone: 'ZoneIdentity',
        primary_network_attachment: 'InstanceNetworkAttachmentPrototype',
        *,
        availability_policy: Optional['InstanceAvailabilityPolicyPrototype'] = None,
        cluster_network_attachments: Optional[List['InstanceClusterNetworkAttachmentPrototypeInstanceContext']] = None,
        confidential_compute_mode: Optional[str] = None,
        default_trusted_profile: Optional['InstanceDefaultTrustedProfilePrototype'] = None,
        enable_secure_boot: Optional[bool] = None,
        keys: Optional[List['KeyIdentity']] = None,
        metadata_service: Optional['InstanceMetadataServicePrototype'] = None,
        name: Optional[str] = None,
        placement_target: Optional['InstancePlacementTargetPrototype'] = None,
        profile: Optional['InstanceProfileIdentity'] = None,
        reservation_affinity: Optional['InstanceReservationAffinityPrototype'] = None,
        resource_group: Optional['ResourceGroupIdentity'] = None,
        total_volume_bandwidth: Optional[int] = None,
        user_data: Optional[str] = None,
        volume_attachments: Optional[List['VolumeAttachmentPrototype']] = None,
        vpc: Optional['VPCIdentity'] = None,
        boot_volume_attachment: Optional['VolumeAttachmentPrototypeInstanceByImageContext'] = None,
        network_attachments: Optional[List['InstanceNetworkAttachmentPrototype']] = None,
    ) -> None:
        """
        Initialize a InstanceTemplatePrototypeInstanceTemplateByCatalogOfferingInstanceTemplateByCatalogOfferingInstanceByNetworkAttachment object.

        :param InstanceCatalogOfferingPrototype catalog_offering:
        :param ZoneIdentity zone: The zone this virtual server instance will reside
               in.
        :param InstanceNetworkAttachmentPrototype primary_network_attachment: The
               primary network attachment to create for the virtual server instance.
        :param InstanceAvailabilityPolicyPrototype availability_policy: (optional)
               The availability policy to use for this virtual server instance.
        :param List[InstanceClusterNetworkAttachmentPrototypeInstanceContext]
               cluster_network_attachments: (optional) The cluster network attachments to
               create for this virtual server instance. A cluster network attachment
               represents a device that is connected to a cluster network. The number of
               network attachments must match one of the values from the instance
               profile's `cluster_network_attachment_count` before the instance can be
               started.
        :param str confidential_compute_mode: (optional) The confidential compute
               mode to use for this virtual server instance.
               If unspecified, the default confidential compute mode from the profile will
               be used.
        :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 bool enable_secure_boot: (optional) Indicates whether secure boot is
               enabled for this virtual server instance.
               If unspecified, the default secure boot mode from the profile will be used.
        :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.
               If specified, `reservation_affinity.policy` must be `disabled`.
        :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 InstanceReservationAffinityPrototype reservation_affinity:
               (optional)
        :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
               attachments or instance network interfaces.
        :param VolumeAttachmentPrototypeInstanceByImageContext
               boot_volume_attachment: (optional) The boot volume attachment to create for
               the virtual server instance.
        :param List[InstanceNetworkAttachmentPrototype] network_attachments:
               (optional) The additional network attachments to create for the virtual
               server instance.
        """
        # pylint: disable=super-init-not-called
        self.availability_policy = availability_policy
        self.cluster_network_attachments = cluster_network_attachments
        self.confidential_compute_mode = confidential_compute_mode
        self.default_trusted_profile = default_trusted_profile
        self.enable_secure_boot = enable_secure_boot
        self.keys = keys
        self.metadata_service = metadata_service
        self.name = name
        self.placement_target = placement_target
        self.profile = profile
        self.reservation_affinity = reservation_affinity
        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.zone = zone
        self.network_attachments = network_attachments
        self.primary_network_attachment = primary_network_attachment

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceTemplatePrototypeInstanceTemplateByCatalogOfferingInstanceTemplateByCatalogOfferingInstanceByNetworkAttachment':
        """Initialize a InstanceTemplatePrototypeInstanceTemplateByCatalogOfferingInstanceTemplateByCatalogOfferingInstanceByNetworkAttachment object from a json dictionary."""
        args = {}
        if (availability_policy := _dict.get('availability_policy')) is not None:
            args['availability_policy'] = InstanceAvailabilityPolicyPrototype.from_dict(availability_policy)
        if (cluster_network_attachments := _dict.get('cluster_network_attachments')) is not None:
            args['cluster_network_attachments'] = [InstanceClusterNetworkAttachmentPrototypeInstanceContext.from_dict(v) for v in cluster_network_attachments]
        if (confidential_compute_mode := _dict.get('confidential_compute_mode')) is not None:
            args['confidential_compute_mode'] = confidential_compute_mode
        if (default_trusted_profile := _dict.get('default_trusted_profile')) is not None:
            args['default_trusted_profile'] = InstanceDefaultTrustedProfilePrototype.from_dict(default_trusted_profile)
        if (enable_secure_boot := _dict.get('enable_secure_boot')) is not None:
            args['enable_secure_boot'] = enable_secure_boot
        if (keys := _dict.get('keys')) is not None:
            args['keys'] = keys
        if (metadata_service := _dict.get('metadata_service')) is not None:
            args['metadata_service'] = InstanceMetadataServicePrototype.from_dict(metadata_service)
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        if (placement_target := _dict.get('placement_target')) is not None:
            args['placement_target'] = placement_target
        if (profile := _dict.get('profile')) is not None:
            args['profile'] = profile
        if (reservation_affinity := _dict.get('reservation_affinity')) is not None:
            args['reservation_affinity'] = InstanceReservationAffinityPrototype.from_dict(reservation_affinity)
        if (resource_group := _dict.get('resource_group')) is not None:
            args['resource_group'] = resource_group
        if (total_volume_bandwidth := _dict.get('total_volume_bandwidth')) is not None:
            args['total_volume_bandwidth'] = total_volume_bandwidth
        if (user_data := _dict.get('user_data')) is not None:
            args['user_data'] = user_data
        if (volume_attachments := _dict.get('volume_attachments')) is not None:
            args['volume_attachments'] = [VolumeAttachmentPrototype.from_dict(v) for v in volume_attachments]
        if (vpc := _dict.get('vpc')) is not None:
            args['vpc'] = vpc
        if (boot_volume_attachment := _dict.get('boot_volume_attachment')) is not None:
            args['boot_volume_attachment'] = VolumeAttachmentPrototypeInstanceByImageContext.from_dict(boot_volume_attachment)
        if (catalog_offering := _dict.get('catalog_offering')) is not None:
            args['catalog_offering'] = catalog_offering
        else:
            raise ValueError('Required property \'catalog_offering\' not present in InstanceTemplatePrototypeInstanceTemplateByCatalogOfferingInstanceTemplateByCatalogOfferingInstanceByNetworkAttachment JSON')
        if (zone := _dict.get('zone')) is not None:
            args['zone'] = zone
        else:
            raise ValueError('Required property \'zone\' not present in InstanceTemplatePrototypeInstanceTemplateByCatalogOfferingInstanceTemplateByCatalogOfferingInstanceByNetworkAttachment JSON')
        if (network_attachments := _dict.get('network_attachments')) is not None:
            args['network_attachments'] = [InstanceNetworkAttachmentPrototype.from_dict(v) for v in network_attachments]
        if (primary_network_attachment := _dict.get('primary_network_attachment')) is not None:
            args['primary_network_attachment'] = InstanceNetworkAttachmentPrototype.from_dict(primary_network_attachment)
        else:
            raise ValueError('Required property \'primary_network_attachment\' not present in InstanceTemplatePrototypeInstanceTemplateByCatalogOfferingInstanceTemplateByCatalogOfferingInstanceByNetworkAttachment JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceTemplatePrototypeInstanceTemplateByCatalogOfferingInstanceTemplateByCatalogOfferingInstanceByNetworkAttachment object from 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, 'cluster_network_attachments') and self.cluster_network_attachments is not None:
            cluster_network_attachments_list = []
            for v in self.cluster_network_attachments:
                if isinstance(v, dict):
                    cluster_network_attachments_list.append(v)
                else:
                    cluster_network_attachments_list.append(v.to_dict())
            _dict['cluster_network_attachments'] = cluster_network_attachments_list
        if hasattr(self, 'confidential_compute_mode') and self.confidential_compute_mode is not None:
            _dict['confidential_compute_mode'] = self.confidential_compute_mode
        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, 'enable_secure_boot') and self.enable_secure_boot is not None:
            _dict['enable_secure_boot'] = self.enable_secure_boot
        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, 'reservation_affinity') and self.reservation_affinity is not None:
            if isinstance(self.reservation_affinity, dict):
                _dict['reservation_affinity'] = self.reservation_affinity
            else:
                _dict['reservation_affinity'] = self.reservation_affinity.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, '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, 'network_attachments') and self.network_attachments is not None:
            network_attachments_list = []
            for v in self.network_attachments:
                if isinstance(v, dict):
                    network_attachments_list.append(v)
                else:
                    network_attachments_list.append(v.to_dict())
            _dict['network_attachments'] = network_attachments_list
        if hasattr(self, 'primary_network_attachment') and self.primary_network_attachment is not None:
            if isinstance(self.primary_network_attachment, dict):
                _dict['primary_network_attachment'] = self.primary_network_attachment
            else:
                _dict['primary_network_attachment'] = self.primary_network_attachment.to_dict()
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceTemplatePrototypeInstanceTemplateByCatalogOfferingInstanceTemplateByCatalogOfferingInstanceByNetworkAttachment object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceTemplatePrototypeInstanceTemplateByCatalogOfferingInstanceTemplateByCatalogOfferingInstanceByNetworkAttachment') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceTemplatePrototypeInstanceTemplateByCatalogOfferingInstanceTemplateByCatalogOfferingInstanceByNetworkAttachment') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ConfidentialComputeModeEnum(str, Enum):
        """
        The confidential compute mode to use for this virtual server instance.
        If unspecified, the default confidential compute mode from the profile will be
        used.
        """

        DISABLED = 'disabled'
        SGX = 'sgx'



class InstanceTemplatePrototypeInstanceTemplateByCatalogOfferingInstanceTemplateByCatalogOfferingInstanceByNetworkInterface(InstanceTemplatePrototypeInstanceTemplateByCatalogOffering):
    """
    InstanceTemplatePrototypeInstanceTemplateByCatalogOfferingInstanceTemplateByCatalogOfferingInstanceByNetworkInterface.

    :param InstanceAvailabilityPolicyPrototype availability_policy: (optional) The
          availability policy to use for this virtual server instance.
    :param List[InstanceClusterNetworkAttachmentPrototypeInstanceContext]
          cluster_network_attachments: (optional) The cluster network attachments to
          create for this virtual server instance. A cluster network attachment represents
          a device that is connected to a cluster network. The number of network
          attachments must match one of the values from the instance profile's
          `cluster_network_attachment_count` before the instance can be started.
    :param str confidential_compute_mode: (optional) The confidential compute mode
          to use for this virtual server instance.
          If unspecified, the default confidential compute mode from the profile will be
          used.
    :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 bool enable_secure_boot: (optional) Indicates whether secure boot is
          enabled for this virtual server instance.
          If unspecified, the default secure boot mode from the profile will be used.
    :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.
          If specified, `reservation_affinity.policy` must be `disabled`.
    :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 InstanceReservationAffinityPrototype reservation_affinity: (optional)
    :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
          attachments or instance network interfaces.
    :param VolumeAttachmentPrototypeInstanceByImageContext boot_volume_attachment:
          (optional) The boot volume attachment to create for the virtual server instance.
    :param InstanceCatalogOfferingPrototype catalog_offering:
    :param ZoneIdentity zone: The zone this virtual server instance will reside in.
    :param List[NetworkInterfacePrototype] network_interfaces: (optional) The
          additional instance network interfaces to create.
    :param NetworkInterfacePrototype primary_network_interface: The primary instance
          network interface to create.
    """

    def __init__(
        self,
        catalog_offering: 'InstanceCatalogOfferingPrototype',
        zone: 'ZoneIdentity',
        primary_network_interface: 'NetworkInterfacePrototype',
        *,
        availability_policy: Optional['InstanceAvailabilityPolicyPrototype'] = None,
        cluster_network_attachments: Optional[List['InstanceClusterNetworkAttachmentPrototypeInstanceContext']] = None,
        confidential_compute_mode: Optional[str] = None,
        default_trusted_profile: Optional['InstanceDefaultTrustedProfilePrototype'] = None,
        enable_secure_boot: Optional[bool] = None,
        keys: Optional[List['KeyIdentity']] = None,
        metadata_service: Optional['InstanceMetadataServicePrototype'] = None,
        name: Optional[str] = None,
        placement_target: Optional['InstancePlacementTargetPrototype'] = None,
        profile: Optional['InstanceProfileIdentity'] = None,
        reservation_affinity: Optional['InstanceReservationAffinityPrototype'] = None,
        resource_group: Optional['ResourceGroupIdentity'] = None,
        total_volume_bandwidth: Optional[int] = None,
        user_data: Optional[str] = None,
        volume_attachments: Optional[List['VolumeAttachmentPrototype']] = None,
        vpc: Optional['VPCIdentity'] = None,
        boot_volume_attachment: Optional['VolumeAttachmentPrototypeInstanceByImageContext'] = None,
        network_interfaces: Optional[List['NetworkInterfacePrototype']] = None,
    ) -> None:
        """
        Initialize a InstanceTemplatePrototypeInstanceTemplateByCatalogOfferingInstanceTemplateByCatalogOfferingInstanceByNetworkInterface object.

        :param InstanceCatalogOfferingPrototype catalog_offering:
        :param ZoneIdentity zone: The zone this virtual server instance will reside
               in.
        :param NetworkInterfacePrototype primary_network_interface: The primary
               instance network interface to create.
        :param InstanceAvailabilityPolicyPrototype availability_policy: (optional)
               The availability policy to use for this virtual server instance.
        :param List[InstanceClusterNetworkAttachmentPrototypeInstanceContext]
               cluster_network_attachments: (optional) The cluster network attachments to
               create for this virtual server instance. A cluster network attachment
               represents a device that is connected to a cluster network. The number of
               network attachments must match one of the values from the instance
               profile's `cluster_network_attachment_count` before the instance can be
               started.
        :param str confidential_compute_mode: (optional) The confidential compute
               mode to use for this virtual server instance.
               If unspecified, the default confidential compute mode from the profile will
               be used.
        :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 bool enable_secure_boot: (optional) Indicates whether secure boot is
               enabled for this virtual server instance.
               If unspecified, the default secure boot mode from the profile will be used.
        :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.
               If specified, `reservation_affinity.policy` must be `disabled`.
        :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 InstanceReservationAffinityPrototype reservation_affinity:
               (optional)
        :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
               attachments or 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.cluster_network_attachments = cluster_network_attachments
        self.confidential_compute_mode = confidential_compute_mode
        self.default_trusted_profile = default_trusted_profile
        self.enable_secure_boot = enable_secure_boot
        self.keys = keys
        self.metadata_service = metadata_service
        self.name = name
        self.placement_target = placement_target
        self.profile = profile
        self.reservation_affinity = reservation_affinity
        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.zone = zone
        self.network_interfaces = network_interfaces
        self.primary_network_interface = primary_network_interface

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceTemplatePrototypeInstanceTemplateByCatalogOfferingInstanceTemplateByCatalogOfferingInstanceByNetworkInterface':
        """Initialize a InstanceTemplatePrototypeInstanceTemplateByCatalogOfferingInstanceTemplateByCatalogOfferingInstanceByNetworkInterface object from a json dictionary."""
        args = {}
        if (availability_policy := _dict.get('availability_policy')) is not None:
            args['availability_policy'] = InstanceAvailabilityPolicyPrototype.from_dict(availability_policy)
        if (cluster_network_attachments := _dict.get('cluster_network_attachments')) is not None:
            args['cluster_network_attachments'] = [InstanceClusterNetworkAttachmentPrototypeInstanceContext.from_dict(v) for v in cluster_network_attachments]
        if (confidential_compute_mode := _dict.get('confidential_compute_mode')) is not None:
            args['confidential_compute_mode'] = confidential_compute_mode
        if (default_trusted_profile := _dict.get('default_trusted_profile')) is not None:
            args['default_trusted_profile'] = InstanceDefaultTrustedProfilePrototype.from_dict(default_trusted_profile)
        if (enable_secure_boot := _dict.get('enable_secure_boot')) is not None:
            args['enable_secure_boot'] = enable_secure_boot
        if (keys := _dict.get('keys')) is not None:
            args['keys'] = keys
        if (metadata_service := _dict.get('metadata_service')) is not None:
            args['metadata_service'] = InstanceMetadataServicePrototype.from_dict(metadata_service)
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        if (placement_target := _dict.get('placement_target')) is not None:
            args['placement_target'] = placement_target
        if (profile := _dict.get('profile')) is not None:
            args['profile'] = profile
        if (reservation_affinity := _dict.get('reservation_affinity')) is not None:
            args['reservation_affinity'] = InstanceReservationAffinityPrototype.from_dict(reservation_affinity)
        if (resource_group := _dict.get('resource_group')) is not None:
            args['resource_group'] = resource_group
        if (total_volume_bandwidth := _dict.get('total_volume_bandwidth')) is not None:
            args['total_volume_bandwidth'] = total_volume_bandwidth
        if (user_data := _dict.get('user_data')) is not None:
            args['user_data'] = user_data
        if (volume_attachments := _dict.get('volume_attachments')) is not None:
            args['volume_attachments'] = [VolumeAttachmentPrototype.from_dict(v) for v in volume_attachments]
        if (vpc := _dict.get('vpc')) is not None:
            args['vpc'] = vpc
        if (boot_volume_attachment := _dict.get('boot_volume_attachment')) is not None:
            args['boot_volume_attachment'] = VolumeAttachmentPrototypeInstanceByImageContext.from_dict(boot_volume_attachment)
        if (catalog_offering := _dict.get('catalog_offering')) is not None:
            args['catalog_offering'] = catalog_offering
        else:
            raise ValueError('Required property \'catalog_offering\' not present in InstanceTemplatePrototypeInstanceTemplateByCatalogOfferingInstanceTemplateByCatalogOfferingInstanceByNetworkInterface JSON')
        if (zone := _dict.get('zone')) is not None:
            args['zone'] = zone
        else:
            raise ValueError('Required property \'zone\' not present in InstanceTemplatePrototypeInstanceTemplateByCatalogOfferingInstanceTemplateByCatalogOfferingInstanceByNetworkInterface JSON')
        if (network_interfaces := _dict.get('network_interfaces')) is not None:
            args['network_interfaces'] = [NetworkInterfacePrototype.from_dict(v) for v in network_interfaces]
        if (primary_network_interface := _dict.get('primary_network_interface')) is not None:
            args['primary_network_interface'] = NetworkInterfacePrototype.from_dict(primary_network_interface)
        else:
            raise ValueError('Required property \'primary_network_interface\' not present in InstanceTemplatePrototypeInstanceTemplateByCatalogOfferingInstanceTemplateByCatalogOfferingInstanceByNetworkInterface JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceTemplatePrototypeInstanceTemplateByCatalogOfferingInstanceTemplateByCatalogOfferingInstanceByNetworkInterface object from 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, 'cluster_network_attachments') and self.cluster_network_attachments is not None:
            cluster_network_attachments_list = []
            for v in self.cluster_network_attachments:
                if isinstance(v, dict):
                    cluster_network_attachments_list.append(v)
                else:
                    cluster_network_attachments_list.append(v.to_dict())
            _dict['cluster_network_attachments'] = cluster_network_attachments_list
        if hasattr(self, 'confidential_compute_mode') and self.confidential_compute_mode is not None:
            _dict['confidential_compute_mode'] = self.confidential_compute_mode
        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, 'enable_secure_boot') and self.enable_secure_boot is not None:
            _dict['enable_secure_boot'] = self.enable_secure_boot
        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, 'reservation_affinity') and self.reservation_affinity is not None:
            if isinstance(self.reservation_affinity, dict):
                _dict['reservation_affinity'] = self.reservation_affinity
            else:
                _dict['reservation_affinity'] = self.reservation_affinity.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, '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, '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()
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceTemplatePrototypeInstanceTemplateByCatalogOfferingInstanceTemplateByCatalogOfferingInstanceByNetworkInterface object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceTemplatePrototypeInstanceTemplateByCatalogOfferingInstanceTemplateByCatalogOfferingInstanceByNetworkInterface') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceTemplatePrototypeInstanceTemplateByCatalogOfferingInstanceTemplateByCatalogOfferingInstanceByNetworkInterface') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ConfidentialComputeModeEnum(str, Enum):
        """
        The confidential compute mode to use for this virtual server instance.
        If unspecified, the default confidential compute mode from the profile will be
        used.
        """

        DISABLED = 'disabled'
        SGX = 'sgx'



class InstanceTemplatePrototypeInstanceTemplateByImageInstanceTemplateByImageInstanceByNetworkAttachment(InstanceTemplatePrototypeInstanceTemplateByImage):
    """
    InstanceTemplatePrototypeInstanceTemplateByImageInstanceTemplateByImageInstanceByNetworkAttachment.

    :param InstanceAvailabilityPolicyPrototype availability_policy: (optional) The
          availability policy to use for this virtual server instance.
    :param List[InstanceClusterNetworkAttachmentPrototypeInstanceContext]
          cluster_network_attachments: (optional) The cluster network attachments to
          create for this virtual server instance. A cluster network attachment represents
          a device that is connected to a cluster network. The number of network
          attachments must match one of the values from the instance profile's
          `cluster_network_attachment_count` before the instance can be started.
    :param str confidential_compute_mode: (optional) The confidential compute mode
          to use for this virtual server instance.
          If unspecified, the default confidential compute mode from the profile will be
          used.
    :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 bool enable_secure_boot: (optional) Indicates whether secure boot is
          enabled for this virtual server instance.
          If unspecified, the default secure boot mode from the profile will be used.
    :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.
          If specified, `reservation_affinity.policy` must be `disabled`.
    :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 InstanceReservationAffinityPrototype reservation_affinity: (optional)
    :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
          attachments or instance network interfaces.
    :param VolumeAttachmentPrototypeInstanceByImageContext boot_volume_attachment:
          (optional) The boot volume attachment to create for the virtual server instance.
    :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 List[InstanceNetworkAttachmentPrototype] network_attachments: (optional)
          The additional network attachments to create for the virtual server instance.
    :param InstanceNetworkAttachmentPrototype primary_network_attachment: The
          primary network attachment to create for the virtual server instance.
    """

    def __init__(
        self,
        image: 'ImageIdentity',
        zone: 'ZoneIdentity',
        primary_network_attachment: 'InstanceNetworkAttachmentPrototype',
        *,
        availability_policy: Optional['InstanceAvailabilityPolicyPrototype'] = None,
        cluster_network_attachments: Optional[List['InstanceClusterNetworkAttachmentPrototypeInstanceContext']] = None,
        confidential_compute_mode: Optional[str] = None,
        default_trusted_profile: Optional['InstanceDefaultTrustedProfilePrototype'] = None,
        enable_secure_boot: Optional[bool] = None,
        keys: Optional[List['KeyIdentity']] = None,
        metadata_service: Optional['InstanceMetadataServicePrototype'] = None,
        name: Optional[str] = None,
        placement_target: Optional['InstancePlacementTargetPrototype'] = None,
        profile: Optional['InstanceProfileIdentity'] = None,
        reservation_affinity: Optional['InstanceReservationAffinityPrototype'] = None,
        resource_group: Optional['ResourceGroupIdentity'] = None,
        total_volume_bandwidth: Optional[int] = None,
        user_data: Optional[str] = None,
        volume_attachments: Optional[List['VolumeAttachmentPrototype']] = None,
        vpc: Optional['VPCIdentity'] = None,
        boot_volume_attachment: Optional['VolumeAttachmentPrototypeInstanceByImageContext'] = None,
        network_attachments: Optional[List['InstanceNetworkAttachmentPrototype']] = None,
    ) -> None:
        """
        Initialize a InstanceTemplatePrototypeInstanceTemplateByImageInstanceTemplateByImageInstanceByNetworkAttachment object.

        :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 InstanceNetworkAttachmentPrototype primary_network_attachment: The
               primary network attachment to create for the virtual server instance.
        :param InstanceAvailabilityPolicyPrototype availability_policy: (optional)
               The availability policy to use for this virtual server instance.
        :param List[InstanceClusterNetworkAttachmentPrototypeInstanceContext]
               cluster_network_attachments: (optional) The cluster network attachments to
               create for this virtual server instance. A cluster network attachment
               represents a device that is connected to a cluster network. The number of
               network attachments must match one of the values from the instance
               profile's `cluster_network_attachment_count` before the instance can be
               started.
        :param str confidential_compute_mode: (optional) The confidential compute
               mode to use for this virtual server instance.
               If unspecified, the default confidential compute mode from the profile will
               be used.
        :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 bool enable_secure_boot: (optional) Indicates whether secure boot is
               enabled for this virtual server instance.
               If unspecified, the default secure boot mode from the profile will be used.
        :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.
               If specified, `reservation_affinity.policy` must be `disabled`.
        :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 InstanceReservationAffinityPrototype reservation_affinity:
               (optional)
        :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
               attachments or instance network interfaces.
        :param VolumeAttachmentPrototypeInstanceByImageContext
               boot_volume_attachment: (optional) The boot volume attachment to create for
               the virtual server instance.
        :param List[InstanceNetworkAttachmentPrototype] network_attachments:
               (optional) The additional network attachments to create for the virtual
               server instance.
        """
        # pylint: disable=super-init-not-called
        self.availability_policy = availability_policy
        self.cluster_network_attachments = cluster_network_attachments
        self.confidential_compute_mode = confidential_compute_mode
        self.default_trusted_profile = default_trusted_profile
        self.enable_secure_boot = enable_secure_boot
        self.keys = keys
        self.metadata_service = metadata_service
        self.name = name
        self.placement_target = placement_target
        self.profile = profile
        self.reservation_affinity = reservation_affinity
        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.zone = zone
        self.network_attachments = network_attachments
        self.primary_network_attachment = primary_network_attachment

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceTemplatePrototypeInstanceTemplateByImageInstanceTemplateByImageInstanceByNetworkAttachment':
        """Initialize a InstanceTemplatePrototypeInstanceTemplateByImageInstanceTemplateByImageInstanceByNetworkAttachment object from a json dictionary."""
        args = {}
        if (availability_policy := _dict.get('availability_policy')) is not None:
            args['availability_policy'] = InstanceAvailabilityPolicyPrototype.from_dict(availability_policy)
        if (cluster_network_attachments := _dict.get('cluster_network_attachments')) is not None:
            args['cluster_network_attachments'] = [InstanceClusterNetworkAttachmentPrototypeInstanceContext.from_dict(v) for v in cluster_network_attachments]
        if (confidential_compute_mode := _dict.get('confidential_compute_mode')) is not None:
            args['confidential_compute_mode'] = confidential_compute_mode
        if (default_trusted_profile := _dict.get('default_trusted_profile')) is not None:
            args['default_trusted_profile'] = InstanceDefaultTrustedProfilePrototype.from_dict(default_trusted_profile)
        if (enable_secure_boot := _dict.get('enable_secure_boot')) is not None:
            args['enable_secure_boot'] = enable_secure_boot
        if (keys := _dict.get('keys')) is not None:
            args['keys'] = keys
        if (metadata_service := _dict.get('metadata_service')) is not None:
            args['metadata_service'] = InstanceMetadataServicePrototype.from_dict(metadata_service)
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        if (placement_target := _dict.get('placement_target')) is not None:
            args['placement_target'] = placement_target
        if (profile := _dict.get('profile')) is not None:
            args['profile'] = profile
        if (reservation_affinity := _dict.get('reservation_affinity')) is not None:
            args['reservation_affinity'] = InstanceReservationAffinityPrototype.from_dict(reservation_affinity)
        if (resource_group := _dict.get('resource_group')) is not None:
            args['resource_group'] = resource_group
        if (total_volume_bandwidth := _dict.get('total_volume_bandwidth')) is not None:
            args['total_volume_bandwidth'] = total_volume_bandwidth
        if (user_data := _dict.get('user_data')) is not None:
            args['user_data'] = user_data
        if (volume_attachments := _dict.get('volume_attachments')) is not None:
            args['volume_attachments'] = [VolumeAttachmentPrototype.from_dict(v) for v in volume_attachments]
        if (vpc := _dict.get('vpc')) is not None:
            args['vpc'] = vpc
        if (boot_volume_attachment := _dict.get('boot_volume_attachment')) is not None:
            args['boot_volume_attachment'] = VolumeAttachmentPrototypeInstanceByImageContext.from_dict(boot_volume_attachment)
        if (image := _dict.get('image')) is not None:
            args['image'] = image
        else:
            raise ValueError('Required property \'image\' not present in InstanceTemplatePrototypeInstanceTemplateByImageInstanceTemplateByImageInstanceByNetworkAttachment JSON')
        if (zone := _dict.get('zone')) is not None:
            args['zone'] = zone
        else:
            raise ValueError('Required property \'zone\' not present in InstanceTemplatePrototypeInstanceTemplateByImageInstanceTemplateByImageInstanceByNetworkAttachment JSON')
        if (network_attachments := _dict.get('network_attachments')) is not None:
            args['network_attachments'] = [InstanceNetworkAttachmentPrototype.from_dict(v) for v in network_attachments]
        if (primary_network_attachment := _dict.get('primary_network_attachment')) is not None:
            args['primary_network_attachment'] = InstanceNetworkAttachmentPrototype.from_dict(primary_network_attachment)
        else:
            raise ValueError('Required property \'primary_network_attachment\' not present in InstanceTemplatePrototypeInstanceTemplateByImageInstanceTemplateByImageInstanceByNetworkAttachment JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceTemplatePrototypeInstanceTemplateByImageInstanceTemplateByImageInstanceByNetworkAttachment object from 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, 'cluster_network_attachments') and self.cluster_network_attachments is not None:
            cluster_network_attachments_list = []
            for v in self.cluster_network_attachments:
                if isinstance(v, dict):
                    cluster_network_attachments_list.append(v)
                else:
                    cluster_network_attachments_list.append(v.to_dict())
            _dict['cluster_network_attachments'] = cluster_network_attachments_list
        if hasattr(self, 'confidential_compute_mode') and self.confidential_compute_mode is not None:
            _dict['confidential_compute_mode'] = self.confidential_compute_mode
        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, 'enable_secure_boot') and self.enable_secure_boot is not None:
            _dict['enable_secure_boot'] = self.enable_secure_boot
        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, 'reservation_affinity') and self.reservation_affinity is not None:
            if isinstance(self.reservation_affinity, dict):
                _dict['reservation_affinity'] = self.reservation_affinity
            else:
                _dict['reservation_affinity'] = self.reservation_affinity.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, '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, 'network_attachments') and self.network_attachments is not None:
            network_attachments_list = []
            for v in self.network_attachments:
                if isinstance(v, dict):
                    network_attachments_list.append(v)
                else:
                    network_attachments_list.append(v.to_dict())
            _dict['network_attachments'] = network_attachments_list
        if hasattr(self, 'primary_network_attachment') and self.primary_network_attachment is not None:
            if isinstance(self.primary_network_attachment, dict):
                _dict['primary_network_attachment'] = self.primary_network_attachment
            else:
                _dict['primary_network_attachment'] = self.primary_network_attachment.to_dict()
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceTemplatePrototypeInstanceTemplateByImageInstanceTemplateByImageInstanceByNetworkAttachment object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceTemplatePrototypeInstanceTemplateByImageInstanceTemplateByImageInstanceByNetworkAttachment') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceTemplatePrototypeInstanceTemplateByImageInstanceTemplateByImageInstanceByNetworkAttachment') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ConfidentialComputeModeEnum(str, Enum):
        """
        The confidential compute mode to use for this virtual server instance.
        If unspecified, the default confidential compute mode from the profile will be
        used.
        """

        DISABLED = 'disabled'
        SGX = 'sgx'



class InstanceTemplatePrototypeInstanceTemplateByImageInstanceTemplateByImageInstanceByNetworkInterface(InstanceTemplatePrototypeInstanceTemplateByImage):
    """
    InstanceTemplatePrototypeInstanceTemplateByImageInstanceTemplateByImageInstanceByNetworkInterface.

    :param InstanceAvailabilityPolicyPrototype availability_policy: (optional) The
          availability policy to use for this virtual server instance.
    :param List[InstanceClusterNetworkAttachmentPrototypeInstanceContext]
          cluster_network_attachments: (optional) The cluster network attachments to
          create for this virtual server instance. A cluster network attachment represents
          a device that is connected to a cluster network. The number of network
          attachments must match one of the values from the instance profile's
          `cluster_network_attachment_count` before the instance can be started.
    :param str confidential_compute_mode: (optional) The confidential compute mode
          to use for this virtual server instance.
          If unspecified, the default confidential compute mode from the profile will be
          used.
    :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 bool enable_secure_boot: (optional) Indicates whether secure boot is
          enabled for this virtual server instance.
          If unspecified, the default secure boot mode from the profile will be used.
    :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.
          If specified, `reservation_affinity.policy` must be `disabled`.
    :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 InstanceReservationAffinityPrototype reservation_affinity: (optional)
    :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
          attachments or instance network interfaces.
    :param VolumeAttachmentPrototypeInstanceByImageContext boot_volume_attachment:
          (optional) The boot volume attachment to create for the virtual server instance.
    :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 List[NetworkInterfacePrototype] network_interfaces: (optional) The
          additional instance network interfaces to create.
    :param NetworkInterfacePrototype primary_network_interface: The primary instance
          network interface to create.
    """

    def __init__(
        self,
        image: 'ImageIdentity',
        zone: 'ZoneIdentity',
        primary_network_interface: 'NetworkInterfacePrototype',
        *,
        availability_policy: Optional['InstanceAvailabilityPolicyPrototype'] = None,
        cluster_network_attachments: Optional[List['InstanceClusterNetworkAttachmentPrototypeInstanceContext']] = None,
        confidential_compute_mode: Optional[str] = None,
        default_trusted_profile: Optional['InstanceDefaultTrustedProfilePrototype'] = None,
        enable_secure_boot: Optional[bool] = None,
        keys: Optional[List['KeyIdentity']] = None,
        metadata_service: Optional['InstanceMetadataServicePrototype'] = None,
        name: Optional[str] = None,
        placement_target: Optional['InstancePlacementTargetPrototype'] = None,
        profile: Optional['InstanceProfileIdentity'] = None,
        reservation_affinity: Optional['InstanceReservationAffinityPrototype'] = None,
        resource_group: Optional['ResourceGroupIdentity'] = None,
        total_volume_bandwidth: Optional[int] = None,
        user_data: Optional[str] = None,
        volume_attachments: Optional[List['VolumeAttachmentPrototype']] = None,
        vpc: Optional['VPCIdentity'] = None,
        boot_volume_attachment: Optional['VolumeAttachmentPrototypeInstanceByImageContext'] = None,
        network_interfaces: Optional[List['NetworkInterfacePrototype']] = None,
    ) -> None:
        """
        Initialize a InstanceTemplatePrototypeInstanceTemplateByImageInstanceTemplateByImageInstanceByNetworkInterface object.

        :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 NetworkInterfacePrototype primary_network_interface: The primary
               instance network interface to create.
        :param InstanceAvailabilityPolicyPrototype availability_policy: (optional)
               The availability policy to use for this virtual server instance.
        :param List[InstanceClusterNetworkAttachmentPrototypeInstanceContext]
               cluster_network_attachments: (optional) The cluster network attachments to
               create for this virtual server instance. A cluster network attachment
               represents a device that is connected to a cluster network. The number of
               network attachments must match one of the values from the instance
               profile's `cluster_network_attachment_count` before the instance can be
               started.
        :param str confidential_compute_mode: (optional) The confidential compute
               mode to use for this virtual server instance.
               If unspecified, the default confidential compute mode from the profile will
               be used.
        :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 bool enable_secure_boot: (optional) Indicates whether secure boot is
               enabled for this virtual server instance.
               If unspecified, the default secure boot mode from the profile will be used.
        :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.
               If specified, `reservation_affinity.policy` must be `disabled`.
        :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 InstanceReservationAffinityPrototype reservation_affinity:
               (optional)
        :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
               attachments or 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.cluster_network_attachments = cluster_network_attachments
        self.confidential_compute_mode = confidential_compute_mode
        self.default_trusted_profile = default_trusted_profile
        self.enable_secure_boot = enable_secure_boot
        self.keys = keys
        self.metadata_service = metadata_service
        self.name = name
        self.placement_target = placement_target
        self.profile = profile
        self.reservation_affinity = reservation_affinity
        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.zone = zone
        self.network_interfaces = network_interfaces
        self.primary_network_interface = primary_network_interface

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceTemplatePrototypeInstanceTemplateByImageInstanceTemplateByImageInstanceByNetworkInterface':
        """Initialize a InstanceTemplatePrototypeInstanceTemplateByImageInstanceTemplateByImageInstanceByNetworkInterface object from a json dictionary."""
        args = {}
        if (availability_policy := _dict.get('availability_policy')) is not None:
            args['availability_policy'] = InstanceAvailabilityPolicyPrototype.from_dict(availability_policy)
        if (cluster_network_attachments := _dict.get('cluster_network_attachments')) is not None:
            args['cluster_network_attachments'] = [InstanceClusterNetworkAttachmentPrototypeInstanceContext.from_dict(v) for v in cluster_network_attachments]
        if (confidential_compute_mode := _dict.get('confidential_compute_mode')) is not None:
            args['confidential_compute_mode'] = confidential_compute_mode
        if (default_trusted_profile := _dict.get('default_trusted_profile')) is not None:
            args['default_trusted_profile'] = InstanceDefaultTrustedProfilePrototype.from_dict(default_trusted_profile)
        if (enable_secure_boot := _dict.get('enable_secure_boot')) is not None:
            args['enable_secure_boot'] = enable_secure_boot
        if (keys := _dict.get('keys')) is not None:
            args['keys'] = keys
        if (metadata_service := _dict.get('metadata_service')) is not None:
            args['metadata_service'] = InstanceMetadataServicePrototype.from_dict(metadata_service)
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        if (placement_target := _dict.get('placement_target')) is not None:
            args['placement_target'] = placement_target
        if (profile := _dict.get('profile')) is not None:
            args['profile'] = profile
        if (reservation_affinity := _dict.get('reservation_affinity')) is not None:
            args['reservation_affinity'] = InstanceReservationAffinityPrototype.from_dict(reservation_affinity)
        if (resource_group := _dict.get('resource_group')) is not None:
            args['resource_group'] = resource_group
        if (total_volume_bandwidth := _dict.get('total_volume_bandwidth')) is not None:
            args['total_volume_bandwidth'] = total_volume_bandwidth
        if (user_data := _dict.get('user_data')) is not None:
            args['user_data'] = user_data
        if (volume_attachments := _dict.get('volume_attachments')) is not None:
            args['volume_attachments'] = [VolumeAttachmentPrototype.from_dict(v) for v in volume_attachments]
        if (vpc := _dict.get('vpc')) is not None:
            args['vpc'] = vpc
        if (boot_volume_attachment := _dict.get('boot_volume_attachment')) is not None:
            args['boot_volume_attachment'] = VolumeAttachmentPrototypeInstanceByImageContext.from_dict(boot_volume_attachment)
        if (image := _dict.get('image')) is not None:
            args['image'] = image
        else:
            raise ValueError('Required property \'image\' not present in InstanceTemplatePrototypeInstanceTemplateByImageInstanceTemplateByImageInstanceByNetworkInterface JSON')
        if (zone := _dict.get('zone')) is not None:
            args['zone'] = zone
        else:
            raise ValueError('Required property \'zone\' not present in InstanceTemplatePrototypeInstanceTemplateByImageInstanceTemplateByImageInstanceByNetworkInterface JSON')
        if (network_interfaces := _dict.get('network_interfaces')) is not None:
            args['network_interfaces'] = [NetworkInterfacePrototype.from_dict(v) for v in network_interfaces]
        if (primary_network_interface := _dict.get('primary_network_interface')) is not None:
            args['primary_network_interface'] = NetworkInterfacePrototype.from_dict(primary_network_interface)
        else:
            raise ValueError('Required property \'primary_network_interface\' not present in InstanceTemplatePrototypeInstanceTemplateByImageInstanceTemplateByImageInstanceByNetworkInterface JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceTemplatePrototypeInstanceTemplateByImageInstanceTemplateByImageInstanceByNetworkInterface object from 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, 'cluster_network_attachments') and self.cluster_network_attachments is not None:
            cluster_network_attachments_list = []
            for v in self.cluster_network_attachments:
                if isinstance(v, dict):
                    cluster_network_attachments_list.append(v)
                else:
                    cluster_network_attachments_list.append(v.to_dict())
            _dict['cluster_network_attachments'] = cluster_network_attachments_list
        if hasattr(self, 'confidential_compute_mode') and self.confidential_compute_mode is not None:
            _dict['confidential_compute_mode'] = self.confidential_compute_mode
        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, 'enable_secure_boot') and self.enable_secure_boot is not None:
            _dict['enable_secure_boot'] = self.enable_secure_boot
        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, 'reservation_affinity') and self.reservation_affinity is not None:
            if isinstance(self.reservation_affinity, dict):
                _dict['reservation_affinity'] = self.reservation_affinity
            else:
                _dict['reservation_affinity'] = self.reservation_affinity.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, '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, '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()
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceTemplatePrototypeInstanceTemplateByImageInstanceTemplateByImageInstanceByNetworkInterface object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceTemplatePrototypeInstanceTemplateByImageInstanceTemplateByImageInstanceByNetworkInterface') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceTemplatePrototypeInstanceTemplateByImageInstanceTemplateByImageInstanceByNetworkInterface') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ConfidentialComputeModeEnum(str, Enum):
        """
        The confidential compute mode to use for this virtual server instance.
        If unspecified, the default confidential compute mode from the profile will be
        used.
        """

        DISABLED = 'disabled'
        SGX = 'sgx'



class InstanceTemplatePrototypeInstanceTemplateBySourceSnapshotInstanceTemplateBySourceSnapshotInstanceByNetworkAttachment(InstanceTemplatePrototypeInstanceTemplateBySourceSnapshot):
    """
    InstanceTemplatePrototypeInstanceTemplateBySourceSnapshotInstanceTemplateBySourceSnapshotInstanceByNetworkAttachment.

    :param InstanceAvailabilityPolicyPrototype availability_policy: (optional) The
          availability policy to use for this virtual server instance.
    :param List[InstanceClusterNetworkAttachmentPrototypeInstanceContext]
          cluster_network_attachments: (optional) The cluster network attachments to
          create for this virtual server instance. A cluster network attachment represents
          a device that is connected to a cluster network. The number of network
          attachments must match one of the values from the instance profile's
          `cluster_network_attachment_count` before the instance can be started.
    :param str confidential_compute_mode: (optional) The confidential compute mode
          to use for this virtual server instance.
          If unspecified, the default confidential compute mode from the profile will be
          used.
    :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 bool enable_secure_boot: (optional) Indicates whether secure boot is
          enabled for this virtual server instance.
          If unspecified, the default secure boot mode from the profile will be used.
    :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.
          If specified, `reservation_affinity.policy` must be `disabled`.
    :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 InstanceReservationAffinityPrototype reservation_affinity: (optional)
    :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
          attachments or instance network interfaces.
    :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 List[InstanceNetworkAttachmentPrototype] network_attachments: (optional)
          The additional network attachments to create for the virtual server instance.
    :param InstanceNetworkAttachmentPrototype primary_network_attachment: The
          primary network attachment to create for the virtual server instance.
    """

    def __init__(
        self,
        boot_volume_attachment: 'VolumeAttachmentPrototypeInstanceBySourceSnapshotContext',
        zone: 'ZoneIdentity',
        primary_network_attachment: 'InstanceNetworkAttachmentPrototype',
        *,
        availability_policy: Optional['InstanceAvailabilityPolicyPrototype'] = None,
        cluster_network_attachments: Optional[List['InstanceClusterNetworkAttachmentPrototypeInstanceContext']] = None,
        confidential_compute_mode: Optional[str] = None,
        default_trusted_profile: Optional['InstanceDefaultTrustedProfilePrototype'] = None,
        enable_secure_boot: Optional[bool] = None,
        keys: Optional[List['KeyIdentity']] = None,
        metadata_service: Optional['InstanceMetadataServicePrototype'] = None,
        name: Optional[str] = None,
        placement_target: Optional['InstancePlacementTargetPrototype'] = None,
        profile: Optional['InstanceProfileIdentity'] = None,
        reservation_affinity: Optional['InstanceReservationAffinityPrototype'] = None,
        resource_group: Optional['ResourceGroupIdentity'] = None,
        total_volume_bandwidth: Optional[int] = None,
        user_data: Optional[str] = None,
        volume_attachments: Optional[List['VolumeAttachmentPrototype']] = None,
        vpc: Optional['VPCIdentity'] = None,
        network_attachments: Optional[List['InstanceNetworkAttachmentPrototype']] = None,
    ) -> None:
        """
        Initialize a InstanceTemplatePrototypeInstanceTemplateBySourceSnapshotInstanceTemplateBySourceSnapshotInstanceByNetworkAttachment object.

        :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 InstanceNetworkAttachmentPrototype primary_network_attachment: The
               primary network attachment to create for the virtual server instance.
        :param InstanceAvailabilityPolicyPrototype availability_policy: (optional)
               The availability policy to use for this virtual server instance.
        :param List[InstanceClusterNetworkAttachmentPrototypeInstanceContext]
               cluster_network_attachments: (optional) The cluster network attachments to
               create for this virtual server instance. A cluster network attachment
               represents a device that is connected to a cluster network. The number of
               network attachments must match one of the values from the instance
               profile's `cluster_network_attachment_count` before the instance can be
               started.
        :param str confidential_compute_mode: (optional) The confidential compute
               mode to use for this virtual server instance.
               If unspecified, the default confidential compute mode from the profile will
               be used.
        :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 bool enable_secure_boot: (optional) Indicates whether secure boot is
               enabled for this virtual server instance.
               If unspecified, the default secure boot mode from the profile will be used.
        :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.
               If specified, `reservation_affinity.policy` must be `disabled`.
        :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 InstanceReservationAffinityPrototype reservation_affinity:
               (optional)
        :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
               attachments or instance network interfaces.
        :param List[InstanceNetworkAttachmentPrototype] network_attachments:
               (optional) The additional network attachments to create for the virtual
               server instance.
        """
        # pylint: disable=super-init-not-called
        self.availability_policy = availability_policy
        self.cluster_network_attachments = cluster_network_attachments
        self.confidential_compute_mode = confidential_compute_mode
        self.default_trusted_profile = default_trusted_profile
        self.enable_secure_boot = enable_secure_boot
        self.keys = keys
        self.metadata_service = metadata_service
        self.name = name
        self.placement_target = placement_target
        self.profile = profile
        self.reservation_affinity = reservation_affinity
        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.zone = zone
        self.network_attachments = network_attachments
        self.primary_network_attachment = primary_network_attachment

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceTemplatePrototypeInstanceTemplateBySourceSnapshotInstanceTemplateBySourceSnapshotInstanceByNetworkAttachment':
        """Initialize a InstanceTemplatePrototypeInstanceTemplateBySourceSnapshotInstanceTemplateBySourceSnapshotInstanceByNetworkAttachment object from a json dictionary."""
        args = {}
        if (availability_policy := _dict.get('availability_policy')) is not None:
            args['availability_policy'] = InstanceAvailabilityPolicyPrototype.from_dict(availability_policy)
        if (cluster_network_attachments := _dict.get('cluster_network_attachments')) is not None:
            args['cluster_network_attachments'] = [InstanceClusterNetworkAttachmentPrototypeInstanceContext.from_dict(v) for v in cluster_network_attachments]
        if (confidential_compute_mode := _dict.get('confidential_compute_mode')) is not None:
            args['confidential_compute_mode'] = confidential_compute_mode
        if (default_trusted_profile := _dict.get('default_trusted_profile')) is not None:
            args['default_trusted_profile'] = InstanceDefaultTrustedProfilePrototype.from_dict(default_trusted_profile)
        if (enable_secure_boot := _dict.get('enable_secure_boot')) is not None:
            args['enable_secure_boot'] = enable_secure_boot
        if (keys := _dict.get('keys')) is not None:
            args['keys'] = keys
        if (metadata_service := _dict.get('metadata_service')) is not None:
            args['metadata_service'] = InstanceMetadataServicePrototype.from_dict(metadata_service)
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        if (placement_target := _dict.get('placement_target')) is not None:
            args['placement_target'] = placement_target
        if (profile := _dict.get('profile')) is not None:
            args['profile'] = profile
        if (reservation_affinity := _dict.get('reservation_affinity')) is not None:
            args['reservation_affinity'] = InstanceReservationAffinityPrototype.from_dict(reservation_affinity)
        if (resource_group := _dict.get('resource_group')) is not None:
            args['resource_group'] = resource_group
        if (total_volume_bandwidth := _dict.get('total_volume_bandwidth')) is not None:
            args['total_volume_bandwidth'] = total_volume_bandwidth
        if (user_data := _dict.get('user_data')) is not None:
            args['user_data'] = user_data
        if (volume_attachments := _dict.get('volume_attachments')) is not None:
            args['volume_attachments'] = [VolumeAttachmentPrototype.from_dict(v) for v in volume_attachments]
        if (vpc := _dict.get('vpc')) is not None:
            args['vpc'] = vpc
        if (boot_volume_attachment := _dict.get('boot_volume_attachment')) is not None:
            args['boot_volume_attachment'] = VolumeAttachmentPrototypeInstanceBySourceSnapshotContext.from_dict(boot_volume_attachment)
        else:
            raise ValueError('Required property \'boot_volume_attachment\' not present in InstanceTemplatePrototypeInstanceTemplateBySourceSnapshotInstanceTemplateBySourceSnapshotInstanceByNetworkAttachment JSON')
        if (zone := _dict.get('zone')) is not None:
            args['zone'] = zone
        else:
            raise ValueError('Required property \'zone\' not present in InstanceTemplatePrototypeInstanceTemplateBySourceSnapshotInstanceTemplateBySourceSnapshotInstanceByNetworkAttachment JSON')
        if (network_attachments := _dict.get('network_attachments')) is not None:
            args['network_attachments'] = [InstanceNetworkAttachmentPrototype.from_dict(v) for v in network_attachments]
        if (primary_network_attachment := _dict.get('primary_network_attachment')) is not None:
            args['primary_network_attachment'] = InstanceNetworkAttachmentPrototype.from_dict(primary_network_attachment)
        else:
            raise ValueError('Required property \'primary_network_attachment\' not present in InstanceTemplatePrototypeInstanceTemplateBySourceSnapshotInstanceTemplateBySourceSnapshotInstanceByNetworkAttachment JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceTemplatePrototypeInstanceTemplateBySourceSnapshotInstanceTemplateBySourceSnapshotInstanceByNetworkAttachment object from 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, 'cluster_network_attachments') and self.cluster_network_attachments is not None:
            cluster_network_attachments_list = []
            for v in self.cluster_network_attachments:
                if isinstance(v, dict):
                    cluster_network_attachments_list.append(v)
                else:
                    cluster_network_attachments_list.append(v.to_dict())
            _dict['cluster_network_attachments'] = cluster_network_attachments_list
        if hasattr(self, 'confidential_compute_mode') and self.confidential_compute_mode is not None:
            _dict['confidential_compute_mode'] = self.confidential_compute_mode
        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, 'enable_secure_boot') and self.enable_secure_boot is not None:
            _dict['enable_secure_boot'] = self.enable_secure_boot
        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, 'reservation_affinity') and self.reservation_affinity is not None:
            if isinstance(self.reservation_affinity, dict):
                _dict['reservation_affinity'] = self.reservation_affinity
            else:
                _dict['reservation_affinity'] = self.reservation_affinity.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, '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, 'network_attachments') and self.network_attachments is not None:
            network_attachments_list = []
            for v in self.network_attachments:
                if isinstance(v, dict):
                    network_attachments_list.append(v)
                else:
                    network_attachments_list.append(v.to_dict())
            _dict['network_attachments'] = network_attachments_list
        if hasattr(self, 'primary_network_attachment') and self.primary_network_attachment is not None:
            if isinstance(self.primary_network_attachment, dict):
                _dict['primary_network_attachment'] = self.primary_network_attachment
            else:
                _dict['primary_network_attachment'] = self.primary_network_attachment.to_dict()
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceTemplatePrototypeInstanceTemplateBySourceSnapshotInstanceTemplateBySourceSnapshotInstanceByNetworkAttachment object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceTemplatePrototypeInstanceTemplateBySourceSnapshotInstanceTemplateBySourceSnapshotInstanceByNetworkAttachment') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceTemplatePrototypeInstanceTemplateBySourceSnapshotInstanceTemplateBySourceSnapshotInstanceByNetworkAttachment') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ConfidentialComputeModeEnum(str, Enum):
        """
        The confidential compute mode to use for this virtual server instance.
        If unspecified, the default confidential compute mode from the profile will be
        used.
        """

        DISABLED = 'disabled'
        SGX = 'sgx'



class InstanceTemplatePrototypeInstanceTemplateBySourceSnapshotInstanceTemplateBySourceSnapshotInstanceByNetworkInterface(InstanceTemplatePrototypeInstanceTemplateBySourceSnapshot):
    """
    InstanceTemplatePrototypeInstanceTemplateBySourceSnapshotInstanceTemplateBySourceSnapshotInstanceByNetworkInterface.

    :param InstanceAvailabilityPolicyPrototype availability_policy: (optional) The
          availability policy to use for this virtual server instance.
    :param List[InstanceClusterNetworkAttachmentPrototypeInstanceContext]
          cluster_network_attachments: (optional) The cluster network attachments to
          create for this virtual server instance. A cluster network attachment represents
          a device that is connected to a cluster network. The number of network
          attachments must match one of the values from the instance profile's
          `cluster_network_attachment_count` before the instance can be started.
    :param str confidential_compute_mode: (optional) The confidential compute mode
          to use for this virtual server instance.
          If unspecified, the default confidential compute mode from the profile will be
          used.
    :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 bool enable_secure_boot: (optional) Indicates whether secure boot is
          enabled for this virtual server instance.
          If unspecified, the default secure boot mode from the profile will be used.
    :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.
          If specified, `reservation_affinity.policy` must be `disabled`.
    :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 InstanceReservationAffinityPrototype reservation_affinity: (optional)
    :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
          attachments or instance network interfaces.
    :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 List[NetworkInterfacePrototype] network_interfaces: (optional) The
          additional instance network interfaces to create.
    :param NetworkInterfacePrototype primary_network_interface: The primary instance
          network interface to create.
    """

    def __init__(
        self,
        boot_volume_attachment: 'VolumeAttachmentPrototypeInstanceBySourceSnapshotContext',
        zone: 'ZoneIdentity',
        primary_network_interface: 'NetworkInterfacePrototype',
        *,
        availability_policy: Optional['InstanceAvailabilityPolicyPrototype'] = None,
        cluster_network_attachments: Optional[List['InstanceClusterNetworkAttachmentPrototypeInstanceContext']] = None,
        confidential_compute_mode: Optional[str] = None,
        default_trusted_profile: Optional['InstanceDefaultTrustedProfilePrototype'] = None,
        enable_secure_boot: Optional[bool] = None,
        keys: Optional[List['KeyIdentity']] = None,
        metadata_service: Optional['InstanceMetadataServicePrototype'] = None,
        name: Optional[str] = None,
        placement_target: Optional['InstancePlacementTargetPrototype'] = None,
        profile: Optional['InstanceProfileIdentity'] = None,
        reservation_affinity: Optional['InstanceReservationAffinityPrototype'] = None,
        resource_group: Optional['ResourceGroupIdentity'] = None,
        total_volume_bandwidth: Optional[int] = None,
        user_data: Optional[str] = None,
        volume_attachments: Optional[List['VolumeAttachmentPrototype']] = None,
        vpc: Optional['VPCIdentity'] = None,
        network_interfaces: Optional[List['NetworkInterfacePrototype']] = None,
    ) -> None:
        """
        Initialize a InstanceTemplatePrototypeInstanceTemplateBySourceSnapshotInstanceTemplateBySourceSnapshotInstanceByNetworkInterface object.

        :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 NetworkInterfacePrototype primary_network_interface: The primary
               instance network interface to create.
        :param InstanceAvailabilityPolicyPrototype availability_policy: (optional)
               The availability policy to use for this virtual server instance.
        :param List[InstanceClusterNetworkAttachmentPrototypeInstanceContext]
               cluster_network_attachments: (optional) The cluster network attachments to
               create for this virtual server instance. A cluster network attachment
               represents a device that is connected to a cluster network. The number of
               network attachments must match one of the values from the instance
               profile's `cluster_network_attachment_count` before the instance can be
               started.
        :param str confidential_compute_mode: (optional) The confidential compute
               mode to use for this virtual server instance.
               If unspecified, the default confidential compute mode from the profile will
               be used.
        :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 bool enable_secure_boot: (optional) Indicates whether secure boot is
               enabled for this virtual server instance.
               If unspecified, the default secure boot mode from the profile will be used.
        :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.
               If specified, `reservation_affinity.policy` must be `disabled`.
        :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 InstanceReservationAffinityPrototype reservation_affinity:
               (optional)
        :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
               attachments or 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.cluster_network_attachments = cluster_network_attachments
        self.confidential_compute_mode = confidential_compute_mode
        self.default_trusted_profile = default_trusted_profile
        self.enable_secure_boot = enable_secure_boot
        self.keys = keys
        self.metadata_service = metadata_service
        self.name = name
        self.placement_target = placement_target
        self.profile = profile
        self.reservation_affinity = reservation_affinity
        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.zone = zone
        self.network_interfaces = network_interfaces
        self.primary_network_interface = primary_network_interface

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceTemplatePrototypeInstanceTemplateBySourceSnapshotInstanceTemplateBySourceSnapshotInstanceByNetworkInterface':
        """Initialize a InstanceTemplatePrototypeInstanceTemplateBySourceSnapshotInstanceTemplateBySourceSnapshotInstanceByNetworkInterface object from a json dictionary."""
        args = {}
        if (availability_policy := _dict.get('availability_policy')) is not None:
            args['availability_policy'] = InstanceAvailabilityPolicyPrototype.from_dict(availability_policy)
        if (cluster_network_attachments := _dict.get('cluster_network_attachments')) is not None:
            args['cluster_network_attachments'] = [InstanceClusterNetworkAttachmentPrototypeInstanceContext.from_dict(v) for v in cluster_network_attachments]
        if (confidential_compute_mode := _dict.get('confidential_compute_mode')) is not None:
            args['confidential_compute_mode'] = confidential_compute_mode
        if (default_trusted_profile := _dict.get('default_trusted_profile')) is not None:
            args['default_trusted_profile'] = InstanceDefaultTrustedProfilePrototype.from_dict(default_trusted_profile)
        if (enable_secure_boot := _dict.get('enable_secure_boot')) is not None:
            args['enable_secure_boot'] = enable_secure_boot
        if (keys := _dict.get('keys')) is not None:
            args['keys'] = keys
        if (metadata_service := _dict.get('metadata_service')) is not None:
            args['metadata_service'] = InstanceMetadataServicePrototype.from_dict(metadata_service)
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        if (placement_target := _dict.get('placement_target')) is not None:
            args['placement_target'] = placement_target
        if (profile := _dict.get('profile')) is not None:
            args['profile'] = profile
        if (reservation_affinity := _dict.get('reservation_affinity')) is not None:
            args['reservation_affinity'] = InstanceReservationAffinityPrototype.from_dict(reservation_affinity)
        if (resource_group := _dict.get('resource_group')) is not None:
            args['resource_group'] = resource_group
        if (total_volume_bandwidth := _dict.get('total_volume_bandwidth')) is not None:
            args['total_volume_bandwidth'] = total_volume_bandwidth
        if (user_data := _dict.get('user_data')) is not None:
            args['user_data'] = user_data
        if (volume_attachments := _dict.get('volume_attachments')) is not None:
            args['volume_attachments'] = [VolumeAttachmentPrototype.from_dict(v) for v in volume_attachments]
        if (vpc := _dict.get('vpc')) is not None:
            args['vpc'] = vpc
        if (boot_volume_attachment := _dict.get('boot_volume_attachment')) is not None:
            args['boot_volume_attachment'] = VolumeAttachmentPrototypeInstanceBySourceSnapshotContext.from_dict(boot_volume_attachment)
        else:
            raise ValueError('Required property \'boot_volume_attachment\' not present in InstanceTemplatePrototypeInstanceTemplateBySourceSnapshotInstanceTemplateBySourceSnapshotInstanceByNetworkInterface JSON')
        if (zone := _dict.get('zone')) is not None:
            args['zone'] = zone
        else:
            raise ValueError('Required property \'zone\' not present in InstanceTemplatePrototypeInstanceTemplateBySourceSnapshotInstanceTemplateBySourceSnapshotInstanceByNetworkInterface JSON')
        if (network_interfaces := _dict.get('network_interfaces')) is not None:
            args['network_interfaces'] = [NetworkInterfacePrototype.from_dict(v) for v in network_interfaces]
        if (primary_network_interface := _dict.get('primary_network_interface')) is not None:
            args['primary_network_interface'] = NetworkInterfacePrototype.from_dict(primary_network_interface)
        else:
            raise ValueError('Required property \'primary_network_interface\' not present in InstanceTemplatePrototypeInstanceTemplateBySourceSnapshotInstanceTemplateBySourceSnapshotInstanceByNetworkInterface JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceTemplatePrototypeInstanceTemplateBySourceSnapshotInstanceTemplateBySourceSnapshotInstanceByNetworkInterface object from 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, 'cluster_network_attachments') and self.cluster_network_attachments is not None:
            cluster_network_attachments_list = []
            for v in self.cluster_network_attachments:
                if isinstance(v, dict):
                    cluster_network_attachments_list.append(v)
                else:
                    cluster_network_attachments_list.append(v.to_dict())
            _dict['cluster_network_attachments'] = cluster_network_attachments_list
        if hasattr(self, 'confidential_compute_mode') and self.confidential_compute_mode is not None:
            _dict['confidential_compute_mode'] = self.confidential_compute_mode
        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, 'enable_secure_boot') and self.enable_secure_boot is not None:
            _dict['enable_secure_boot'] = self.enable_secure_boot
        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, 'reservation_affinity') and self.reservation_affinity is not None:
            if isinstance(self.reservation_affinity, dict):
                _dict['reservation_affinity'] = self.reservation_affinity
            else:
                _dict['reservation_affinity'] = self.reservation_affinity.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, '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, '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()
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceTemplatePrototypeInstanceTemplateBySourceSnapshotInstanceTemplateBySourceSnapshotInstanceByNetworkInterface object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceTemplatePrototypeInstanceTemplateBySourceSnapshotInstanceTemplateBySourceSnapshotInstanceByNetworkInterface') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceTemplatePrototypeInstanceTemplateBySourceSnapshotInstanceTemplateBySourceSnapshotInstanceByNetworkInterface') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ConfidentialComputeModeEnum(str, Enum):
        """
        The confidential compute mode to use for this virtual server instance.
        If unspecified, the default confidential compute mode from the profile will be
        used.
        """

        DISABLED = 'disabled'
        SGX = 'sgx'



class InstanceTemplateInstanceByCatalogOfferingInstanceTemplateContextInstanceByCatalogOfferingInstanceTemplateContextInstanceByNetworkAttachment(InstanceTemplateInstanceByCatalogOfferingInstanceTemplateContext):
    """
    InstanceTemplateInstanceByCatalogOfferingInstanceTemplateContextInstanceByCatalogOfferingInstanceTemplateContextInstanceByNetworkAttachment.

    :param InstanceAvailabilityPolicyPrototype availability_policy: (optional) The
          availability policy to use for this virtual server instance.
    :param List[InstanceClusterNetworkAttachmentPrototypeInstanceContext]
          cluster_network_attachments: (optional) The cluster network attachments to
          create for this virtual server instance. A cluster network attachment represents
          a device that is connected to a cluster network. The number of network
          attachments must match one of the values from the instance profile's
          `cluster_network_attachment_count` before the instance can be started.
    :param str confidential_compute_mode: (optional) The confidential compute mode
          to use for this virtual server instance.
          If unspecified, the default confidential compute mode from the profile will be
          used.
    :param datetime created_at: The date and time that the instance template was
          created.
    :param str crn: The CRN for this instance template.
    :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 bool enable_secure_boot: (optional) Indicates whether secure boot is
          enabled for this virtual server instance.
          If unspecified, the default secure boot mode from the profile will be used.
    :param str href: The URL for this instance template.
    :param str id: The unique identifier for this instance template.
    :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: The name for this instance template. The name is unique across
          all instance templates in the region.
    :param InstancePlacementTargetPrototype placement_target: (optional) The
          placement restrictions to use for the virtual server instance.
          If specified, `reservation_affinity.policy` must be `disabled`.
    :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 InstanceReservationAffinityPrototype reservation_affinity: (optional)
    :param ResourceGroupReference resource_group: The resource group for this
          instance template.
    :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
          attachments or instance network interfaces.
    :param VolumeAttachmentPrototypeInstanceByImageContext boot_volume_attachment:
          (optional) The boot volume attachment to create for the virtual server instance.
    :param InstanceCatalogOfferingPrototype catalog_offering:
    :param ZoneIdentity zone: The zone this virtual server instance will reside in.
    :param List[InstanceNetworkAttachmentPrototype] network_attachments: (optional)
          The additional network attachments to create for the virtual server instance.
    :param InstanceNetworkAttachmentPrototype primary_network_attachment: The
          primary network attachment to create for the virtual server instance.
    """

    def __init__(
        self,
        created_at: datetime,
        crn: str,
        href: str,
        id: str,
        name: str,
        resource_group: 'ResourceGroupReference',
        catalog_offering: 'InstanceCatalogOfferingPrototype',
        zone: 'ZoneIdentity',
        primary_network_attachment: 'InstanceNetworkAttachmentPrototype',
        *,
        availability_policy: Optional['InstanceAvailabilityPolicyPrototype'] = None,
        cluster_network_attachments: Optional[List['InstanceClusterNetworkAttachmentPrototypeInstanceContext']] = None,
        confidential_compute_mode: Optional[str] = None,
        default_trusted_profile: Optional['InstanceDefaultTrustedProfilePrototype'] = None,
        enable_secure_boot: Optional[bool] = None,
        keys: Optional[List['KeyIdentity']] = None,
        metadata_service: Optional['InstanceMetadataServicePrototype'] = None,
        placement_target: Optional['InstancePlacementTargetPrototype'] = None,
        profile: Optional['InstanceProfileIdentity'] = None,
        reservation_affinity: Optional['InstanceReservationAffinityPrototype'] = None,
        total_volume_bandwidth: Optional[int] = None,
        user_data: Optional[str] = None,
        volume_attachments: Optional[List['VolumeAttachmentPrototype']] = None,
        vpc: Optional['VPCIdentity'] = None,
        boot_volume_attachment: Optional['VolumeAttachmentPrototypeInstanceByImageContext'] = None,
        network_attachments: Optional[List['InstanceNetworkAttachmentPrototype']] = None,
    ) -> None:
        """
        Initialize a InstanceTemplateInstanceByCatalogOfferingInstanceTemplateContextInstanceByCatalogOfferingInstanceTemplateContextInstanceByNetworkAttachment 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:
        :param ZoneIdentity zone: The zone this virtual server instance will reside
               in.
        :param InstanceNetworkAttachmentPrototype primary_network_attachment: The
               primary network attachment to create for the virtual server instance.
        :param InstanceAvailabilityPolicyPrototype availability_policy: (optional)
               The availability policy to use for this virtual server instance.
        :param List[InstanceClusterNetworkAttachmentPrototypeInstanceContext]
               cluster_network_attachments: (optional) The cluster network attachments to
               create for this virtual server instance. A cluster network attachment
               represents a device that is connected to a cluster network. The number of
               network attachments must match one of the values from the instance
               profile's `cluster_network_attachment_count` before the instance can be
               started.
        :param str confidential_compute_mode: (optional) The confidential compute
               mode to use for this virtual server instance.
               If unspecified, the default confidential compute mode from the profile will
               be used.
        :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 bool enable_secure_boot: (optional) Indicates whether secure boot is
               enabled for this virtual server instance.
               If unspecified, the default secure boot mode from the profile will be used.
        :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.
               If specified, `reservation_affinity.policy` must be `disabled`.
        :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 InstanceReservationAffinityPrototype reservation_affinity:
               (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
               attachments or instance network interfaces.
        :param VolumeAttachmentPrototypeInstanceByImageContext
               boot_volume_attachment: (optional) The boot volume attachment to create for
               the virtual server instance.
        :param List[InstanceNetworkAttachmentPrototype] network_attachments:
               (optional) The additional network attachments to create for the virtual
               server instance.
        """
        # pylint: disable=super-init-not-called
        self.availability_policy = availability_policy
        self.cluster_network_attachments = cluster_network_attachments
        self.confidential_compute_mode = confidential_compute_mode
        self.created_at = created_at
        self.crn = crn
        self.default_trusted_profile = default_trusted_profile
        self.enable_secure_boot = enable_secure_boot
        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.reservation_affinity = reservation_affinity
        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.zone = zone
        self.network_attachments = network_attachments
        self.primary_network_attachment = primary_network_attachment

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceTemplateInstanceByCatalogOfferingInstanceTemplateContextInstanceByCatalogOfferingInstanceTemplateContextInstanceByNetworkAttachment':
        """Initialize a InstanceTemplateInstanceByCatalogOfferingInstanceTemplateContextInstanceByCatalogOfferingInstanceTemplateContextInstanceByNetworkAttachment object from a json dictionary."""
        args = {}
        if (availability_policy := _dict.get('availability_policy')) is not None:
            args['availability_policy'] = InstanceAvailabilityPolicyPrototype.from_dict(availability_policy)
        if (cluster_network_attachments := _dict.get('cluster_network_attachments')) is not None:
            args['cluster_network_attachments'] = [InstanceClusterNetworkAttachmentPrototypeInstanceContext.from_dict(v) for v in cluster_network_attachments]
        if (confidential_compute_mode := _dict.get('confidential_compute_mode')) is not None:
            args['confidential_compute_mode'] = confidential_compute_mode
        if (created_at := _dict.get('created_at')) is not None:
            args['created_at'] = string_to_datetime(created_at)
        else:
            raise ValueError('Required property \'created_at\' not present in InstanceTemplateInstanceByCatalogOfferingInstanceTemplateContextInstanceByCatalogOfferingInstanceTemplateContextInstanceByNetworkAttachment JSON')
        if (crn := _dict.get('crn')) is not None:
            args['crn'] = crn
        else:
            raise ValueError('Required property \'crn\' not present in InstanceTemplateInstanceByCatalogOfferingInstanceTemplateContextInstanceByCatalogOfferingInstanceTemplateContextInstanceByNetworkAttachment JSON')
        if (default_trusted_profile := _dict.get('default_trusted_profile')) is not None:
            args['default_trusted_profile'] = InstanceDefaultTrustedProfilePrototype.from_dict(default_trusted_profile)
        if (enable_secure_boot := _dict.get('enable_secure_boot')) is not None:
            args['enable_secure_boot'] = enable_secure_boot
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in InstanceTemplateInstanceByCatalogOfferingInstanceTemplateContextInstanceByCatalogOfferingInstanceTemplateContextInstanceByNetworkAttachment JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in InstanceTemplateInstanceByCatalogOfferingInstanceTemplateContextInstanceByCatalogOfferingInstanceTemplateContextInstanceByNetworkAttachment JSON')
        if (keys := _dict.get('keys')) is not None:
            args['keys'] = keys
        if (metadata_service := _dict.get('metadata_service')) is not None:
            args['metadata_service'] = InstanceMetadataServicePrototype.from_dict(metadata_service)
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in InstanceTemplateInstanceByCatalogOfferingInstanceTemplateContextInstanceByCatalogOfferingInstanceTemplateContextInstanceByNetworkAttachment JSON')
        if (placement_target := _dict.get('placement_target')) is not None:
            args['placement_target'] = placement_target
        if (profile := _dict.get('profile')) is not None:
            args['profile'] = profile
        if (reservation_affinity := _dict.get('reservation_affinity')) is not None:
            args['reservation_affinity'] = InstanceReservationAffinityPrototype.from_dict(reservation_affinity)
        if (resource_group := _dict.get('resource_group')) is not None:
            args['resource_group'] = ResourceGroupReference.from_dict(resource_group)
        else:
            raise ValueError('Required property \'resource_group\' not present in InstanceTemplateInstanceByCatalogOfferingInstanceTemplateContextInstanceByCatalogOfferingInstanceTemplateContextInstanceByNetworkAttachment JSON')
        if (total_volume_bandwidth := _dict.get('total_volume_bandwidth')) is not None:
            args['total_volume_bandwidth'] = total_volume_bandwidth
        if (user_data := _dict.get('user_data')) is not None:
            args['user_data'] = user_data
        if (volume_attachments := _dict.get('volume_attachments')) is not None:
            args['volume_attachments'] = [VolumeAttachmentPrototype.from_dict(v) for v in volume_attachments]
        if (vpc := _dict.get('vpc')) is not None:
            args['vpc'] = vpc
        if (boot_volume_attachment := _dict.get('boot_volume_attachment')) is not None:
            args['boot_volume_attachment'] = VolumeAttachmentPrototypeInstanceByImageContext.from_dict(boot_volume_attachment)
        if (catalog_offering := _dict.get('catalog_offering')) is not None:
            args['catalog_offering'] = catalog_offering
        else:
            raise ValueError('Required property \'catalog_offering\' not present in InstanceTemplateInstanceByCatalogOfferingInstanceTemplateContextInstanceByCatalogOfferingInstanceTemplateContextInstanceByNetworkAttachment JSON')
        if (zone := _dict.get('zone')) is not None:
            args['zone'] = zone
        else:
            raise ValueError('Required property \'zone\' not present in InstanceTemplateInstanceByCatalogOfferingInstanceTemplateContextInstanceByCatalogOfferingInstanceTemplateContextInstanceByNetworkAttachment JSON')
        if (network_attachments := _dict.get('network_attachments')) is not None:
            args['network_attachments'] = [InstanceNetworkAttachmentPrototype.from_dict(v) for v in network_attachments]
        if (primary_network_attachment := _dict.get('primary_network_attachment')) is not None:
            args['primary_network_attachment'] = InstanceNetworkAttachmentPrototype.from_dict(primary_network_attachment)
        else:
            raise ValueError('Required property \'primary_network_attachment\' not present in InstanceTemplateInstanceByCatalogOfferingInstanceTemplateContextInstanceByCatalogOfferingInstanceTemplateContextInstanceByNetworkAttachment JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceTemplateInstanceByCatalogOfferingInstanceTemplateContextInstanceByCatalogOfferingInstanceTemplateContextInstanceByNetworkAttachment object from 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, 'cluster_network_attachments') and self.cluster_network_attachments is not None:
            cluster_network_attachments_list = []
            for v in self.cluster_network_attachments:
                if isinstance(v, dict):
                    cluster_network_attachments_list.append(v)
                else:
                    cluster_network_attachments_list.append(v.to_dict())
            _dict['cluster_network_attachments'] = cluster_network_attachments_list
        if hasattr(self, 'confidential_compute_mode') and self.confidential_compute_mode is not None:
            _dict['confidential_compute_mode'] = self.confidential_compute_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, '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, '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, '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, 'reservation_affinity') and self.reservation_affinity is not None:
            if isinstance(self.reservation_affinity, dict):
                _dict['reservation_affinity'] = self.reservation_affinity
            else:
                _dict['reservation_affinity'] = self.reservation_affinity.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, '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, 'network_attachments') and self.network_attachments is not None:
            network_attachments_list = []
            for v in self.network_attachments:
                if isinstance(v, dict):
                    network_attachments_list.append(v)
                else:
                    network_attachments_list.append(v.to_dict())
            _dict['network_attachments'] = network_attachments_list
        if hasattr(self, 'primary_network_attachment') and self.primary_network_attachment is not None:
            if isinstance(self.primary_network_attachment, dict):
                _dict['primary_network_attachment'] = self.primary_network_attachment
            else:
                _dict['primary_network_attachment'] = self.primary_network_attachment.to_dict()
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceTemplateInstanceByCatalogOfferingInstanceTemplateContextInstanceByCatalogOfferingInstanceTemplateContextInstanceByNetworkAttachment object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceTemplateInstanceByCatalogOfferingInstanceTemplateContextInstanceByCatalogOfferingInstanceTemplateContextInstanceByNetworkAttachment') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceTemplateInstanceByCatalogOfferingInstanceTemplateContextInstanceByCatalogOfferingInstanceTemplateContextInstanceByNetworkAttachment') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ConfidentialComputeModeEnum(str, Enum):
        """
        The confidential compute mode to use for this virtual server instance.
        If unspecified, the default confidential compute mode from the profile will be
        used.
        """

        DISABLED = 'disabled'
        SGX = 'sgx'



class InstanceTemplateInstanceByCatalogOfferingInstanceTemplateContextInstanceByCatalogOfferingInstanceTemplateContextInstanceByNetworkInterface(InstanceTemplateInstanceByCatalogOfferingInstanceTemplateContext):
    """
    InstanceTemplateInstanceByCatalogOfferingInstanceTemplateContextInstanceByCatalogOfferingInstanceTemplateContextInstanceByNetworkInterface.

    :param InstanceAvailabilityPolicyPrototype availability_policy: (optional) The
          availability policy to use for this virtual server instance.
    :param List[InstanceClusterNetworkAttachmentPrototypeInstanceContext]
          cluster_network_attachments: (optional) The cluster network attachments to
          create for this virtual server instance. A cluster network attachment represents
          a device that is connected to a cluster network. The number of network
          attachments must match one of the values from the instance profile's
          `cluster_network_attachment_count` before the instance can be started.
    :param str confidential_compute_mode: (optional) The confidential compute mode
          to use for this virtual server instance.
          If unspecified, the default confidential compute mode from the profile will be
          used.
    :param datetime created_at: The date and time that the instance template was
          created.
    :param str crn: The CRN for this instance template.
    :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 bool enable_secure_boot: (optional) Indicates whether secure boot is
          enabled for this virtual server instance.
          If unspecified, the default secure boot mode from the profile will be used.
    :param str href: The URL for this instance template.
    :param str id: The unique identifier for this instance template.
    :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: The name for this instance template. The name is unique across
          all instance templates in the region.
    :param InstancePlacementTargetPrototype placement_target: (optional) The
          placement restrictions to use for the virtual server instance.
          If specified, `reservation_affinity.policy` must be `disabled`.
    :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 InstanceReservationAffinityPrototype reservation_affinity: (optional)
    :param ResourceGroupReference resource_group: The resource group for this
          instance template.
    :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
          attachments or instance network interfaces.
    :param VolumeAttachmentPrototypeInstanceByImageContext boot_volume_attachment:
          (optional) The boot volume attachment to create for the virtual server instance.
    :param InstanceCatalogOfferingPrototype catalog_offering:
    :param ZoneIdentity zone: The zone this virtual server instance will reside in.
    :param List[NetworkInterfacePrototype] network_interfaces: (optional) The
          additional instance network interfaces to create.
    :param NetworkInterfacePrototype primary_network_interface: The primary instance
          network interface to create.
    """

    def __init__(
        self,
        created_at: datetime,
        crn: str,
        href: str,
        id: str,
        name: str,
        resource_group: 'ResourceGroupReference',
        catalog_offering: 'InstanceCatalogOfferingPrototype',
        zone: 'ZoneIdentity',
        primary_network_interface: 'NetworkInterfacePrototype',
        *,
        availability_policy: Optional['InstanceAvailabilityPolicyPrototype'] = None,
        cluster_network_attachments: Optional[List['InstanceClusterNetworkAttachmentPrototypeInstanceContext']] = None,
        confidential_compute_mode: Optional[str] = None,
        default_trusted_profile: Optional['InstanceDefaultTrustedProfilePrototype'] = None,
        enable_secure_boot: Optional[bool] = None,
        keys: Optional[List['KeyIdentity']] = None,
        metadata_service: Optional['InstanceMetadataServicePrototype'] = None,
        placement_target: Optional['InstancePlacementTargetPrototype'] = None,
        profile: Optional['InstanceProfileIdentity'] = None,
        reservation_affinity: Optional['InstanceReservationAffinityPrototype'] = None,
        total_volume_bandwidth: Optional[int] = None,
        user_data: Optional[str] = None,
        volume_attachments: Optional[List['VolumeAttachmentPrototype']] = None,
        vpc: Optional['VPCIdentity'] = None,
        boot_volume_attachment: Optional['VolumeAttachmentPrototypeInstanceByImageContext'] = None,
        network_interfaces: Optional[List['NetworkInterfacePrototype']] = None,
    ) -> None:
        """
        Initialize a InstanceTemplateInstanceByCatalogOfferingInstanceTemplateContextInstanceByCatalogOfferingInstanceTemplateContextInstanceByNetworkInterface 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:
        :param ZoneIdentity zone: The zone this virtual server instance will reside
               in.
        :param NetworkInterfacePrototype primary_network_interface: The primary
               instance network interface to create.
        :param InstanceAvailabilityPolicyPrototype availability_policy: (optional)
               The availability policy to use for this virtual server instance.
        :param List[InstanceClusterNetworkAttachmentPrototypeInstanceContext]
               cluster_network_attachments: (optional) The cluster network attachments to
               create for this virtual server instance. A cluster network attachment
               represents a device that is connected to a cluster network. The number of
               network attachments must match one of the values from the instance
               profile's `cluster_network_attachment_count` before the instance can be
               started.
        :param str confidential_compute_mode: (optional) The confidential compute
               mode to use for this virtual server instance.
               If unspecified, the default confidential compute mode from the profile will
               be used.
        :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 bool enable_secure_boot: (optional) Indicates whether secure boot is
               enabled for this virtual server instance.
               If unspecified, the default secure boot mode from the profile will be used.
        :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.
               If specified, `reservation_affinity.policy` must be `disabled`.
        :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 InstanceReservationAffinityPrototype reservation_affinity:
               (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
               attachments or 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.cluster_network_attachments = cluster_network_attachments
        self.confidential_compute_mode = confidential_compute_mode
        self.created_at = created_at
        self.crn = crn
        self.default_trusted_profile = default_trusted_profile
        self.enable_secure_boot = enable_secure_boot
        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.reservation_affinity = reservation_affinity
        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.zone = zone
        self.network_interfaces = network_interfaces
        self.primary_network_interface = primary_network_interface

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceTemplateInstanceByCatalogOfferingInstanceTemplateContextInstanceByCatalogOfferingInstanceTemplateContextInstanceByNetworkInterface':
        """Initialize a InstanceTemplateInstanceByCatalogOfferingInstanceTemplateContextInstanceByCatalogOfferingInstanceTemplateContextInstanceByNetworkInterface object from a json dictionary."""
        args = {}
        if (availability_policy := _dict.get('availability_policy')) is not None:
            args['availability_policy'] = InstanceAvailabilityPolicyPrototype.from_dict(availability_policy)
        if (cluster_network_attachments := _dict.get('cluster_network_attachments')) is not None:
            args['cluster_network_attachments'] = [InstanceClusterNetworkAttachmentPrototypeInstanceContext.from_dict(v) for v in cluster_network_attachments]
        if (confidential_compute_mode := _dict.get('confidential_compute_mode')) is not None:
            args['confidential_compute_mode'] = confidential_compute_mode
        if (created_at := _dict.get('created_at')) is not None:
            args['created_at'] = string_to_datetime(created_at)
        else:
            raise ValueError('Required property \'created_at\' not present in InstanceTemplateInstanceByCatalogOfferingInstanceTemplateContextInstanceByCatalogOfferingInstanceTemplateContextInstanceByNetworkInterface JSON')
        if (crn := _dict.get('crn')) is not None:
            args['crn'] = crn
        else:
            raise ValueError('Required property \'crn\' not present in InstanceTemplateInstanceByCatalogOfferingInstanceTemplateContextInstanceByCatalogOfferingInstanceTemplateContextInstanceByNetworkInterface JSON')
        if (default_trusted_profile := _dict.get('default_trusted_profile')) is not None:
            args['default_trusted_profile'] = InstanceDefaultTrustedProfilePrototype.from_dict(default_trusted_profile)
        if (enable_secure_boot := _dict.get('enable_secure_boot')) is not None:
            args['enable_secure_boot'] = enable_secure_boot
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in InstanceTemplateInstanceByCatalogOfferingInstanceTemplateContextInstanceByCatalogOfferingInstanceTemplateContextInstanceByNetworkInterface JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in InstanceTemplateInstanceByCatalogOfferingInstanceTemplateContextInstanceByCatalogOfferingInstanceTemplateContextInstanceByNetworkInterface JSON')
        if (keys := _dict.get('keys')) is not None:
            args['keys'] = keys
        if (metadata_service := _dict.get('metadata_service')) is not None:
            args['metadata_service'] = InstanceMetadataServicePrototype.from_dict(metadata_service)
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in InstanceTemplateInstanceByCatalogOfferingInstanceTemplateContextInstanceByCatalogOfferingInstanceTemplateContextInstanceByNetworkInterface JSON')
        if (placement_target := _dict.get('placement_target')) is not None:
            args['placement_target'] = placement_target
        if (profile := _dict.get('profile')) is not None:
            args['profile'] = profile
        if (reservation_affinity := _dict.get('reservation_affinity')) is not None:
            args['reservation_affinity'] = InstanceReservationAffinityPrototype.from_dict(reservation_affinity)
        if (resource_group := _dict.get('resource_group')) is not None:
            args['resource_group'] = ResourceGroupReference.from_dict(resource_group)
        else:
            raise ValueError('Required property \'resource_group\' not present in InstanceTemplateInstanceByCatalogOfferingInstanceTemplateContextInstanceByCatalogOfferingInstanceTemplateContextInstanceByNetworkInterface JSON')
        if (total_volume_bandwidth := _dict.get('total_volume_bandwidth')) is not None:
            args['total_volume_bandwidth'] = total_volume_bandwidth
        if (user_data := _dict.get('user_data')) is not None:
            args['user_data'] = user_data
        if (volume_attachments := _dict.get('volume_attachments')) is not None:
            args['volume_attachments'] = [VolumeAttachmentPrototype.from_dict(v) for v in volume_attachments]
        if (vpc := _dict.get('vpc')) is not None:
            args['vpc'] = vpc
        if (boot_volume_attachment := _dict.get('boot_volume_attachment')) is not None:
            args['boot_volume_attachment'] = VolumeAttachmentPrototypeInstanceByImageContext.from_dict(boot_volume_attachment)
        if (catalog_offering := _dict.get('catalog_offering')) is not None:
            args['catalog_offering'] = catalog_offering
        else:
            raise ValueError('Required property \'catalog_offering\' not present in InstanceTemplateInstanceByCatalogOfferingInstanceTemplateContextInstanceByCatalogOfferingInstanceTemplateContextInstanceByNetworkInterface JSON')
        if (zone := _dict.get('zone')) is not None:
            args['zone'] = zone
        else:
            raise ValueError('Required property \'zone\' not present in InstanceTemplateInstanceByCatalogOfferingInstanceTemplateContextInstanceByCatalogOfferingInstanceTemplateContextInstanceByNetworkInterface JSON')
        if (network_interfaces := _dict.get('network_interfaces')) is not None:
            args['network_interfaces'] = [NetworkInterfacePrototype.from_dict(v) for v in network_interfaces]
        if (primary_network_interface := _dict.get('primary_network_interface')) is not None:
            args['primary_network_interface'] = NetworkInterfacePrototype.from_dict(primary_network_interface)
        else:
            raise ValueError('Required property \'primary_network_interface\' not present in InstanceTemplateInstanceByCatalogOfferingInstanceTemplateContextInstanceByCatalogOfferingInstanceTemplateContextInstanceByNetworkInterface JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceTemplateInstanceByCatalogOfferingInstanceTemplateContextInstanceByCatalogOfferingInstanceTemplateContextInstanceByNetworkInterface object from 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, 'cluster_network_attachments') and self.cluster_network_attachments is not None:
            cluster_network_attachments_list = []
            for v in self.cluster_network_attachments:
                if isinstance(v, dict):
                    cluster_network_attachments_list.append(v)
                else:
                    cluster_network_attachments_list.append(v.to_dict())
            _dict['cluster_network_attachments'] = cluster_network_attachments_list
        if hasattr(self, 'confidential_compute_mode') and self.confidential_compute_mode is not None:
            _dict['confidential_compute_mode'] = self.confidential_compute_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, '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, '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, '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, 'reservation_affinity') and self.reservation_affinity is not None:
            if isinstance(self.reservation_affinity, dict):
                _dict['reservation_affinity'] = self.reservation_affinity
            else:
                _dict['reservation_affinity'] = self.reservation_affinity.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, '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, '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()
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceTemplateInstanceByCatalogOfferingInstanceTemplateContextInstanceByCatalogOfferingInstanceTemplateContextInstanceByNetworkInterface object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceTemplateInstanceByCatalogOfferingInstanceTemplateContextInstanceByCatalogOfferingInstanceTemplateContextInstanceByNetworkInterface') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceTemplateInstanceByCatalogOfferingInstanceTemplateContextInstanceByCatalogOfferingInstanceTemplateContextInstanceByNetworkInterface') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ConfidentialComputeModeEnum(str, Enum):
        """
        The confidential compute mode to use for this virtual server instance.
        If unspecified, the default confidential compute mode from the profile will be
        used.
        """

        DISABLED = 'disabled'
        SGX = 'sgx'



class InstanceTemplateInstanceByImageInstanceTemplateContextInstanceByImageInstanceTemplateContextInstanceByNetworkAttachment(InstanceTemplateInstanceByImageInstanceTemplateContext):
    """
    InstanceTemplateInstanceByImageInstanceTemplateContextInstanceByImageInstanceTemplateContextInstanceByNetworkAttachment.

    :param InstanceAvailabilityPolicyPrototype availability_policy: (optional) The
          availability policy to use for this virtual server instance.
    :param List[InstanceClusterNetworkAttachmentPrototypeInstanceContext]
          cluster_network_attachments: (optional) The cluster network attachments to
          create for this virtual server instance. A cluster network attachment represents
          a device that is connected to a cluster network. The number of network
          attachments must match one of the values from the instance profile's
          `cluster_network_attachment_count` before the instance can be started.
    :param str confidential_compute_mode: (optional) The confidential compute mode
          to use for this virtual server instance.
          If unspecified, the default confidential compute mode from the profile will be
          used.
    :param datetime created_at: The date and time that the instance template was
          created.
    :param str crn: The CRN for this instance template.
    :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 bool enable_secure_boot: (optional) Indicates whether secure boot is
          enabled for this virtual server instance.
          If unspecified, the default secure boot mode from the profile will be used.
    :param str href: The URL for this instance template.
    :param str id: The unique identifier for this instance template.
    :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: The name for this instance template. The name is unique across
          all instance templates in the region.
    :param InstancePlacementTargetPrototype placement_target: (optional) The
          placement restrictions to use for the virtual server instance.
          If specified, `reservation_affinity.policy` must be `disabled`.
    :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 InstanceReservationAffinityPrototype reservation_affinity: (optional)
    :param ResourceGroupReference resource_group: The resource group for this
          instance template.
    :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
          attachments or instance network interfaces.
    :param VolumeAttachmentPrototypeInstanceByImageContext boot_volume_attachment:
          (optional) The boot volume attachment to create for the virtual server instance.
    :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 List[InstanceNetworkAttachmentPrototype] network_attachments: (optional)
          The additional network attachments to create for the virtual server instance.
    :param InstanceNetworkAttachmentPrototype primary_network_attachment: The
          primary network attachment to create for the virtual server instance.
    """

    def __init__(
        self,
        created_at: datetime,
        crn: str,
        href: str,
        id: str,
        name: str,
        resource_group: 'ResourceGroupReference',
        image: 'ImageIdentity',
        zone: 'ZoneIdentity',
        primary_network_attachment: 'InstanceNetworkAttachmentPrototype',
        *,
        availability_policy: Optional['InstanceAvailabilityPolicyPrototype'] = None,
        cluster_network_attachments: Optional[List['InstanceClusterNetworkAttachmentPrototypeInstanceContext']] = None,
        confidential_compute_mode: Optional[str] = None,
        default_trusted_profile: Optional['InstanceDefaultTrustedProfilePrototype'] = None,
        enable_secure_boot: Optional[bool] = None,
        keys: Optional[List['KeyIdentity']] = None,
        metadata_service: Optional['InstanceMetadataServicePrototype'] = None,
        placement_target: Optional['InstancePlacementTargetPrototype'] = None,
        profile: Optional['InstanceProfileIdentity'] = None,
        reservation_affinity: Optional['InstanceReservationAffinityPrototype'] = None,
        total_volume_bandwidth: Optional[int] = None,
        user_data: Optional[str] = None,
        volume_attachments: Optional[List['VolumeAttachmentPrototype']] = None,
        vpc: Optional['VPCIdentity'] = None,
        boot_volume_attachment: Optional['VolumeAttachmentPrototypeInstanceByImageContext'] = None,
        network_attachments: Optional[List['InstanceNetworkAttachmentPrototype']] = None,
    ) -> None:
        """
        Initialize a InstanceTemplateInstanceByImageInstanceTemplateContextInstanceByImageInstanceTemplateContextInstanceByNetworkAttachment 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 InstanceNetworkAttachmentPrototype primary_network_attachment: The
               primary network attachment to create for the virtual server instance.
        :param InstanceAvailabilityPolicyPrototype availability_policy: (optional)
               The availability policy to use for this virtual server instance.
        :param List[InstanceClusterNetworkAttachmentPrototypeInstanceContext]
               cluster_network_attachments: (optional) The cluster network attachments to
               create for this virtual server instance. A cluster network attachment
               represents a device that is connected to a cluster network. The number of
               network attachments must match one of the values from the instance
               profile's `cluster_network_attachment_count` before the instance can be
               started.
        :param str confidential_compute_mode: (optional) The confidential compute
               mode to use for this virtual server instance.
               If unspecified, the default confidential compute mode from the profile will
               be used.
        :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 bool enable_secure_boot: (optional) Indicates whether secure boot is
               enabled for this virtual server instance.
               If unspecified, the default secure boot mode from the profile will be used.
        :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.
               If specified, `reservation_affinity.policy` must be `disabled`.
        :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 InstanceReservationAffinityPrototype reservation_affinity:
               (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
               attachments or instance network interfaces.
        :param VolumeAttachmentPrototypeInstanceByImageContext
               boot_volume_attachment: (optional) The boot volume attachment to create for
               the virtual server instance.
        :param List[InstanceNetworkAttachmentPrototype] network_attachments:
               (optional) The additional network attachments to create for the virtual
               server instance.
        """
        # pylint: disable=super-init-not-called
        self.availability_policy = availability_policy
        self.cluster_network_attachments = cluster_network_attachments
        self.confidential_compute_mode = confidential_compute_mode
        self.created_at = created_at
        self.crn = crn
        self.default_trusted_profile = default_trusted_profile
        self.enable_secure_boot = enable_secure_boot
        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.reservation_affinity = reservation_affinity
        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.zone = zone
        self.network_attachments = network_attachments
        self.primary_network_attachment = primary_network_attachment

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceTemplateInstanceByImageInstanceTemplateContextInstanceByImageInstanceTemplateContextInstanceByNetworkAttachment':
        """Initialize a InstanceTemplateInstanceByImageInstanceTemplateContextInstanceByImageInstanceTemplateContextInstanceByNetworkAttachment object from a json dictionary."""
        args = {}
        if (availability_policy := _dict.get('availability_policy')) is not None:
            args['availability_policy'] = InstanceAvailabilityPolicyPrototype.from_dict(availability_policy)
        if (cluster_network_attachments := _dict.get('cluster_network_attachments')) is not None:
            args['cluster_network_attachments'] = [InstanceClusterNetworkAttachmentPrototypeInstanceContext.from_dict(v) for v in cluster_network_attachments]
        if (confidential_compute_mode := _dict.get('confidential_compute_mode')) is not None:
            args['confidential_compute_mode'] = confidential_compute_mode
        if (created_at := _dict.get('created_at')) is not None:
            args['created_at'] = string_to_datetime(created_at)
        else:
            raise ValueError('Required property \'created_at\' not present in InstanceTemplateInstanceByImageInstanceTemplateContextInstanceByImageInstanceTemplateContextInstanceByNetworkAttachment JSON')
        if (crn := _dict.get('crn')) is not None:
            args['crn'] = crn
        else:
            raise ValueError('Required property \'crn\' not present in InstanceTemplateInstanceByImageInstanceTemplateContextInstanceByImageInstanceTemplateContextInstanceByNetworkAttachment JSON')
        if (default_trusted_profile := _dict.get('default_trusted_profile')) is not None:
            args['default_trusted_profile'] = InstanceDefaultTrustedProfilePrototype.from_dict(default_trusted_profile)
        if (enable_secure_boot := _dict.get('enable_secure_boot')) is not None:
            args['enable_secure_boot'] = enable_secure_boot
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in InstanceTemplateInstanceByImageInstanceTemplateContextInstanceByImageInstanceTemplateContextInstanceByNetworkAttachment JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in InstanceTemplateInstanceByImageInstanceTemplateContextInstanceByImageInstanceTemplateContextInstanceByNetworkAttachment JSON')
        if (keys := _dict.get('keys')) is not None:
            args['keys'] = keys
        if (metadata_service := _dict.get('metadata_service')) is not None:
            args['metadata_service'] = InstanceMetadataServicePrototype.from_dict(metadata_service)
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in InstanceTemplateInstanceByImageInstanceTemplateContextInstanceByImageInstanceTemplateContextInstanceByNetworkAttachment JSON')
        if (placement_target := _dict.get('placement_target')) is not None:
            args['placement_target'] = placement_target
        if (profile := _dict.get('profile')) is not None:
            args['profile'] = profile
        if (reservation_affinity := _dict.get('reservation_affinity')) is not None:
            args['reservation_affinity'] = InstanceReservationAffinityPrototype.from_dict(reservation_affinity)
        if (resource_group := _dict.get('resource_group')) is not None:
            args['resource_group'] = ResourceGroupReference.from_dict(resource_group)
        else:
            raise ValueError('Required property \'resource_group\' not present in InstanceTemplateInstanceByImageInstanceTemplateContextInstanceByImageInstanceTemplateContextInstanceByNetworkAttachment JSON')
        if (total_volume_bandwidth := _dict.get('total_volume_bandwidth')) is not None:
            args['total_volume_bandwidth'] = total_volume_bandwidth
        if (user_data := _dict.get('user_data')) is not None:
            args['user_data'] = user_data
        if (volume_attachments := _dict.get('volume_attachments')) is not None:
            args['volume_attachments'] = [VolumeAttachmentPrototype.from_dict(v) for v in volume_attachments]
        if (vpc := _dict.get('vpc')) is not None:
            args['vpc'] = vpc
        if (boot_volume_attachment := _dict.get('boot_volume_attachment')) is not None:
            args['boot_volume_attachment'] = VolumeAttachmentPrototypeInstanceByImageContext.from_dict(boot_volume_attachment)
        if (image := _dict.get('image')) is not None:
            args['image'] = image
        else:
            raise ValueError('Required property \'image\' not present in InstanceTemplateInstanceByImageInstanceTemplateContextInstanceByImageInstanceTemplateContextInstanceByNetworkAttachment JSON')
        if (zone := _dict.get('zone')) is not None:
            args['zone'] = zone
        else:
            raise ValueError('Required property \'zone\' not present in InstanceTemplateInstanceByImageInstanceTemplateContextInstanceByImageInstanceTemplateContextInstanceByNetworkAttachment JSON')
        if (network_attachments := _dict.get('network_attachments')) is not None:
            args['network_attachments'] = [InstanceNetworkAttachmentPrototype.from_dict(v) for v in network_attachments]
        if (primary_network_attachment := _dict.get('primary_network_attachment')) is not None:
            args['primary_network_attachment'] = InstanceNetworkAttachmentPrototype.from_dict(primary_network_attachment)
        else:
            raise ValueError('Required property \'primary_network_attachment\' not present in InstanceTemplateInstanceByImageInstanceTemplateContextInstanceByImageInstanceTemplateContextInstanceByNetworkAttachment JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceTemplateInstanceByImageInstanceTemplateContextInstanceByImageInstanceTemplateContextInstanceByNetworkAttachment object from 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, 'cluster_network_attachments') and self.cluster_network_attachments is not None:
            cluster_network_attachments_list = []
            for v in self.cluster_network_attachments:
                if isinstance(v, dict):
                    cluster_network_attachments_list.append(v)
                else:
                    cluster_network_attachments_list.append(v.to_dict())
            _dict['cluster_network_attachments'] = cluster_network_attachments_list
        if hasattr(self, 'confidential_compute_mode') and self.confidential_compute_mode is not None:
            _dict['confidential_compute_mode'] = self.confidential_compute_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, '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, '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, '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, 'reservation_affinity') and self.reservation_affinity is not None:
            if isinstance(self.reservation_affinity, dict):
                _dict['reservation_affinity'] = self.reservation_affinity
            else:
                _dict['reservation_affinity'] = self.reservation_affinity.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, '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, 'network_attachments') and self.network_attachments is not None:
            network_attachments_list = []
            for v in self.network_attachments:
                if isinstance(v, dict):
                    network_attachments_list.append(v)
                else:
                    network_attachments_list.append(v.to_dict())
            _dict['network_attachments'] = network_attachments_list
        if hasattr(self, 'primary_network_attachment') and self.primary_network_attachment is not None:
            if isinstance(self.primary_network_attachment, dict):
                _dict['primary_network_attachment'] = self.primary_network_attachment
            else:
                _dict['primary_network_attachment'] = self.primary_network_attachment.to_dict()
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceTemplateInstanceByImageInstanceTemplateContextInstanceByImageInstanceTemplateContextInstanceByNetworkAttachment object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceTemplateInstanceByImageInstanceTemplateContextInstanceByImageInstanceTemplateContextInstanceByNetworkAttachment') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceTemplateInstanceByImageInstanceTemplateContextInstanceByImageInstanceTemplateContextInstanceByNetworkAttachment') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ConfidentialComputeModeEnum(str, Enum):
        """
        The confidential compute mode to use for this virtual server instance.
        If unspecified, the default confidential compute mode from the profile will be
        used.
        """

        DISABLED = 'disabled'
        SGX = 'sgx'



class InstanceTemplateInstanceByImageInstanceTemplateContextInstanceByImageInstanceTemplateContextInstanceByNetworkInterface(InstanceTemplateInstanceByImageInstanceTemplateContext):
    """
    InstanceTemplateInstanceByImageInstanceTemplateContextInstanceByImageInstanceTemplateContextInstanceByNetworkInterface.

    :param InstanceAvailabilityPolicyPrototype availability_policy: (optional) The
          availability policy to use for this virtual server instance.
    :param List[InstanceClusterNetworkAttachmentPrototypeInstanceContext]
          cluster_network_attachments: (optional) The cluster network attachments to
          create for this virtual server instance. A cluster network attachment represents
          a device that is connected to a cluster network. The number of network
          attachments must match one of the values from the instance profile's
          `cluster_network_attachment_count` before the instance can be started.
    :param str confidential_compute_mode: (optional) The confidential compute mode
          to use for this virtual server instance.
          If unspecified, the default confidential compute mode from the profile will be
          used.
    :param datetime created_at: The date and time that the instance template was
          created.
    :param str crn: The CRN for this instance template.
    :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 bool enable_secure_boot: (optional) Indicates whether secure boot is
          enabled for this virtual server instance.
          If unspecified, the default secure boot mode from the profile will be used.
    :param str href: The URL for this instance template.
    :param str id: The unique identifier for this instance template.
    :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: The name for this instance template. The name is unique across
          all instance templates in the region.
    :param InstancePlacementTargetPrototype placement_target: (optional) The
          placement restrictions to use for the virtual server instance.
          If specified, `reservation_affinity.policy` must be `disabled`.
    :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 InstanceReservationAffinityPrototype reservation_affinity: (optional)
    :param ResourceGroupReference resource_group: The resource group for this
          instance template.
    :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
          attachments or instance network interfaces.
    :param VolumeAttachmentPrototypeInstanceByImageContext boot_volume_attachment:
          (optional) The boot volume attachment to create for the virtual server instance.
    :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 List[NetworkInterfacePrototype] network_interfaces: (optional) The
          additional instance network interfaces to create.
    :param NetworkInterfacePrototype primary_network_interface: The primary instance
          network interface to create.
    """

    def __init__(
        self,
        created_at: datetime,
        crn: str,
        href: str,
        id: str,
        name: str,
        resource_group: 'ResourceGroupReference',
        image: 'ImageIdentity',
        zone: 'ZoneIdentity',
        primary_network_interface: 'NetworkInterfacePrototype',
        *,
        availability_policy: Optional['InstanceAvailabilityPolicyPrototype'] = None,
        cluster_network_attachments: Optional[List['InstanceClusterNetworkAttachmentPrototypeInstanceContext']] = None,
        confidential_compute_mode: Optional[str] = None,
        default_trusted_profile: Optional['InstanceDefaultTrustedProfilePrototype'] = None,
        enable_secure_boot: Optional[bool] = None,
        keys: Optional[List['KeyIdentity']] = None,
        metadata_service: Optional['InstanceMetadataServicePrototype'] = None,
        placement_target: Optional['InstancePlacementTargetPrototype'] = None,
        profile: Optional['InstanceProfileIdentity'] = None,
        reservation_affinity: Optional['InstanceReservationAffinityPrototype'] = None,
        total_volume_bandwidth: Optional[int] = None,
        user_data: Optional[str] = None,
        volume_attachments: Optional[List['VolumeAttachmentPrototype']] = None,
        vpc: Optional['VPCIdentity'] = None,
        boot_volume_attachment: Optional['VolumeAttachmentPrototypeInstanceByImageContext'] = None,
        network_interfaces: Optional[List['NetworkInterfacePrototype']] = None,
    ) -> None:
        """
        Initialize a InstanceTemplateInstanceByImageInstanceTemplateContextInstanceByImageInstanceTemplateContextInstanceByNetworkInterface 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 NetworkInterfacePrototype primary_network_interface: The primary
               instance network interface to create.
        :param InstanceAvailabilityPolicyPrototype availability_policy: (optional)
               The availability policy to use for this virtual server instance.
        :param List[InstanceClusterNetworkAttachmentPrototypeInstanceContext]
               cluster_network_attachments: (optional) The cluster network attachments to
               create for this virtual server instance. A cluster network attachment
               represents a device that is connected to a cluster network. The number of
               network attachments must match one of the values from the instance
               profile's `cluster_network_attachment_count` before the instance can be
               started.
        :param str confidential_compute_mode: (optional) The confidential compute
               mode to use for this virtual server instance.
               If unspecified, the default confidential compute mode from the profile will
               be used.
        :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 bool enable_secure_boot: (optional) Indicates whether secure boot is
               enabled for this virtual server instance.
               If unspecified, the default secure boot mode from the profile will be used.
        :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.
               If specified, `reservation_affinity.policy` must be `disabled`.
        :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 InstanceReservationAffinityPrototype reservation_affinity:
               (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
               attachments or 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.cluster_network_attachments = cluster_network_attachments
        self.confidential_compute_mode = confidential_compute_mode
        self.created_at = created_at
        self.crn = crn
        self.default_trusted_profile = default_trusted_profile
        self.enable_secure_boot = enable_secure_boot
        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.reservation_affinity = reservation_affinity
        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.zone = zone
        self.network_interfaces = network_interfaces
        self.primary_network_interface = primary_network_interface

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceTemplateInstanceByImageInstanceTemplateContextInstanceByImageInstanceTemplateContextInstanceByNetworkInterface':
        """Initialize a InstanceTemplateInstanceByImageInstanceTemplateContextInstanceByImageInstanceTemplateContextInstanceByNetworkInterface object from a json dictionary."""
        args = {}
        if (availability_policy := _dict.get('availability_policy')) is not None:
            args['availability_policy'] = InstanceAvailabilityPolicyPrototype.from_dict(availability_policy)
        if (cluster_network_attachments := _dict.get('cluster_network_attachments')) is not None:
            args['cluster_network_attachments'] = [InstanceClusterNetworkAttachmentPrototypeInstanceContext.from_dict(v) for v in cluster_network_attachments]
        if (confidential_compute_mode := _dict.get('confidential_compute_mode')) is not None:
            args['confidential_compute_mode'] = confidential_compute_mode
        if (created_at := _dict.get('created_at')) is not None:
            args['created_at'] = string_to_datetime(created_at)
        else:
            raise ValueError('Required property \'created_at\' not present in InstanceTemplateInstanceByImageInstanceTemplateContextInstanceByImageInstanceTemplateContextInstanceByNetworkInterface JSON')
        if (crn := _dict.get('crn')) is not None:
            args['crn'] = crn
        else:
            raise ValueError('Required property \'crn\' not present in InstanceTemplateInstanceByImageInstanceTemplateContextInstanceByImageInstanceTemplateContextInstanceByNetworkInterface JSON')
        if (default_trusted_profile := _dict.get('default_trusted_profile')) is not None:
            args['default_trusted_profile'] = InstanceDefaultTrustedProfilePrototype.from_dict(default_trusted_profile)
        if (enable_secure_boot := _dict.get('enable_secure_boot')) is not None:
            args['enable_secure_boot'] = enable_secure_boot
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in InstanceTemplateInstanceByImageInstanceTemplateContextInstanceByImageInstanceTemplateContextInstanceByNetworkInterface JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in InstanceTemplateInstanceByImageInstanceTemplateContextInstanceByImageInstanceTemplateContextInstanceByNetworkInterface JSON')
        if (keys := _dict.get('keys')) is not None:
            args['keys'] = keys
        if (metadata_service := _dict.get('metadata_service')) is not None:
            args['metadata_service'] = InstanceMetadataServicePrototype.from_dict(metadata_service)
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in InstanceTemplateInstanceByImageInstanceTemplateContextInstanceByImageInstanceTemplateContextInstanceByNetworkInterface JSON')
        if (placement_target := _dict.get('placement_target')) is not None:
            args['placement_target'] = placement_target
        if (profile := _dict.get('profile')) is not None:
            args['profile'] = profile
        if (reservation_affinity := _dict.get('reservation_affinity')) is not None:
            args['reservation_affinity'] = InstanceReservationAffinityPrototype.from_dict(reservation_affinity)
        if (resource_group := _dict.get('resource_group')) is not None:
            args['resource_group'] = ResourceGroupReference.from_dict(resource_group)
        else:
            raise ValueError('Required property \'resource_group\' not present in InstanceTemplateInstanceByImageInstanceTemplateContextInstanceByImageInstanceTemplateContextInstanceByNetworkInterface JSON')
        if (total_volume_bandwidth := _dict.get('total_volume_bandwidth')) is not None:
            args['total_volume_bandwidth'] = total_volume_bandwidth
        if (user_data := _dict.get('user_data')) is not None:
            args['user_data'] = user_data
        if (volume_attachments := _dict.get('volume_attachments')) is not None:
            args['volume_attachments'] = [VolumeAttachmentPrototype.from_dict(v) for v in volume_attachments]
        if (vpc := _dict.get('vpc')) is not None:
            args['vpc'] = vpc
        if (boot_volume_attachment := _dict.get('boot_volume_attachment')) is not None:
            args['boot_volume_attachment'] = VolumeAttachmentPrototypeInstanceByImageContext.from_dict(boot_volume_attachment)
        if (image := _dict.get('image')) is not None:
            args['image'] = image
        else:
            raise ValueError('Required property \'image\' not present in InstanceTemplateInstanceByImageInstanceTemplateContextInstanceByImageInstanceTemplateContextInstanceByNetworkInterface JSON')
        if (zone := _dict.get('zone')) is not None:
            args['zone'] = zone
        else:
            raise ValueError('Required property \'zone\' not present in InstanceTemplateInstanceByImageInstanceTemplateContextInstanceByImageInstanceTemplateContextInstanceByNetworkInterface JSON')
        if (network_interfaces := _dict.get('network_interfaces')) is not None:
            args['network_interfaces'] = [NetworkInterfacePrototype.from_dict(v) for v in network_interfaces]
        if (primary_network_interface := _dict.get('primary_network_interface')) is not None:
            args['primary_network_interface'] = NetworkInterfacePrototype.from_dict(primary_network_interface)
        else:
            raise ValueError('Required property \'primary_network_interface\' not present in InstanceTemplateInstanceByImageInstanceTemplateContextInstanceByImageInstanceTemplateContextInstanceByNetworkInterface JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceTemplateInstanceByImageInstanceTemplateContextInstanceByImageInstanceTemplateContextInstanceByNetworkInterface object from 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, 'cluster_network_attachments') and self.cluster_network_attachments is not None:
            cluster_network_attachments_list = []
            for v in self.cluster_network_attachments:
                if isinstance(v, dict):
                    cluster_network_attachments_list.append(v)
                else:
                    cluster_network_attachments_list.append(v.to_dict())
            _dict['cluster_network_attachments'] = cluster_network_attachments_list
        if hasattr(self, 'confidential_compute_mode') and self.confidential_compute_mode is not None:
            _dict['confidential_compute_mode'] = self.confidential_compute_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, '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, '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, '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, 'reservation_affinity') and self.reservation_affinity is not None:
            if isinstance(self.reservation_affinity, dict):
                _dict['reservation_affinity'] = self.reservation_affinity
            else:
                _dict['reservation_affinity'] = self.reservation_affinity.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, '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, '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()
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceTemplateInstanceByImageInstanceTemplateContextInstanceByImageInstanceTemplateContextInstanceByNetworkInterface object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceTemplateInstanceByImageInstanceTemplateContextInstanceByImageInstanceTemplateContextInstanceByNetworkInterface') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceTemplateInstanceByImageInstanceTemplateContextInstanceByImageInstanceTemplateContextInstanceByNetworkInterface') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ConfidentialComputeModeEnum(str, Enum):
        """
        The confidential compute mode to use for this virtual server instance.
        If unspecified, the default confidential compute mode from the profile will be
        used.
        """

        DISABLED = 'disabled'
        SGX = 'sgx'



class InstanceTemplateInstanceBySourceSnapshotInstanceTemplateContextInstanceBySourceSnapshotInstanceTemplateContextInstanceByNetworkAttachment(InstanceTemplateInstanceBySourceSnapshotInstanceTemplateContext):
    """
    InstanceTemplateInstanceBySourceSnapshotInstanceTemplateContextInstanceBySourceSnapshotInstanceTemplateContextInstanceByNetworkAttachment.

    :param InstanceAvailabilityPolicyPrototype availability_policy: (optional) The
          availability policy to use for this virtual server instance.
    :param List[InstanceClusterNetworkAttachmentPrototypeInstanceContext]
          cluster_network_attachments: (optional) The cluster network attachments to
          create for this virtual server instance. A cluster network attachment represents
          a device that is connected to a cluster network. The number of network
          attachments must match one of the values from the instance profile's
          `cluster_network_attachment_count` before the instance can be started.
    :param str confidential_compute_mode: (optional) The confidential compute mode
          to use for this virtual server instance.
          If unspecified, the default confidential compute mode from the profile will be
          used.
    :param datetime created_at: The date and time that the instance template was
          created.
    :param str crn: The CRN for this instance template.
    :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 bool enable_secure_boot: (optional) Indicates whether secure boot is
          enabled for this virtual server instance.
          If unspecified, the default secure boot mode from the profile will be used.
    :param str href: The URL for this instance template.
    :param str id: The unique identifier for this instance template.
    :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: The name for this instance template. The name is unique across
          all instance templates in the region.
    :param InstancePlacementTargetPrototype placement_target: (optional) The
          placement restrictions to use for the virtual server instance.
          If specified, `reservation_affinity.policy` must be `disabled`.
    :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 InstanceReservationAffinityPrototype reservation_affinity: (optional)
    :param ResourceGroupReference resource_group: The resource group for this
          instance template.
    :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
          attachments or instance network interfaces.
    :param VolumeAttachmentPrototypeInstanceBySourceSnapshotContext
          boot_volume_attachment: 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 ZoneIdentity zone: The zone this virtual server instance will reside in.
    :param List[InstanceNetworkAttachmentPrototype] network_attachments: (optional)
          The additional network attachments to create for the virtual server instance.
    :param InstanceNetworkAttachmentPrototype primary_network_attachment: The
          primary network attachment to create for the virtual server instance.
    """

    def __init__(
        self,
        created_at: datetime,
        crn: str,
        href: str,
        id: str,
        name: str,
        resource_group: 'ResourceGroupReference',
        boot_volume_attachment: 'VolumeAttachmentPrototypeInstanceBySourceSnapshotContext',
        zone: 'ZoneIdentity',
        primary_network_attachment: 'InstanceNetworkAttachmentPrototype',
        *,
        availability_policy: Optional['InstanceAvailabilityPolicyPrototype'] = None,
        cluster_network_attachments: Optional[List['InstanceClusterNetworkAttachmentPrototypeInstanceContext']] = None,
        confidential_compute_mode: Optional[str] = None,
        default_trusted_profile: Optional['InstanceDefaultTrustedProfilePrototype'] = None,
        enable_secure_boot: Optional[bool] = None,
        keys: Optional[List['KeyIdentity']] = None,
        metadata_service: Optional['InstanceMetadataServicePrototype'] = None,
        placement_target: Optional['InstancePlacementTargetPrototype'] = None,
        profile: Optional['InstanceProfileIdentity'] = None,
        reservation_affinity: Optional['InstanceReservationAffinityPrototype'] = None,
        total_volume_bandwidth: Optional[int] = None,
        user_data: Optional[str] = None,
        volume_attachments: Optional[List['VolumeAttachmentPrototype']] = None,
        vpc: Optional['VPCIdentity'] = None,
        network_interfaces: Optional[List['NetworkInterfacePrototype']] = None,
        network_attachments: Optional[List['InstanceNetworkAttachmentPrototype']] = None,
    ) -> None:
        """
        Initialize a InstanceTemplateInstanceBySourceSnapshotInstanceTemplateContextInstanceBySourceSnapshotInstanceTemplateContextInstanceByNetworkAttachment 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 InstanceNetworkAttachmentPrototype primary_network_attachment: The
               primary network attachment to create for the virtual server instance.
        :param InstanceAvailabilityPolicyPrototype availability_policy: (optional)
               The availability policy to use for this virtual server instance.
        :param List[InstanceClusterNetworkAttachmentPrototypeInstanceContext]
               cluster_network_attachments: (optional) The cluster network attachments to
               create for this virtual server instance. A cluster network attachment
               represents a device that is connected to a cluster network. The number of
               network attachments must match one of the values from the instance
               profile's `cluster_network_attachment_count` before the instance can be
               started.
        :param str confidential_compute_mode: (optional) The confidential compute
               mode to use for this virtual server instance.
               If unspecified, the default confidential compute mode from the profile will
               be used.
        :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 bool enable_secure_boot: (optional) Indicates whether secure boot is
               enabled for this virtual server instance.
               If unspecified, the default secure boot mode from the profile will be used.
        :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.
               If specified, `reservation_affinity.policy` must be `disabled`.
        :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 InstanceReservationAffinityPrototype reservation_affinity:
               (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
               attachments or instance network interfaces.
        :param List[NetworkInterfacePrototype] network_interfaces: (optional) The
               additional instance network interfaces to create.
        :param List[InstanceNetworkAttachmentPrototype] network_attachments:
               (optional) The additional network attachments to create for the virtual
               server instance.
        """
        # pylint: disable=super-init-not-called
        self.availability_policy = availability_policy
        self.cluster_network_attachments = cluster_network_attachments
        self.confidential_compute_mode = confidential_compute_mode
        self.created_at = created_at
        self.crn = crn
        self.default_trusted_profile = default_trusted_profile
        self.enable_secure_boot = enable_secure_boot
        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.reservation_affinity = reservation_affinity
        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.zone = zone
        self.network_attachments = network_attachments
        self.primary_network_attachment = primary_network_attachment

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceTemplateInstanceBySourceSnapshotInstanceTemplateContextInstanceBySourceSnapshotInstanceTemplateContextInstanceByNetworkAttachment':
        """Initialize a InstanceTemplateInstanceBySourceSnapshotInstanceTemplateContextInstanceBySourceSnapshotInstanceTemplateContextInstanceByNetworkAttachment object from a json dictionary."""
        args = {}
        if (availability_policy := _dict.get('availability_policy')) is not None:
            args['availability_policy'] = InstanceAvailabilityPolicyPrototype.from_dict(availability_policy)
        if (cluster_network_attachments := _dict.get('cluster_network_attachments')) is not None:
            args['cluster_network_attachments'] = [InstanceClusterNetworkAttachmentPrototypeInstanceContext.from_dict(v) for v in cluster_network_attachments]
        if (confidential_compute_mode := _dict.get('confidential_compute_mode')) is not None:
            args['confidential_compute_mode'] = confidential_compute_mode
        if (created_at := _dict.get('created_at')) is not None:
            args['created_at'] = string_to_datetime(created_at)
        else:
            raise ValueError('Required property \'created_at\' not present in InstanceTemplateInstanceBySourceSnapshotInstanceTemplateContextInstanceBySourceSnapshotInstanceTemplateContextInstanceByNetworkAttachment JSON')
        if (crn := _dict.get('crn')) is not None:
            args['crn'] = crn
        else:
            raise ValueError('Required property \'crn\' not present in InstanceTemplateInstanceBySourceSnapshotInstanceTemplateContextInstanceBySourceSnapshotInstanceTemplateContextInstanceByNetworkAttachment JSON')
        if (default_trusted_profile := _dict.get('default_trusted_profile')) is not None:
            args['default_trusted_profile'] = InstanceDefaultTrustedProfilePrototype.from_dict(default_trusted_profile)
        if (enable_secure_boot := _dict.get('enable_secure_boot')) is not None:
            args['enable_secure_boot'] = enable_secure_boot
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in InstanceTemplateInstanceBySourceSnapshotInstanceTemplateContextInstanceBySourceSnapshotInstanceTemplateContextInstanceByNetworkAttachment JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in InstanceTemplateInstanceBySourceSnapshotInstanceTemplateContextInstanceBySourceSnapshotInstanceTemplateContextInstanceByNetworkAttachment JSON')
        if (keys := _dict.get('keys')) is not None:
            args['keys'] = keys
        if (metadata_service := _dict.get('metadata_service')) is not None:
            args['metadata_service'] = InstanceMetadataServicePrototype.from_dict(metadata_service)
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in InstanceTemplateInstanceBySourceSnapshotInstanceTemplateContextInstanceBySourceSnapshotInstanceTemplateContextInstanceByNetworkAttachment JSON')
        if (placement_target := _dict.get('placement_target')) is not None:
            args['placement_target'] = placement_target
        if (profile := _dict.get('profile')) is not None:
            args['profile'] = profile
        if (reservation_affinity := _dict.get('reservation_affinity')) is not None:
            args['reservation_affinity'] = InstanceReservationAffinityPrototype.from_dict(reservation_affinity)
        if (resource_group := _dict.get('resource_group')) is not None:
            args['resource_group'] = ResourceGroupReference.from_dict(resource_group)
        else:
            raise ValueError('Required property \'resource_group\' not present in InstanceTemplateInstanceBySourceSnapshotInstanceTemplateContextInstanceBySourceSnapshotInstanceTemplateContextInstanceByNetworkAttachment JSON')
        if (total_volume_bandwidth := _dict.get('total_volume_bandwidth')) is not None:
            args['total_volume_bandwidth'] = total_volume_bandwidth
        if (user_data := _dict.get('user_data')) is not None:
            args['user_data'] = user_data
        if (volume_attachments := _dict.get('volume_attachments')) is not None:
            args['volume_attachments'] = [VolumeAttachmentPrototype.from_dict(v) for v in volume_attachments]
        if (vpc := _dict.get('vpc')) is not None:
            args['vpc'] = vpc
        if (boot_volume_attachment := _dict.get('boot_volume_attachment')) is not None:
            args['boot_volume_attachment'] = VolumeAttachmentPrototypeInstanceBySourceSnapshotContext.from_dict(boot_volume_attachment)
        else:
            raise ValueError('Required property \'boot_volume_attachment\' not present in InstanceTemplateInstanceBySourceSnapshotInstanceTemplateContextInstanceBySourceSnapshotInstanceTemplateContextInstanceByNetworkAttachment JSON')
        if (network_interfaces := _dict.get('network_interfaces')) is not None:
            args['network_interfaces'] = [NetworkInterfacePrototype.from_dict(v) for v in network_interfaces]
        if (zone := _dict.get('zone')) is not None:
            args['zone'] = zone
        else:
            raise ValueError('Required property \'zone\' not present in InstanceTemplateInstanceBySourceSnapshotInstanceTemplateContextInstanceBySourceSnapshotInstanceTemplateContextInstanceByNetworkAttachment JSON')
        if (network_attachments := _dict.get('network_attachments')) is not None:
            args['network_attachments'] = [InstanceNetworkAttachmentPrototype.from_dict(v) for v in network_attachments]
        if (primary_network_attachment := _dict.get('primary_network_attachment')) is not None:
            args['primary_network_attachment'] = InstanceNetworkAttachmentPrototype.from_dict(primary_network_attachment)
        else:
            raise ValueError('Required property \'primary_network_attachment\' not present in InstanceTemplateInstanceBySourceSnapshotInstanceTemplateContextInstanceBySourceSnapshotInstanceTemplateContextInstanceByNetworkAttachment JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceTemplateInstanceBySourceSnapshotInstanceTemplateContextInstanceBySourceSnapshotInstanceTemplateContextInstanceByNetworkAttachment object from 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, 'cluster_network_attachments') and self.cluster_network_attachments is not None:
            cluster_network_attachments_list = []
            for v in self.cluster_network_attachments:
                if isinstance(v, dict):
                    cluster_network_attachments_list.append(v)
                else:
                    cluster_network_attachments_list.append(v.to_dict())
            _dict['cluster_network_attachments'] = cluster_network_attachments_list
        if hasattr(self, 'confidential_compute_mode') and self.confidential_compute_mode is not None:
            _dict['confidential_compute_mode'] = self.confidential_compute_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, '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, '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, '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, 'reservation_affinity') and self.reservation_affinity is not None:
            if isinstance(self.reservation_affinity, dict):
                _dict['reservation_affinity'] = self.reservation_affinity
            else:
                _dict['reservation_affinity'] = self.reservation_affinity.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, '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, 'network_attachments') and self.network_attachments is not None:
            network_attachments_list = []
            for v in self.network_attachments:
                if isinstance(v, dict):
                    network_attachments_list.append(v)
                else:
                    network_attachments_list.append(v.to_dict())
            _dict['network_attachments'] = network_attachments_list
        if hasattr(self, 'primary_network_attachment') and self.primary_network_attachment is not None:
            if isinstance(self.primary_network_attachment, dict):
                _dict['primary_network_attachment'] = self.primary_network_attachment
            else:
                _dict['primary_network_attachment'] = self.primary_network_attachment.to_dict()
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceTemplateInstanceBySourceSnapshotInstanceTemplateContextInstanceBySourceSnapshotInstanceTemplateContextInstanceByNetworkAttachment object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceTemplateInstanceBySourceSnapshotInstanceTemplateContextInstanceBySourceSnapshotInstanceTemplateContextInstanceByNetworkAttachment') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceTemplateInstanceBySourceSnapshotInstanceTemplateContextInstanceBySourceSnapshotInstanceTemplateContextInstanceByNetworkAttachment') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ConfidentialComputeModeEnum(str, Enum):
        """
        The confidential compute mode to use for this virtual server instance.
        If unspecified, the default confidential compute mode from the profile will be
        used.
        """

        DISABLED = 'disabled'
        SGX = 'sgx'



class InstanceTemplateInstanceBySourceSnapshotInstanceTemplateContextInstanceBySourceSnapshotInstanceTemplateContextInstanceByNetworkInterface(InstanceTemplateInstanceBySourceSnapshotInstanceTemplateContext):
    """
    InstanceTemplateInstanceBySourceSnapshotInstanceTemplateContextInstanceBySourceSnapshotInstanceTemplateContextInstanceByNetworkInterface.

    :param InstanceAvailabilityPolicyPrototype availability_policy: (optional) The
          availability policy to use for this virtual server instance.
    :param List[InstanceClusterNetworkAttachmentPrototypeInstanceContext]
          cluster_network_attachments: (optional) The cluster network attachments to
          create for this virtual server instance. A cluster network attachment represents
          a device that is connected to a cluster network. The number of network
          attachments must match one of the values from the instance profile's
          `cluster_network_attachment_count` before the instance can be started.
    :param str confidential_compute_mode: (optional) The confidential compute mode
          to use for this virtual server instance.
          If unspecified, the default confidential compute mode from the profile will be
          used.
    :param datetime created_at: The date and time that the instance template was
          created.
    :param str crn: The CRN for this instance template.
    :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 bool enable_secure_boot: (optional) Indicates whether secure boot is
          enabled for this virtual server instance.
          If unspecified, the default secure boot mode from the profile will be used.
    :param str href: The URL for this instance template.
    :param str id: The unique identifier for this instance template.
    :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: The name for this instance template. The name is unique across
          all instance templates in the region.
    :param InstancePlacementTargetPrototype placement_target: (optional) The
          placement restrictions to use for the virtual server instance.
          If specified, `reservation_affinity.policy` must be `disabled`.
    :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 InstanceReservationAffinityPrototype reservation_affinity: (optional)
    :param ResourceGroupReference resource_group: The resource group for this
          instance template.
    :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
          attachments or instance network interfaces.
    :param VolumeAttachmentPrototypeInstanceBySourceSnapshotContext
          boot_volume_attachment: The boot volume attachment to create for the virtual
          server instance.
    :param List[InstanceNetworkAttachmentPrototype] network_attachments: (optional)
          The additional network attachments to create for the virtual server instance.
    :param InstanceNetworkAttachmentPrototype primary_network_attachment: (optional)
          The primary network attachment to create for the virtual server instance.
    :param ZoneIdentity zone: The zone this virtual server instance will reside in.
    :param List[NetworkInterfacePrototype] network_interfaces: (optional) The
          additional instance network interfaces to create.
    :param NetworkInterfacePrototype primary_network_interface: The primary instance
          network interface to create.
    """

    def __init__(
        self,
        created_at: datetime,
        crn: str,
        href: str,
        id: str,
        name: str,
        resource_group: 'ResourceGroupReference',
        boot_volume_attachment: 'VolumeAttachmentPrototypeInstanceBySourceSnapshotContext',
        zone: 'ZoneIdentity',
        primary_network_interface: 'NetworkInterfacePrototype',
        *,
        availability_policy: Optional['InstanceAvailabilityPolicyPrototype'] = None,
        cluster_network_attachments: Optional[List['InstanceClusterNetworkAttachmentPrototypeInstanceContext']] = None,
        confidential_compute_mode: Optional[str] = None,
        default_trusted_profile: Optional['InstanceDefaultTrustedProfilePrototype'] = None,
        enable_secure_boot: Optional[bool] = None,
        keys: Optional[List['KeyIdentity']] = None,
        metadata_service: Optional['InstanceMetadataServicePrototype'] = None,
        placement_target: Optional['InstancePlacementTargetPrototype'] = None,
        profile: Optional['InstanceProfileIdentity'] = None,
        reservation_affinity: Optional['InstanceReservationAffinityPrototype'] = None,
        total_volume_bandwidth: Optional[int] = None,
        user_data: Optional[str] = None,
        volume_attachments: Optional[List['VolumeAttachmentPrototype']] = None,
        vpc: Optional['VPCIdentity'] = None,
        network_attachments: Optional[List['InstanceNetworkAttachmentPrototype']] = None,
        primary_network_attachment: Optional['InstanceNetworkAttachmentPrototype'] = None,
        network_interfaces: Optional[List['NetworkInterfacePrototype']] = None,
    ) -> None:
        """
        Initialize a InstanceTemplateInstanceBySourceSnapshotInstanceTemplateContextInstanceBySourceSnapshotInstanceTemplateContextInstanceByNetworkInterface 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 NetworkInterfacePrototype primary_network_interface: The primary
               instance network interface to create.
        :param InstanceAvailabilityPolicyPrototype availability_policy: (optional)
               The availability policy to use for this virtual server instance.
        :param List[InstanceClusterNetworkAttachmentPrototypeInstanceContext]
               cluster_network_attachments: (optional) The cluster network attachments to
               create for this virtual server instance. A cluster network attachment
               represents a device that is connected to a cluster network. The number of
               network attachments must match one of the values from the instance
               profile's `cluster_network_attachment_count` before the instance can be
               started.
        :param str confidential_compute_mode: (optional) The confidential compute
               mode to use for this virtual server instance.
               If unspecified, the default confidential compute mode from the profile will
               be used.
        :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 bool enable_secure_boot: (optional) Indicates whether secure boot is
               enabled for this virtual server instance.
               If unspecified, the default secure boot mode from the profile will be used.
        :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.
               If specified, `reservation_affinity.policy` must be `disabled`.
        :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 InstanceReservationAffinityPrototype reservation_affinity:
               (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
               attachments or instance network interfaces.
        :param List[InstanceNetworkAttachmentPrototype] network_attachments:
               (optional) The additional network attachments to create for the virtual
               server instance.
        :param InstanceNetworkAttachmentPrototype primary_network_attachment:
               (optional) The primary network 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.cluster_network_attachments = cluster_network_attachments
        self.confidential_compute_mode = confidential_compute_mode
        self.created_at = created_at
        self.crn = crn
        self.default_trusted_profile = default_trusted_profile
        self.enable_secure_boot = enable_secure_boot
        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.reservation_affinity = reservation_affinity
        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_attachments = network_attachments
        self.primary_network_attachment = primary_network_attachment
        self.zone = zone
        self.network_interfaces = network_interfaces
        self.primary_network_interface = primary_network_interface

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'InstanceTemplateInstanceBySourceSnapshotInstanceTemplateContextInstanceBySourceSnapshotInstanceTemplateContextInstanceByNetworkInterface':
        """Initialize a InstanceTemplateInstanceBySourceSnapshotInstanceTemplateContextInstanceBySourceSnapshotInstanceTemplateContextInstanceByNetworkInterface object from a json dictionary."""
        args = {}
        if (availability_policy := _dict.get('availability_policy')) is not None:
            args['availability_policy'] = InstanceAvailabilityPolicyPrototype.from_dict(availability_policy)
        if (cluster_network_attachments := _dict.get('cluster_network_attachments')) is not None:
            args['cluster_network_attachments'] = [InstanceClusterNetworkAttachmentPrototypeInstanceContext.from_dict(v) for v in cluster_network_attachments]
        if (confidential_compute_mode := _dict.get('confidential_compute_mode')) is not None:
            args['confidential_compute_mode'] = confidential_compute_mode
        if (created_at := _dict.get('created_at')) is not None:
            args['created_at'] = string_to_datetime(created_at)
        else:
            raise ValueError('Required property \'created_at\' not present in InstanceTemplateInstanceBySourceSnapshotInstanceTemplateContextInstanceBySourceSnapshotInstanceTemplateContextInstanceByNetworkInterface JSON')
        if (crn := _dict.get('crn')) is not None:
            args['crn'] = crn
        else:
            raise ValueError('Required property \'crn\' not present in InstanceTemplateInstanceBySourceSnapshotInstanceTemplateContextInstanceBySourceSnapshotInstanceTemplateContextInstanceByNetworkInterface JSON')
        if (default_trusted_profile := _dict.get('default_trusted_profile')) is not None:
            args['default_trusted_profile'] = InstanceDefaultTrustedProfilePrototype.from_dict(default_trusted_profile)
        if (enable_secure_boot := _dict.get('enable_secure_boot')) is not None:
            args['enable_secure_boot'] = enable_secure_boot
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in InstanceTemplateInstanceBySourceSnapshotInstanceTemplateContextInstanceBySourceSnapshotInstanceTemplateContextInstanceByNetworkInterface JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in InstanceTemplateInstanceBySourceSnapshotInstanceTemplateContextInstanceBySourceSnapshotInstanceTemplateContextInstanceByNetworkInterface JSON')
        if (keys := _dict.get('keys')) is not None:
            args['keys'] = keys
        if (metadata_service := _dict.get('metadata_service')) is not None:
            args['metadata_service'] = InstanceMetadataServicePrototype.from_dict(metadata_service)
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in InstanceTemplateInstanceBySourceSnapshotInstanceTemplateContextInstanceBySourceSnapshotInstanceTemplateContextInstanceByNetworkInterface JSON')
        if (placement_target := _dict.get('placement_target')) is not None:
            args['placement_target'] = placement_target
        if (profile := _dict.get('profile')) is not None:
            args['profile'] = profile
        if (reservation_affinity := _dict.get('reservation_affinity')) is not None:
            args['reservation_affinity'] = InstanceReservationAffinityPrototype.from_dict(reservation_affinity)
        if (resource_group := _dict.get('resource_group')) is not None:
            args['resource_group'] = ResourceGroupReference.from_dict(resource_group)
        else:
            raise ValueError('Required property \'resource_group\' not present in InstanceTemplateInstanceBySourceSnapshotInstanceTemplateContextInstanceBySourceSnapshotInstanceTemplateContextInstanceByNetworkInterface JSON')
        if (total_volume_bandwidth := _dict.get('total_volume_bandwidth')) is not None:
            args['total_volume_bandwidth'] = total_volume_bandwidth
        if (user_data := _dict.get('user_data')) is not None:
            args['user_data'] = user_data
        if (volume_attachments := _dict.get('volume_attachments')) is not None:
            args['volume_attachments'] = [VolumeAttachmentPrototype.from_dict(v) for v in volume_attachments]
        if (vpc := _dict.get('vpc')) is not None:
            args['vpc'] = vpc
        if (boot_volume_attachment := _dict.get('boot_volume_attachment')) is not None:
            args['boot_volume_attachment'] = VolumeAttachmentPrototypeInstanceBySourceSnapshotContext.from_dict(boot_volume_attachment)
        else:
            raise ValueError('Required property \'boot_volume_attachment\' not present in InstanceTemplateInstanceBySourceSnapshotInstanceTemplateContextInstanceBySourceSnapshotInstanceTemplateContextInstanceByNetworkInterface JSON')
        if (network_attachments := _dict.get('network_attachments')) is not None:
            args['network_attachments'] = [InstanceNetworkAttachmentPrototype.from_dict(v) for v in network_attachments]
        if (primary_network_attachment := _dict.get('primary_network_attachment')) is not None:
            args['primary_network_attachment'] = InstanceNetworkAttachmentPrototype.from_dict(primary_network_attachment)
        if (zone := _dict.get('zone')) is not None:
            args['zone'] = zone
        else:
            raise ValueError('Required property \'zone\' not present in InstanceTemplateInstanceBySourceSnapshotInstanceTemplateContextInstanceBySourceSnapshotInstanceTemplateContextInstanceByNetworkInterface JSON')
        if (network_interfaces := _dict.get('network_interfaces')) is not None:
            args['network_interfaces'] = [NetworkInterfacePrototype.from_dict(v) for v in network_interfaces]
        if (primary_network_interface := _dict.get('primary_network_interface')) is not None:
            args['primary_network_interface'] = NetworkInterfacePrototype.from_dict(primary_network_interface)
        else:
            raise ValueError('Required property \'primary_network_interface\' not present in InstanceTemplateInstanceBySourceSnapshotInstanceTemplateContextInstanceBySourceSnapshotInstanceTemplateContextInstanceByNetworkInterface JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a InstanceTemplateInstanceBySourceSnapshotInstanceTemplateContextInstanceBySourceSnapshotInstanceTemplateContextInstanceByNetworkInterface object from 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, 'cluster_network_attachments') and self.cluster_network_attachments is not None:
            cluster_network_attachments_list = []
            for v in self.cluster_network_attachments:
                if isinstance(v, dict):
                    cluster_network_attachments_list.append(v)
                else:
                    cluster_network_attachments_list.append(v.to_dict())
            _dict['cluster_network_attachments'] = cluster_network_attachments_list
        if hasattr(self, 'confidential_compute_mode') and self.confidential_compute_mode is not None:
            _dict['confidential_compute_mode'] = self.confidential_compute_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, '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, '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, '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, 'reservation_affinity') and self.reservation_affinity is not None:
            if isinstance(self.reservation_affinity, dict):
                _dict['reservation_affinity'] = self.reservation_affinity
            else:
                _dict['reservation_affinity'] = self.reservation_affinity.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_attachments') and self.network_attachments is not None:
            network_attachments_list = []
            for v in self.network_attachments:
                if isinstance(v, dict):
                    network_attachments_list.append(v)
                else:
                    network_attachments_list.append(v.to_dict())
            _dict['network_attachments'] = network_attachments_list
        if hasattr(self, 'primary_network_attachment') and self.primary_network_attachment is not None:
            if isinstance(self.primary_network_attachment, dict):
                _dict['primary_network_attachment'] = self.primary_network_attachment
            else:
                _dict['primary_network_attachment'] = self.primary_network_attachment.to_dict()
        if hasattr(self, 'zone') and self.zone is not None:
            if isinstance(self.zone, dict):
                _dict['zone'] = self.zone
            else:
                _dict['zone'] = self.zone.to_dict()
        if hasattr(self, '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()
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this InstanceTemplateInstanceBySourceSnapshotInstanceTemplateContextInstanceBySourceSnapshotInstanceTemplateContextInstanceByNetworkInterface object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'InstanceTemplateInstanceBySourceSnapshotInstanceTemplateContextInstanceBySourceSnapshotInstanceTemplateContextInstanceByNetworkInterface') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'InstanceTemplateInstanceBySourceSnapshotInstanceTemplateContextInstanceBySourceSnapshotInstanceTemplateContextInstanceByNetworkInterface') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class ConfidentialComputeModeEnum(str, Enum):
        """
        The confidential compute mode to use for this virtual server instance.
        If unspecified, the default confidential compute mode from the profile will be
        used.
        """

        DISABLED = 'disabled'
        SGX = 'sgx'



class LoadBalancerListenerPolicyTargetPatchLoadBalancerPoolIdentityLoadBalancerPoolIdentityLoadBalancerPoolIdentityByHref(LoadBalancerListenerPolicyTargetPatchLoadBalancerPoolIdentity):
    """
    LoadBalancerListenerPolicyTargetPatchLoadBalancerPoolIdentityLoadBalancerPoolIdentityLoadBalancerPoolIdentityByHref.

    :param str href: The URL for this load balancer pool.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a LoadBalancerListenerPolicyTargetPatchLoadBalancerPoolIdentityLoadBalancerPoolIdentityLoadBalancerPoolIdentityByHref object.

        :param str href: The URL for this load balancer pool.
        """
        # pylint: disable=super-init-not-called
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerListenerPolicyTargetPatchLoadBalancerPoolIdentityLoadBalancerPoolIdentityLoadBalancerPoolIdentityByHref':
        """Initialize a LoadBalancerListenerPolicyTargetPatchLoadBalancerPoolIdentityLoadBalancerPoolIdentityLoadBalancerPoolIdentityByHref object from a json dictionary."""
        args = {}
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in LoadBalancerListenerPolicyTargetPatchLoadBalancerPoolIdentityLoadBalancerPoolIdentityLoadBalancerPoolIdentityByHref JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerListenerPolicyTargetPatchLoadBalancerPoolIdentityLoadBalancerPoolIdentityLoadBalancerPoolIdentityByHref object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancerListenerPolicyTargetPatchLoadBalancerPoolIdentityLoadBalancerPoolIdentityLoadBalancerPoolIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerListenerPolicyTargetPatchLoadBalancerPoolIdentityLoadBalancerPoolIdentityLoadBalancerPoolIdentityByHref') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerListenerPolicyTargetPatchLoadBalancerPoolIdentityLoadBalancerPoolIdentityLoadBalancerPoolIdentityByHref') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class LoadBalancerListenerPolicyTargetPatchLoadBalancerPoolIdentityLoadBalancerPoolIdentityLoadBalancerPoolIdentityById(LoadBalancerListenerPolicyTargetPatchLoadBalancerPoolIdentity):
    """
    LoadBalancerListenerPolicyTargetPatchLoadBalancerPoolIdentityLoadBalancerPoolIdentityLoadBalancerPoolIdentityById.

    :param str id: The unique identifier for this load balancer pool.
    """

    def __init__(
        self,
        id: str,
    ) -> None:
        """
        Initialize a LoadBalancerListenerPolicyTargetPatchLoadBalancerPoolIdentityLoadBalancerPoolIdentityLoadBalancerPoolIdentityById 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) -> 'LoadBalancerListenerPolicyTargetPatchLoadBalancerPoolIdentityLoadBalancerPoolIdentityLoadBalancerPoolIdentityById':
        """Initialize a LoadBalancerListenerPolicyTargetPatchLoadBalancerPoolIdentityLoadBalancerPoolIdentityLoadBalancerPoolIdentityById object from a json dictionary."""
        args = {}
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in LoadBalancerListenerPolicyTargetPatchLoadBalancerPoolIdentityLoadBalancerPoolIdentityLoadBalancerPoolIdentityById JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerListenerPolicyTargetPatchLoadBalancerPoolIdentityLoadBalancerPoolIdentityLoadBalancerPoolIdentityById object from 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 LoadBalancerListenerPolicyTargetPatchLoadBalancerPoolIdentityLoadBalancerPoolIdentityLoadBalancerPoolIdentityById object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerListenerPolicyTargetPatchLoadBalancerPoolIdentityLoadBalancerPoolIdentityLoadBalancerPoolIdentityById') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerListenerPolicyTargetPatchLoadBalancerPoolIdentityLoadBalancerPoolIdentityLoadBalancerPoolIdentityById') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class LoadBalancerListenerPolicyTargetPrototypeLoadBalancerPoolIdentityLoadBalancerPoolIdentityLoadBalancerPoolIdentityByHref(LoadBalancerListenerPolicyTargetPrototypeLoadBalancerPoolIdentity):
    """
    LoadBalancerListenerPolicyTargetPrototypeLoadBalancerPoolIdentityLoadBalancerPoolIdentityLoadBalancerPoolIdentityByHref.

    :param str href: The URL for this load balancer pool.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a LoadBalancerListenerPolicyTargetPrototypeLoadBalancerPoolIdentityLoadBalancerPoolIdentityLoadBalancerPoolIdentityByHref object.

        :param str href: The URL for this load balancer pool.
        """
        # pylint: disable=super-init-not-called
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LoadBalancerListenerPolicyTargetPrototypeLoadBalancerPoolIdentityLoadBalancerPoolIdentityLoadBalancerPoolIdentityByHref':
        """Initialize a LoadBalancerListenerPolicyTargetPrototypeLoadBalancerPoolIdentityLoadBalancerPoolIdentityLoadBalancerPoolIdentityByHref object from a json dictionary."""
        args = {}
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in LoadBalancerListenerPolicyTargetPrototypeLoadBalancerPoolIdentityLoadBalancerPoolIdentityLoadBalancerPoolIdentityByHref JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerListenerPolicyTargetPrototypeLoadBalancerPoolIdentityLoadBalancerPoolIdentityLoadBalancerPoolIdentityByHref object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this LoadBalancerListenerPolicyTargetPrototypeLoadBalancerPoolIdentityLoadBalancerPoolIdentityLoadBalancerPoolIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerListenerPolicyTargetPrototypeLoadBalancerPoolIdentityLoadBalancerPoolIdentityLoadBalancerPoolIdentityByHref') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerListenerPolicyTargetPrototypeLoadBalancerPoolIdentityLoadBalancerPoolIdentityLoadBalancerPoolIdentityByHref') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class LoadBalancerListenerPolicyTargetPrototypeLoadBalancerPoolIdentityLoadBalancerPoolIdentityLoadBalancerPoolIdentityById(LoadBalancerListenerPolicyTargetPrototypeLoadBalancerPoolIdentity):
    """
    LoadBalancerListenerPolicyTargetPrototypeLoadBalancerPoolIdentityLoadBalancerPoolIdentityLoadBalancerPoolIdentityById.

    :param str id: The unique identifier for this load balancer pool.
    """

    def __init__(
        self,
        id: str,
    ) -> None:
        """
        Initialize a LoadBalancerListenerPolicyTargetPrototypeLoadBalancerPoolIdentityLoadBalancerPoolIdentityLoadBalancerPoolIdentityById 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) -> 'LoadBalancerListenerPolicyTargetPrototypeLoadBalancerPoolIdentityLoadBalancerPoolIdentityLoadBalancerPoolIdentityById':
        """Initialize a LoadBalancerListenerPolicyTargetPrototypeLoadBalancerPoolIdentityLoadBalancerPoolIdentityLoadBalancerPoolIdentityById object from a json dictionary."""
        args = {}
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in LoadBalancerListenerPolicyTargetPrototypeLoadBalancerPoolIdentityLoadBalancerPoolIdentityLoadBalancerPoolIdentityById JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a LoadBalancerListenerPolicyTargetPrototypeLoadBalancerPoolIdentityLoadBalancerPoolIdentityLoadBalancerPoolIdentityById object from 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 LoadBalancerListenerPolicyTargetPrototypeLoadBalancerPoolIdentityLoadBalancerPoolIdentityLoadBalancerPoolIdentityById object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'LoadBalancerListenerPolicyTargetPrototypeLoadBalancerPoolIdentityLoadBalancerPoolIdentityLoadBalancerPoolIdentityById') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'LoadBalancerListenerPolicyTargetPrototypeLoadBalancerPoolIdentityLoadBalancerPoolIdentityLoadBalancerPoolIdentityById') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class LoadBalancerPoolMemberTargetPrototypeInstanceIdentityInstanceIdentityByCRN(LoadBalancerPoolMemberTargetPrototypeInstanceIdentity):
    """
    LoadBalancerPoolMemberTargetPrototypeInstanceIdentityInstanceIdentityByCRN.

    :param 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 := _dict.get('crn')) is not None:
            args['crn'] = 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.

    :param 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 := _dict.get('href')) is not None:
            args['href'] = 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.

    :param 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 := _dict.get('id')) is not None:
            args['id'] = 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.

    :param 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 := _dict.get('href')) is not None:
            args['href'] = 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.

    :param 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 := _dict.get('id')) is not None:
            args['id'] = 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.

    :param 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 := _dict.get('address')) is not None:
            args['address'] = 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.

    :param 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 := _dict.get('crn')) is not None:
            args['crn'] = 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.

    :param 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 := _dict.get('href')) is not None:
            args['href'] = 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.

    :param 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 := _dict.get('id')) is not None:
            args['id'] = 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.

    :param 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 := _dict.get('crn')) is not None:
            args['crn'] = 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.

    :param 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 := _dict.get('href')) is not None:
            args['href'] = 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.

    :param 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 := _dict.get('id')) is not None:
            args['id'] = 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 ReservedIPTargetPrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByCRN(ReservedIPTargetPrototypeVirtualNetworkInterfaceIdentity):
    """
    ReservedIPTargetPrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByCRN.

    :param str crn: The CRN for this virtual network interface.
    """

    def __init__(
        self,
        crn: str,
    ) -> None:
        """
        Initialize a ReservedIPTargetPrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByCRN object.

        :param str crn: The CRN for this virtual network interface.
        """
        # pylint: disable=super-init-not-called
        self.crn = crn

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ReservedIPTargetPrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByCRN':
        """Initialize a ReservedIPTargetPrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByCRN object from a json dictionary."""
        args = {}
        if (crn := _dict.get('crn')) is not None:
            args['crn'] = crn
        else:
            raise ValueError('Required property \'crn\' not present in ReservedIPTargetPrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByCRN JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ReservedIPTargetPrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByCRN object from 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 ReservedIPTargetPrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByCRN object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ReservedIPTargetPrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByCRN') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ReservedIPTargetPrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByCRN') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class ReservedIPTargetPrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByHref(ReservedIPTargetPrototypeVirtualNetworkInterfaceIdentity):
    """
    ReservedIPTargetPrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByHref.

    :param str href: The URL for this virtual network interface.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a ReservedIPTargetPrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByHref object.

        :param str href: The URL for this virtual network interface.
        """
        # pylint: disable=super-init-not-called
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ReservedIPTargetPrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByHref':
        """Initialize a ReservedIPTargetPrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByHref object from a json dictionary."""
        args = {}
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in ReservedIPTargetPrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByHref JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ReservedIPTargetPrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByHref object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this ReservedIPTargetPrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ReservedIPTargetPrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByHref') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ReservedIPTargetPrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByHref') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class ReservedIPTargetPrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityById(ReservedIPTargetPrototypeVirtualNetworkInterfaceIdentity):
    """
    ReservedIPTargetPrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityById.

    :param str id: The unique identifier for this virtual network interface.
    """

    def __init__(
        self,
        id: str,
    ) -> None:
        """
        Initialize a ReservedIPTargetPrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityById object.

        :param str id: The unique identifier for this virtual network interface.
        """
        # pylint: disable=super-init-not-called
        self.id = id

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ReservedIPTargetPrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityById':
        """Initialize a ReservedIPTargetPrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityById object from a json dictionary."""
        args = {}
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in ReservedIPTargetPrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityById JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ReservedIPTargetPrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityById object from 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 ReservedIPTargetPrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityById object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ReservedIPTargetPrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityById') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ReservedIPTargetPrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityById') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class RouteNextHopPatchRouteNextHopIPRouteNextHopIPSentinelIP(RouteNextHopPatchRouteNextHopIP):
    """
    RouteNextHopPatchRouteNextHopIPRouteNextHopIPSentinelIP.

    :param str address: The sentinel IP address (`0.0.0.0`).
          This property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) to support
          IPv6 addresses in the future.
    """

    def __init__(
        self,
        address: str,
    ) -> None:
        """
        Initialize a RouteNextHopPatchRouteNextHopIPRouteNextHopIPSentinelIP object.

        :param str address: The sentinel IP address (`0.0.0.0`).
               This property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) to
               support IPv6 addresses in the future.
        """
        # 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 := _dict.get('address')) is not None:
            args['address'] = 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.

    :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
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) to support
          IPv6 addresses in the future.
    """

    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
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) to
               support IPv6 addresses in the future.
        """
        # 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 := _dict.get('address')) is not None:
            args['address'] = 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.

    :param str href: The URL for this VPN gateway connection.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a RouteNextHopPatchVPNGatewayConnectionIdentityVPNGatewayConnectionIdentityByHref object.

        :param str href: The URL for this VPN gateway connection.
        """
        # 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 := _dict.get('href')) is not None:
            args['href'] = 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.

    :param 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 := _dict.get('id')) is not None:
            args['id'] = 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 RouteNextHopPrototypeRouteNextHopIPRouteNextHopIPSentinelIP(RouteNextHopPrototypeRouteNextHopIP):
    """
    RouteNextHopPrototypeRouteNextHopIPRouteNextHopIPSentinelIP.

    :param str address: The sentinel IP address (`0.0.0.0`).
          This property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) to support
          IPv6 addresses in the future.
    """

    def __init__(
        self,
        address: str,
    ) -> None:
        """
        Initialize a RouteNextHopPrototypeRouteNextHopIPRouteNextHopIPSentinelIP object.

        :param str address: The sentinel IP address (`0.0.0.0`).
               This property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) to
               support IPv6 addresses in the future.
        """
        # pylint: disable=super-init-not-called
        self.address = address

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'RouteNextHopPrototypeRouteNextHopIPRouteNextHopIPSentinelIP':
        """Initialize a RouteNextHopPrototypeRouteNextHopIPRouteNextHopIPSentinelIP object from a json dictionary."""
        args = {}
        if (address := _dict.get('address')) is not None:
            args['address'] = address
        else:
            raise ValueError('Required property \'address\' not present in RouteNextHopPrototypeRouteNextHopIPRouteNextHopIPSentinelIP JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a RouteNextHopPrototypeRouteNextHopIPRouteNextHopIPSentinelIP object from 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 RouteNextHopPrototypeRouteNextHopIPRouteNextHopIPSentinelIP object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'RouteNextHopPrototypeRouteNextHopIPRouteNextHopIPSentinelIP') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'RouteNextHopPrototypeRouteNextHopIPRouteNextHopIPSentinelIP') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class RouteNextHopPrototypeRouteNextHopIPRouteNextHopIPUnicastIP(RouteNextHopPrototypeRouteNextHopIP):
    """
    RouteNextHopPrototypeRouteNextHopIPRouteNextHopIPUnicastIP.

    :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
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) to support
          IPv6 addresses in the future.
    """

    def __init__(
        self,
        address: str,
    ) -> None:
        """
        Initialize a RouteNextHopPrototypeRouteNextHopIPRouteNextHopIPUnicastIP 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
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) to
               support IPv6 addresses in the future.
        """
        # pylint: disable=super-init-not-called
        self.address = address

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'RouteNextHopPrototypeRouteNextHopIPRouteNextHopIPUnicastIP':
        """Initialize a RouteNextHopPrototypeRouteNextHopIPRouteNextHopIPUnicastIP object from a json dictionary."""
        args = {}
        if (address := _dict.get('address')) is not None:
            args['address'] = address
        else:
            raise ValueError('Required property \'address\' not present in RouteNextHopPrototypeRouteNextHopIPRouteNextHopIPUnicastIP JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a RouteNextHopPrototypeRouteNextHopIPRouteNextHopIPUnicastIP object from 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 RouteNextHopPrototypeRouteNextHopIPRouteNextHopIPUnicastIP object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'RouteNextHopPrototypeRouteNextHopIPRouteNextHopIPUnicastIP') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'RouteNextHopPrototypeRouteNextHopIPRouteNextHopIPUnicastIP') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class RouteNextHopPrototypeVPNGatewayConnectionIdentityVPNGatewayConnectionIdentityByHref(RouteNextHopPrototypeVPNGatewayConnectionIdentity):
    """
    RouteNextHopPrototypeVPNGatewayConnectionIdentityVPNGatewayConnectionIdentityByHref.

    :param str href: The URL for this VPN gateway connection.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a RouteNextHopPrototypeVPNGatewayConnectionIdentityVPNGatewayConnectionIdentityByHref object.

        :param str href: The URL for this VPN gateway connection.
        """
        # pylint: disable=super-init-not-called
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'RouteNextHopPrototypeVPNGatewayConnectionIdentityVPNGatewayConnectionIdentityByHref':
        """Initialize a RouteNextHopPrototypeVPNGatewayConnectionIdentityVPNGatewayConnectionIdentityByHref object from a json dictionary."""
        args = {}
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in RouteNextHopPrototypeVPNGatewayConnectionIdentityVPNGatewayConnectionIdentityByHref JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a RouteNextHopPrototypeVPNGatewayConnectionIdentityVPNGatewayConnectionIdentityByHref object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this RouteNextHopPrototypeVPNGatewayConnectionIdentityVPNGatewayConnectionIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'RouteNextHopPrototypeVPNGatewayConnectionIdentityVPNGatewayConnectionIdentityByHref') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'RouteNextHopPrototypeVPNGatewayConnectionIdentityVPNGatewayConnectionIdentityByHref') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class RouteNextHopPrototypeVPNGatewayConnectionIdentityVPNGatewayConnectionIdentityById(RouteNextHopPrototypeVPNGatewayConnectionIdentity):
    """
    RouteNextHopPrototypeVPNGatewayConnectionIdentityVPNGatewayConnectionIdentityById.

    :param str id: The unique identifier for this VPN gateway connection.
    """

    def __init__(
        self,
        id: str,
    ) -> None:
        """
        Initialize a RouteNextHopPrototypeVPNGatewayConnectionIdentityVPNGatewayConnectionIdentityById object.

        :param str id: The unique identifier for this VPN gateway connection.
        """
        # pylint: disable=super-init-not-called
        self.id = id

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'RouteNextHopPrototypeVPNGatewayConnectionIdentityVPNGatewayConnectionIdentityById':
        """Initialize a RouteNextHopPrototypeVPNGatewayConnectionIdentityVPNGatewayConnectionIdentityById object from a json dictionary."""
        args = {}
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in RouteNextHopPrototypeVPNGatewayConnectionIdentityVPNGatewayConnectionIdentityById JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a RouteNextHopPrototypeVPNGatewayConnectionIdentityVPNGatewayConnectionIdentityById object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this RouteNextHopPrototypeVPNGatewayConnectionIdentityVPNGatewayConnectionIdentityById object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'RouteNextHopPrototypeVPNGatewayConnectionIdentityVPNGatewayConnectionIdentityById') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'RouteNextHopPrototypeVPNGatewayConnectionIdentityVPNGatewayConnectionIdentityById') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class SecurityGroupRuleRemotePatchSecurityGroupIdentitySecurityGroupIdentityByCRN(SecurityGroupRuleRemotePatchSecurityGroupIdentity):
    """
    SecurityGroupRuleRemotePatchSecurityGroupIdentitySecurityGroupIdentityByCRN.

    :param str crn: The CRN for this security group.
    """

    def __init__(
        self,
        crn: str,
    ) -> None:
        """
        Initialize a SecurityGroupRuleRemotePatchSecurityGroupIdentitySecurityGroupIdentityByCRN object.

        :param str crn: The CRN for this security group.
        """
        # 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 := _dict.get('crn')) is not None:
            args['crn'] = 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.

    :param str href: The URL for this security group.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a SecurityGroupRuleRemotePatchSecurityGroupIdentitySecurityGroupIdentityByHref object.

        :param str href: The URL for this security group.
        """
        # 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 := _dict.get('href')) is not None:
            args['href'] = 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.

    :param 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 := _dict.get('id')) is not None:
            args['id'] = 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.

    :param str crn: The CRN for this security group.
    """

    def __init__(
        self,
        crn: str,
    ) -> None:
        """
        Initialize a SecurityGroupRuleRemotePrototypeSecurityGroupIdentitySecurityGroupIdentityByCRN object.

        :param str crn: The CRN for this security group.
        """
        # 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 := _dict.get('crn')) is not None:
            args['crn'] = 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.

    :param str href: The URL for this security group.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a SecurityGroupRuleRemotePrototypeSecurityGroupIdentitySecurityGroupIdentityByHref object.

        :param str href: The URL for this security group.
        """
        # 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 := _dict.get('href')) is not None:
            args['href'] = 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.

    :param 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 := _dict.get('id')) is not None:
            args['id'] = 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 ShareMountTargetVirtualNetworkInterfacePrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByCRN(ShareMountTargetVirtualNetworkInterfacePrototypeVirtualNetworkInterfaceIdentity):
    """
    ShareMountTargetVirtualNetworkInterfacePrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByCRN.

    :param str crn: The CRN for this virtual network interface.
    """

    def __init__(
        self,
        crn: str,
    ) -> None:
        """
        Initialize a ShareMountTargetVirtualNetworkInterfacePrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByCRN object.

        :param str crn: The CRN for this virtual network interface.
        """
        # pylint: disable=super-init-not-called
        self.crn = crn

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ShareMountTargetVirtualNetworkInterfacePrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByCRN':
        """Initialize a ShareMountTargetVirtualNetworkInterfacePrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByCRN object from a json dictionary."""
        args = {}
        if (crn := _dict.get('crn')) is not None:
            args['crn'] = crn
        else:
            raise ValueError('Required property \'crn\' not present in ShareMountTargetVirtualNetworkInterfacePrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByCRN JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ShareMountTargetVirtualNetworkInterfacePrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByCRN object from 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 ShareMountTargetVirtualNetworkInterfacePrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByCRN object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ShareMountTargetVirtualNetworkInterfacePrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByCRN') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ShareMountTargetVirtualNetworkInterfacePrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByCRN') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class ShareMountTargetVirtualNetworkInterfacePrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByHref(ShareMountTargetVirtualNetworkInterfacePrototypeVirtualNetworkInterfaceIdentity):
    """
    ShareMountTargetVirtualNetworkInterfacePrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByHref.

    :param str href: The URL for this virtual network interface.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a ShareMountTargetVirtualNetworkInterfacePrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByHref object.

        :param str href: The URL for this virtual network interface.
        """
        # pylint: disable=super-init-not-called
        self.href = href

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ShareMountTargetVirtualNetworkInterfacePrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByHref':
        """Initialize a ShareMountTargetVirtualNetworkInterfacePrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByHref object from a json dictionary."""
        args = {}
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in ShareMountTargetVirtualNetworkInterfacePrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByHref JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ShareMountTargetVirtualNetworkInterfacePrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByHref object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this ShareMountTargetVirtualNetworkInterfacePrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ShareMountTargetVirtualNetworkInterfacePrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByHref') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ShareMountTargetVirtualNetworkInterfacePrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityByHref') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class ShareMountTargetVirtualNetworkInterfacePrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityById(ShareMountTargetVirtualNetworkInterfacePrototypeVirtualNetworkInterfaceIdentity):
    """
    ShareMountTargetVirtualNetworkInterfacePrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityById.

    :param str id: The unique identifier for this virtual network interface.
    """

    def __init__(
        self,
        id: str,
    ) -> None:
        """
        Initialize a ShareMountTargetVirtualNetworkInterfacePrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityById object.

        :param str id: The unique identifier for this virtual network interface.
        """
        # pylint: disable=super-init-not-called
        self.id = id

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ShareMountTargetVirtualNetworkInterfacePrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityById':
        """Initialize a ShareMountTargetVirtualNetworkInterfacePrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityById object from a json dictionary."""
        args = {}
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in ShareMountTargetVirtualNetworkInterfacePrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityById JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a ShareMountTargetVirtualNetworkInterfacePrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityById object from 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 ShareMountTargetVirtualNetworkInterfacePrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityById object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'ShareMountTargetVirtualNetworkInterfacePrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityById') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'ShareMountTargetVirtualNetworkInterfacePrototypeVirtualNetworkInterfaceIdentityVirtualNetworkInterfaceIdentityById') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VPNGatewayConnectionPeerPatchVPNGatewayConnectionPolicyModePeerPatchVPNGatewayConnectionPolicyModePeerPatchVPNGatewayConnectionPeerAddressPatch(VPNGatewayConnectionPeerPatchVPNGatewayConnectionPolicyModePeerPatch):
    """
    VPNGatewayConnectionPeerPatchVPNGatewayConnectionPolicyModePeerPatchVPNGatewayConnectionPolicyModePeerPatchVPNGatewayConnectionPeerAddressPatch.

    :param str address: (optional) The IP address of the peer VPN gateway for this
          connection.
    """

    def __init__(
        self,
        *,
        address: Optional[str] = None,
    ) -> None:
        """
        Initialize a VPNGatewayConnectionPeerPatchVPNGatewayConnectionPolicyModePeerPatchVPNGatewayConnectionPolicyModePeerPatchVPNGatewayConnectionPeerAddressPatch object.

        :param str address: (optional) The IP address of the peer VPN gateway for
               this connection.
        """
        # pylint: disable=super-init-not-called
        self.address = address

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPNGatewayConnectionPeerPatchVPNGatewayConnectionPolicyModePeerPatchVPNGatewayConnectionPolicyModePeerPatchVPNGatewayConnectionPeerAddressPatch':
        """Initialize a VPNGatewayConnectionPeerPatchVPNGatewayConnectionPolicyModePeerPatchVPNGatewayConnectionPolicyModePeerPatchVPNGatewayConnectionPeerAddressPatch object from a json dictionary."""
        args = {}
        if (address := _dict.get('address')) is not None:
            args['address'] = address
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPNGatewayConnectionPeerPatchVPNGatewayConnectionPolicyModePeerPatchVPNGatewayConnectionPolicyModePeerPatchVPNGatewayConnectionPeerAddressPatch object from 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 VPNGatewayConnectionPeerPatchVPNGatewayConnectionPolicyModePeerPatchVPNGatewayConnectionPolicyModePeerPatchVPNGatewayConnectionPeerAddressPatch object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPNGatewayConnectionPeerPatchVPNGatewayConnectionPolicyModePeerPatchVPNGatewayConnectionPolicyModePeerPatchVPNGatewayConnectionPeerAddressPatch') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPNGatewayConnectionPeerPatchVPNGatewayConnectionPolicyModePeerPatchVPNGatewayConnectionPolicyModePeerPatchVPNGatewayConnectionPeerAddressPatch') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VPNGatewayConnectionPeerPatchVPNGatewayConnectionPolicyModePeerPatchVPNGatewayConnectionPolicyModePeerPatchVPNGatewayConnectionPeerFQDNPatch(VPNGatewayConnectionPeerPatchVPNGatewayConnectionPolicyModePeerPatch):
    """
    VPNGatewayConnectionPeerPatchVPNGatewayConnectionPolicyModePeerPatchVPNGatewayConnectionPolicyModePeerPatchVPNGatewayConnectionPeerFQDNPatch.

    :param str fqdn: (optional) The FQDN of the peer VPN gateway for this
          connection.
    """

    def __init__(
        self,
        *,
        fqdn: Optional[str] = None,
    ) -> None:
        """
        Initialize a VPNGatewayConnectionPeerPatchVPNGatewayConnectionPolicyModePeerPatchVPNGatewayConnectionPolicyModePeerPatchVPNGatewayConnectionPeerFQDNPatch object.

        :param str fqdn: (optional) The FQDN of the peer VPN gateway for this
               connection.
        """
        # pylint: disable=super-init-not-called
        self.fqdn = fqdn

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPNGatewayConnectionPeerPatchVPNGatewayConnectionPolicyModePeerPatchVPNGatewayConnectionPolicyModePeerPatchVPNGatewayConnectionPeerFQDNPatch':
        """Initialize a VPNGatewayConnectionPeerPatchVPNGatewayConnectionPolicyModePeerPatchVPNGatewayConnectionPolicyModePeerPatchVPNGatewayConnectionPeerFQDNPatch object from a json dictionary."""
        args = {}
        if (fqdn := _dict.get('fqdn')) is not None:
            args['fqdn'] = fqdn
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPNGatewayConnectionPeerPatchVPNGatewayConnectionPolicyModePeerPatchVPNGatewayConnectionPolicyModePeerPatchVPNGatewayConnectionPeerFQDNPatch object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'fqdn') and self.fqdn is not None:
            _dict['fqdn'] = self.fqdn
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VPNGatewayConnectionPeerPatchVPNGatewayConnectionPolicyModePeerPatchVPNGatewayConnectionPolicyModePeerPatchVPNGatewayConnectionPeerFQDNPatch object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPNGatewayConnectionPeerPatchVPNGatewayConnectionPolicyModePeerPatchVPNGatewayConnectionPolicyModePeerPatchVPNGatewayConnectionPeerFQDNPatch') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPNGatewayConnectionPeerPatchVPNGatewayConnectionPolicyModePeerPatchVPNGatewayConnectionPolicyModePeerPatchVPNGatewayConnectionPeerFQDNPatch') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VPNGatewayConnectionPeerPatchVPNGatewayConnectionStaticRouteModePeerPatchVPNGatewayConnectionStaticRouteModePeerPatchVPNGatewayConnectionPeerAddressPatch(VPNGatewayConnectionPeerPatchVPNGatewayConnectionStaticRouteModePeerPatch):
    """
    VPNGatewayConnectionPeerPatchVPNGatewayConnectionStaticRouteModePeerPatchVPNGatewayConnectionStaticRouteModePeerPatchVPNGatewayConnectionPeerAddressPatch.

    :param str address: (optional) The IP address of the peer VPN gateway for this
          connection.
    """

    def __init__(
        self,
        *,
        address: Optional[str] = None,
    ) -> None:
        """
        Initialize a VPNGatewayConnectionPeerPatchVPNGatewayConnectionStaticRouteModePeerPatchVPNGatewayConnectionStaticRouteModePeerPatchVPNGatewayConnectionPeerAddressPatch object.

        :param str address: (optional) The IP address of the peer VPN gateway for
               this connection.
        """
        # pylint: disable=super-init-not-called
        self.address = address

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPNGatewayConnectionPeerPatchVPNGatewayConnectionStaticRouteModePeerPatchVPNGatewayConnectionStaticRouteModePeerPatchVPNGatewayConnectionPeerAddressPatch':
        """Initialize a VPNGatewayConnectionPeerPatchVPNGatewayConnectionStaticRouteModePeerPatchVPNGatewayConnectionStaticRouteModePeerPatchVPNGatewayConnectionPeerAddressPatch object from a json dictionary."""
        args = {}
        if (address := _dict.get('address')) is not None:
            args['address'] = address
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPNGatewayConnectionPeerPatchVPNGatewayConnectionStaticRouteModePeerPatchVPNGatewayConnectionStaticRouteModePeerPatchVPNGatewayConnectionPeerAddressPatch object from 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 VPNGatewayConnectionPeerPatchVPNGatewayConnectionStaticRouteModePeerPatchVPNGatewayConnectionStaticRouteModePeerPatchVPNGatewayConnectionPeerAddressPatch object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPNGatewayConnectionPeerPatchVPNGatewayConnectionStaticRouteModePeerPatchVPNGatewayConnectionStaticRouteModePeerPatchVPNGatewayConnectionPeerAddressPatch') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPNGatewayConnectionPeerPatchVPNGatewayConnectionStaticRouteModePeerPatchVPNGatewayConnectionStaticRouteModePeerPatchVPNGatewayConnectionPeerAddressPatch') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VPNGatewayConnectionPeerPatchVPNGatewayConnectionStaticRouteModePeerPatchVPNGatewayConnectionStaticRouteModePeerPatchVPNGatewayConnectionPeerFQDNPatch(VPNGatewayConnectionPeerPatchVPNGatewayConnectionStaticRouteModePeerPatch):
    """
    VPNGatewayConnectionPeerPatchVPNGatewayConnectionStaticRouteModePeerPatchVPNGatewayConnectionStaticRouteModePeerPatchVPNGatewayConnectionPeerFQDNPatch.

    :param str fqdn: (optional) The FQDN of the peer VPN gateway for this
          connection.
    """

    def __init__(
        self,
        *,
        fqdn: Optional[str] = None,
    ) -> None:
        """
        Initialize a VPNGatewayConnectionPeerPatchVPNGatewayConnectionStaticRouteModePeerPatchVPNGatewayConnectionStaticRouteModePeerPatchVPNGatewayConnectionPeerFQDNPatch object.

        :param str fqdn: (optional) The FQDN of the peer VPN gateway for this
               connection.
        """
        # pylint: disable=super-init-not-called
        self.fqdn = fqdn

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPNGatewayConnectionPeerPatchVPNGatewayConnectionStaticRouteModePeerPatchVPNGatewayConnectionStaticRouteModePeerPatchVPNGatewayConnectionPeerFQDNPatch':
        """Initialize a VPNGatewayConnectionPeerPatchVPNGatewayConnectionStaticRouteModePeerPatchVPNGatewayConnectionStaticRouteModePeerPatchVPNGatewayConnectionPeerFQDNPatch object from a json dictionary."""
        args = {}
        if (fqdn := _dict.get('fqdn')) is not None:
            args['fqdn'] = fqdn
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPNGatewayConnectionPeerPatchVPNGatewayConnectionStaticRouteModePeerPatchVPNGatewayConnectionStaticRouteModePeerPatchVPNGatewayConnectionPeerFQDNPatch object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'fqdn') and self.fqdn is not None:
            _dict['fqdn'] = self.fqdn
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VPNGatewayConnectionPeerPatchVPNGatewayConnectionStaticRouteModePeerPatchVPNGatewayConnectionStaticRouteModePeerPatchVPNGatewayConnectionPeerFQDNPatch object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPNGatewayConnectionPeerPatchVPNGatewayConnectionStaticRouteModePeerPatchVPNGatewayConnectionStaticRouteModePeerPatchVPNGatewayConnectionPeerFQDNPatch') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPNGatewayConnectionPeerPatchVPNGatewayConnectionStaticRouteModePeerPatchVPNGatewayConnectionStaticRouteModePeerPatchVPNGatewayConnectionPeerFQDNPatch') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VPNGatewayConnectionRouteModeVPNGatewayConnectionStaticRouteMode(VPNGatewayConnectionRouteMode):
    """
    VPNGatewayConnectionRouteModeVPNGatewayConnectionStaticRouteMode.

    :param bool admin_state_up: If set to false, the VPN gateway connection is shut
          down.
    :param str authentication_mode: The authentication mode.
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :param datetime created_at: The date and time that this VPN gateway connection
          was created.
    :param VPNGatewayConnectionDPD dead_peer_detection:
    :param str establish_mode: The establish mode of the VPN gateway connection:
          - `bidirectional`: Either side of the VPN gateway can initiate IKE protocol
             negotiations or rekeying processes.
          - `peer_only`: Only the peer can initiate IKE protocol negotiations for this VPN
          gateway
             connection. Additionally, the peer is responsible for initiating the rekeying
          process
             after the connection is established. If rekeying does not occur, the VPN
          gateway
             connection will be brought down after its lifetime expires.
    :param str href: The URL for this VPN gateway connection.
    :param str id: The unique identifier for this VPN gateway connection.
    :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).
    :param str mode: The mode of the VPN gateway.
          The enumerated values for this property may
          [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
          future.
    :param str name: The name for this VPN gateway connection. The name is unique
          across all connections for the 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).
    :param bool distribute_traffic: Indicates whether the traffic is distributed
          between the `up` tunnels of the VPN gateway connection when the VPC route's next
          hop is a VPN connection. If `false`, the traffic is only routed through the `up`
          tunnel with the lower `public_ip` address.
    :param VPNGatewayConnectionStaticRouteModeLocal local:
    :param VPNGatewayConnectionStaticRouteModePeer peer:
    :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).
    """

    def __init__(
        self,
        admin_state_up: bool,
        authentication_mode: str,
        created_at: datetime,
        dead_peer_detection: 'VPNGatewayConnectionDPD',
        establish_mode: str,
        href: str,
        id: str,
        mode: str,
        name: str,
        psk: str,
        resource_type: str,
        status: str,
        status_reasons: List['VPNGatewayConnectionStatusReason'],
        distribute_traffic: bool,
        local: 'VPNGatewayConnectionStaticRouteModeLocal',
        peer: 'VPNGatewayConnectionStaticRouteModePeer',
        routing_protocol: str,
        tunnels: List['VPNGatewayConnectionStaticRouteModeTunnel'],
        *,
        ike_policy: Optional['IKEPolicyReference'] = None,
        ipsec_policy: Optional['IPsecPolicyReference'] = None,
    ) -> None:
        """
        Initialize a VPNGatewayConnectionRouteModeVPNGatewayConnectionStaticRouteMode object.

        :param bool admin_state_up: If set to false, the VPN gateway connection is
               shut down.
        :param str authentication_mode: The authentication mode.
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :param datetime created_at: The date and time that this VPN gateway
               connection was created.
        :param VPNGatewayConnectionDPD dead_peer_detection:
        :param str establish_mode: The establish mode of the VPN gateway
               connection:
               - `bidirectional`: Either side of the VPN gateway can initiate IKE protocol
                  negotiations or rekeying processes.
               - `peer_only`: Only the peer can initiate IKE protocol negotiations for
               this VPN gateway
                  connection. Additionally, the peer is responsible for initiating the
               rekeying process
                  after the connection is established. If rekeying does not occur, the VPN
               gateway
                  connection will be brought down after its lifetime expires.
        :param str href: The URL for this VPN gateway connection.
        :param str id: The unique identifier for this VPN gateway connection.
        :param str mode: The mode of the VPN gateway.
               The enumerated values for this property may
               [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
               future.
        :param str name: The name for this VPN gateway connection. The name is
               unique across all connections for the 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).
        :param bool distribute_traffic: Indicates whether the traffic is
               distributed between the `up` tunnels of the VPN gateway connection when the
               VPC route's next hop is a VPN connection. If `false`, the traffic is only
               routed through the `up` tunnel with the lower `public_ip` address.
        :param VPNGatewayConnectionStaticRouteModeLocal local:
        :param VPNGatewayConnectionStaticRouteModePeer peer:
        :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.establish_mode = establish_mode
        self.href = href
        self.id = id
        self.ike_policy = ike_policy
        self.ipsec_policy = ipsec_policy
        self.mode = mode
        self.name = name
        self.psk = psk
        self.resource_type = resource_type
        self.status = status
        self.status_reasons = status_reasons
        self.distribute_traffic = distribute_traffic
        self.local = local
        self.peer = peer
        self.routing_protocol = routing_protocol
        self.tunnels = tunnels

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'VPNGatewayConnectionRouteModeVPNGatewayConnectionStaticRouteMode':
        """Initialize a VPNGatewayConnectionRouteModeVPNGatewayConnectionStaticRouteMode object from a json dictionary."""
        args = {}
        if (admin_state_up := _dict.get('admin_state_up')) is not None:
            args['admin_state_up'] = admin_state_up
        else:
            raise ValueError('Required property \'admin_state_up\' not present in VPNGatewayConnectionRouteModeVPNGatewayConnectionStaticRouteMode JSON')
        if (authentication_mode := _dict.get('authentication_mode')) is not None:
            args['authentication_mode'] = authentication_mode
        else:
            raise ValueError('Required property \'authentication_mode\' not present in VPNGatewayConnectionRouteModeVPNGatewayConnectionStaticRouteMode JSON')
        if (created_at := _dict.get('created_at')) is not None:
            args['created_at'] = string_to_datetime(created_at)
        else:
            raise ValueError('Required property \'created_at\' not present in VPNGatewayConnectionRouteModeVPNGatewayConnectionStaticRouteMode JSON')
        if (dead_peer_detection := _dict.get('dead_peer_detection')) is not None:
            args['dead_peer_detection'] = VPNGatewayConnectionDPD.from_dict(dead_peer_detection)
        else:
            raise ValueError('Required property \'dead_peer_detection\' not present in VPNGatewayConnectionRouteModeVPNGatewayConnectionStaticRouteMode JSON')
        if (establish_mode := _dict.get('establish_mode')) is not None:
            args['establish_mode'] = establish_mode
        else:
            raise ValueError('Required property \'establish_mode\' not present in VPNGatewayConnectionRouteModeVPNGatewayConnectionStaticRouteMode JSON')
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in VPNGatewayConnectionRouteModeVPNGatewayConnectionStaticRouteMode JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in VPNGatewayConnectionRouteModeVPNGatewayConnectionStaticRouteMode JSON')
        if (ike_policy := _dict.get('ike_policy')) is not None:
            args['ike_policy'] = IKEPolicyReference.from_dict(ike_policy)
        if (ipsec_policy := _dict.get('ipsec_policy')) is not None:
            args['ipsec_policy'] = IPsecPolicyReference.from_dict(ipsec_policy)
        if (mode := _dict.get('mode')) is not None:
            args['mode'] = mode
        else:
            raise ValueError('Required property \'mode\' not present in VPNGatewayConnectionRouteModeVPNGatewayConnectionStaticRouteMode JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in VPNGatewayConnectionRouteModeVPNGatewayConnectionStaticRouteMode JSON')
        if (psk := _dict.get('psk')) is not None:
            args['psk'] = psk
        else:
            raise ValueError('Required property \'psk\' not present in VPNGatewayConnectionRouteModeVPNGatewayConnectionStaticRouteMode JSON')
        if (resource_type := _dict.get('resource_type')) is not None:
            args['resource_type'] = resource_type
        else:
            raise ValueError('Required property \'resource_type\' not present in VPNGatewayConnectionRouteModeVPNGatewayConnectionStaticRouteMode JSON')
        if (status := _dict.get('status')) is not None:
            args['status'] = status
        else:
            raise ValueError('Required property \'status\' not present in VPNGatewayConnectionRouteModeVPNGatewayConnectionStaticRouteMode JSON')
        if (status_reasons := _dict.get('status_reasons')) is not None:
            args['status_reasons'] = [VPNGatewayConnectionStatusReason.from_dict(v) for v in status_reasons]
        else:
            raise ValueError('Required property \'status_reasons\' not present in VPNGatewayConnectionRouteModeVPNGatewayConnectionStaticRouteMode JSON')
        if (distribute_traffic := _dict.get('distribute_traffic')) is not None:
            args['distribute_traffic'] = distribute_traffic
        else:
            raise ValueError('Required property \'distribute_traffic\' not present in VPNGatewayConnectionRouteModeVPNGatewayConnectionStaticRouteMode JSON')
        if (local := _dict.get('local')) is not None:
            args['local'] = VPNGatewayConnectionStaticRouteModeLocal.from_dict(local)
        else:
            raise ValueError('Required property \'local\' not present in VPNGatewayConnectionRouteModeVPNGatewayConnectionStaticRouteMode JSON')
        if (peer := _dict.get('peer')) is not None:
            args['peer'] = peer
        else:
            raise ValueError('Required property \'peer\' not present in VPNGatewayConnectionRouteModeVPNGatewayConnectionStaticRouteMode JSON')
        if (routing_protocol := _dict.get('routing_protocol')) is not None:
            args['routing_protocol'] = routing_protocol
        else:
            raise ValueError('Required property \'routing_protocol\' not present in VPNGatewayConnectionRouteModeVPNGatewayConnectionStaticRouteMode JSON')
        if (tunnels := _dict.get('tunnels')) is not None:
            args['tunnels'] = [VPNGatewayConnectionStaticRouteModeTunnel.from_dict(v) for v in tunnels]
        else:
            raise ValueError('Required property \'tunnels\' not present in VPNGatewayConnectionRouteModeVPNGatewayConnectionStaticRouteMode JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VPNGatewayConnectionRouteModeVPNGatewayConnectionStaticRouteMode object from 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, 'establish_mode') and self.establish_mode is not None:
            _dict['establish_mode'] = self.establish_mode
        if hasattr(self, 'href') and self.href 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, '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, 'distribute_traffic') and self.distribute_traffic is not None:
            _dict['distribute_traffic'] = self.distribute_traffic
        if hasattr(self, 'local') and self.local is not None:
            if isinstance(self.local, dict):
                _dict['local'] = self.local
            else:
                _dict['local'] = self.local.to_dict()
        if hasattr(self, 'peer') and self.peer is not None:
            if isinstance(self.peer, dict):
                _dict['peer'] = self.peer
            else:
                _dict['peer'] = self.peer.to_dict()
        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 VPNGatewayConnectionRouteModeVPNGatewayConnectionStaticRouteMode object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VPNGatewayConnectionRouteModeVPNGatewayConnectionStaticRouteMode') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VPNGatewayConnectionRouteModeVPNGatewayConnectionStaticRouteMode') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other

    class AuthenticationModeEnum(str, Enum):
        """
        The authentication mode.
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        PSK = 'psk'


    class EstablishModeEnum(str, Enum):
        """
        The establish mode of the VPN gateway connection:
        - `bidirectional`: Either side of the VPN gateway can initiate IKE protocol
           negotiations or rekeying processes.
        - `peer_only`: Only the peer can initiate IKE protocol negotiations for this VPN
        gateway
           connection. Additionally, the peer is responsible for initiating the rekeying
        process
           after the connection is established. If rekeying does not occur, the VPN
        gateway
           connection will be brought down after its lifetime expires.
        """

        BIDIRECTIONAL = 'bidirectional'
        PEER_ONLY = 'peer_only'


    class ModeEnum(str, Enum):
        """
        The mode of the VPN gateway.
        The enumerated values for this property may
        [expand](https://cloud.ibm.com/apidocs/vpc#property-value-expansion) in the
        future.
        """

        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 VirtualNetworkInterfaceIPPrototypeReservedIPIdentityVirtualNetworkInterfaceIPsContextByHref(VirtualNetworkInterfaceIPPrototypeReservedIPIdentityVirtualNetworkInterfaceIPsContext):
    """
    VirtualNetworkInterfaceIPPrototypeReservedIPIdentityVirtualNetworkInterfaceIPsContextByHref.

    :param str href: The URL for this reserved IP.
    """

    def __init__(
        self,
        href: str,
    ) -> None:
        """
        Initialize a VirtualNetworkInterfaceIPPrototypeReservedIPIdentityVirtualNetworkInterfaceIPsContextByHref 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) -> 'VirtualNetworkInterfaceIPPrototypeReservedIPIdentityVirtualNetworkInterfaceIPsContextByHref':
        """Initialize a VirtualNetworkInterfaceIPPrototypeReservedIPIdentityVirtualNetworkInterfaceIPsContextByHref object from a json dictionary."""
        args = {}
        if (href := _dict.get('href')) is not None:
            args['href'] = href
        else:
            raise ValueError('Required property \'href\' not present in VirtualNetworkInterfaceIPPrototypeReservedIPIdentityVirtualNetworkInterfaceIPsContextByHref JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VirtualNetworkInterfaceIPPrototypeReservedIPIdentityVirtualNetworkInterfaceIPsContextByHref object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'href') and self.href is not None:
            _dict['href'] = self.href
        return _dict

    def _to_dict(self):
        """Return a json dictionary representing this model."""
        return self.to_dict()

    def __str__(self) -> str:
        """Return a `str` version of this VirtualNetworkInterfaceIPPrototypeReservedIPIdentityVirtualNetworkInterfaceIPsContextByHref object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VirtualNetworkInterfaceIPPrototypeReservedIPIdentityVirtualNetworkInterfaceIPsContextByHref') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VirtualNetworkInterfaceIPPrototypeReservedIPIdentityVirtualNetworkInterfaceIPsContextByHref') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VirtualNetworkInterfaceIPPrototypeReservedIPIdentityVirtualNetworkInterfaceIPsContextById(VirtualNetworkInterfaceIPPrototypeReservedIPIdentityVirtualNetworkInterfaceIPsContext):
    """
    VirtualNetworkInterfaceIPPrototypeReservedIPIdentityVirtualNetworkInterfaceIPsContextById.

    :param str id: The unique identifier for this reserved IP.
    """

    def __init__(
        self,
        id: str,
    ) -> None:
        """
        Initialize a VirtualNetworkInterfaceIPPrototypeReservedIPIdentityVirtualNetworkInterfaceIPsContextById 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) -> 'VirtualNetworkInterfaceIPPrototypeReservedIPIdentityVirtualNetworkInterfaceIPsContextById':
        """Initialize a VirtualNetworkInterfaceIPPrototypeReservedIPIdentityVirtualNetworkInterfaceIPsContextById object from a json dictionary."""
        args = {}
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in VirtualNetworkInterfaceIPPrototypeReservedIPIdentityVirtualNetworkInterfaceIPsContextById JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a VirtualNetworkInterfaceIPPrototypeReservedIPIdentityVirtualNetworkInterfaceIPsContextById object from 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 VirtualNetworkInterfaceIPPrototypeReservedIPIdentityVirtualNetworkInterfaceIPsContextById object."""
        return json.dumps(self.to_dict(), indent=2)

    def __eq__(self, other: 'VirtualNetworkInterfaceIPPrototypeReservedIPIdentityVirtualNetworkInterfaceIPsContextById') -> bool:
        """Return `true` when self and other are equal, false otherwise."""
        if not isinstance(other, self.__class__):
            return False
        return self.__dict__ == other.__dict__

    def __ne__(self, other: 'VirtualNetworkInterfaceIPPrototypeReservedIPIdentityVirtualNetworkInterfaceIPsContextById') -> bool:
        """Return `true` when self and other are not equal, false otherwise."""
        return not self == other


class VirtualNetworkInterfacePrimaryIPPrototypeReservedIPIdentityVirtualNetworkInterfacePrimaryIPContextByHref(VirtualNetworkInterfacePrimaryIPPrototypeReservedIPIdentityVirtualNetworkInterfacePrimaryIPContext):
    """
    VirtualNetworkInterfacePrimaryIPPrototypeReservedIPIdentityVirtualNetworkInterfacePrimaryIPContextByHref.

    :param 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 := _dict.get('href')) is not None:
            args['href'] = 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.

    :param 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 := _dict.get('id')) is not None:
            args['id'] = 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.

    :param 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 := _dict.get('crn')) is not None:
            args['crn'] = 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.

    :param 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 := _dict.get('href')) is not None:
            args['href'] = 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.

    :param 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 := _dict.get('id')) is not None:
            args['id'] = 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.

    :param int iops: (optional) The maximum I/O operations per second (IOPS) to use
          for this volume. If specified, the `family` of the volume profile must be
          `custom` or `defined_performance`.
    :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 VolumeProfileIdentity profile: The
          [profile](https://cloud.ibm.com/docs/vpc?topic=vpc-block-storage-profiles) to
          use for this volume.
    :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: The capacity to use for the volume (in gigabytes). The
          specified value must be within the `capacity` range of the volume's profile.
    :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`.
    """

    def __init__(
        self,
        profile: 'VolumeProfileIdentity',
        capacity: int,
        *,
        iops: Optional[int] = None,
        name: Optional[str] = None,
        resource_group: Optional['ResourceGroupIdentity'] = None,
        user_tags: Optional[List[str]] = None,
        encryption_key: Optional['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 value must be within the `capacity` range of the volume's
               profile.
        :param int iops: (optional) The maximum I/O operations per second (IOPS) to
               use for this volume. If specified, the `family` of the volume profile must
               be `custom` or `defined_performance`.
        :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 := _dict.get('iops')) is not None:
            args['iops'] = iops
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        if (profile := _dict.get('profile')) is not None:
            args['profile'] = profile
        else:
            raise ValueError('Required property \'profile\' not present in VolumeAttachmentPrototypeVolumeVolumePrototypeInstanceContextVolumePrototypeInstanceContextVolumeByCapacity JSON')
        if (resource_group := _dict.get('resource_group')) is not None:
            args['resource_group'] = resource_group
        if (user_tags := _dict.get('user_tags')) is not None:
            args['user_tags'] = user_tags
        if (capacity := _dict.get('capacity')) is not None:
            args['capacity'] = capacity
        else:
            raise ValueError('Required property \'capacity\' not present in VolumeAttachmentPrototypeVolumeVolumePrototypeInstanceContextVolumePrototypeInstanceContextVolumeByCapacity JSON')
        if (encryption_key := _dict.get('encryption_key')) is not None:
            args['encryption_key'] = 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.

    :param int iops: (optional) The maximum I/O operations per second (IOPS) to use
          for this volume. If specified, the `family` of the volume profile must be
          `custom` or `defined_performance`.
    :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 VolumeProfileIdentity profile: The
          [profile](https://cloud.ibm.com/docs/vpc?topic=vpc-block-storage-profiles) to
          use for this volume.
    :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). The specified value must be at least the snapshot's
          `minimum_capacity`, and must be within the `capacity` range of the volume's
          profile.
          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 SnapshotIdentity source_snapshot: The snapshot to use as a source for the
          volume's data.
          The specified snapshot may be in a different account, subject to IAM policies.
    """

    def __init__(
        self,
        profile: 'VolumeProfileIdentity',
        source_snapshot: 'SnapshotIdentity',
        *,
        iops: Optional[int] = None,
        name: Optional[str] = None,
        resource_group: Optional['ResourceGroupIdentity'] = None,
        user_tags: Optional[List[str]] = None,
        capacity: Optional[int] = None,
        encryption_key: Optional['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 to use as a source
               for the volume's data.
               The specified snapshot may be in a different account, subject to IAM
               policies.
        :param int iops: (optional) The maximum I/O operations per second (IOPS) to
               use for this volume. If specified, the `family` of the volume profile must
               be `custom` or `defined_performance`.
        :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). The specified value must be at least the snapshot's
               `minimum_capacity`, and must be within the `capacity` range of the volume's
               profile.
               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 := _dict.get('iops')) is not None:
            args['iops'] = iops
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        if (profile := _dict.get('profile')) is not None:
            args['profile'] = profile
        else:
            raise ValueError('Required property \'profile\' not present in VolumeAttachmentPrototypeVolumeVolumePrototypeInstanceContextVolumePrototypeInstanceContextVolumeBySourceSnapshot JSON')
        if (resource_group := _dict.get('resource_group')) is not None:
            args['resource_group'] = resource_group
        if (user_tags := _dict.get('user_tags')) is not None:
            args['user_tags'] = user_tags
        if (capacity := _dict.get('capacity')) is not None:
            args['capacity'] = capacity
        if (encryption_key := _dict.get('encryption_key')) is not None:
            args['encryption_key'] = encryption_key
        if (source_snapshot := _dict.get('source_snapshot')) is not None:
            args['source_snapshot'] = 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.

    :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.
    :param InstanceGroupManagerScheduledActionGroupPrototype group:
    """

    def __init__(
        self,
        group: 'InstanceGroupManagerScheduledActionGroupPrototype',
        *,
        name: Optional[str] = None,
        cron_spec: Optional[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 := _dict.get('name')) is not None:
            args['name'] = name
        if (cron_spec := _dict.get('cron_spec')) is not None:
            args['cron_spec'] = cron_spec
        if (group := _dict.get('group')) is not None:
            args['group'] = InstanceGroupManagerScheduledActionGroupPrototype.from_dict(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.

    :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.
    :param InstanceGroupManagerScheduledActionManagerPrototype manager:
    """

    def __init__(
        self,
        manager: 'InstanceGroupManagerScheduledActionManagerPrototype',
        *,
        name: Optional[str] = None,
        cron_spec: Optional[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 := _dict.get('name')) is not None:
            args['name'] = name
        if (cron_spec := _dict.get('cron_spec')) is not None:
            args['cron_spec'] = cron_spec
        if (manager := _dict.get('manager')) is not None:
            args['manager'] = 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.

    :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.
    :param InstanceGroupManagerScheduledActionGroupPrototype group:
    """

    def __init__(
        self,
        group: 'InstanceGroupManagerScheduledActionGroupPrototype',
        *,
        name: Optional[str] = None,
        run_at: Optional[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 := _dict.get('name')) is not None:
            args['name'] = name
        if (run_at := _dict.get('run_at')) is not None:
            args['run_at'] = string_to_datetime(run_at)
        if (group := _dict.get('group')) is not None:
            args['group'] = InstanceGroupManagerScheduledActionGroupPrototype.from_dict(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.

    :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.
    :param InstanceGroupManagerScheduledActionManagerPrototype manager:
    """

    def __init__(
        self,
        manager: 'InstanceGroupManagerScheduledActionManagerPrototype',
        *,
        name: Optional[str] = None,
        run_at: Optional[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 := _dict.get('name')) is not None:
            args['name'] = name
        if (run_at := _dict.get('run_at')) is not None:
            args['run_at'] = string_to_datetime(run_at)
        if (manager := _dict.get('manager')) is not None:
            args['manager'] = 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 Route.
        :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 Route.
        :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,
        target_id: str = None,
        target_crn: str = None,
        target_name: str = None,
        target_resource_type: 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.
        :param str target_id: (optional) Filters the collection to resources with a
               `target.id` property matching the specified identifier.
        :param str target_crn: (optional) Filters the collection to resources with
               a `target.crn` property matching the specified CRN.
        :param str target_name: (optional) Filters the collection to resources with
               a `target.name` property matching the exact specified name.
        :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._subnet_id = subnet_id
        self._limit = limit
        self._sort = sort
        self._target_id = target_id
        self._target_crn = target_crn
        self._target_name = target_name
        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 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,
            target_id=self._target_id,
            target_crn=self._target_crn,
            target_name=self._target_name,
            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('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,
        user_data_format: List[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.
        :param List[str] user_data_format: (optional) Filters the collection to
               images with a `user_data_format` property matching one of the specified
               comma-separated values.
        """
        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
        self._user_data_format = user_data_format

    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,
            user_data_format=self._user_data_format,
            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,
        resource_group_id: str = None,
    ) -> None:
        """
        Initialize a KeysPager 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 Key.
        :rtype: List[dict]
        """
        if not self.has_next():
            raise StopIteration(message='No more results available')

        result = self._client.list_keys(
            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('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,
        cluster_network_id: str = None,
        cluster_network_crn: str = None,
        cluster_network_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,
        reservation_id: str = None,
        reservation_crn: str = None,
        reservation_name: str = None,
        vpc_id: str = None,
        vpc_crn: str = None,
        vpc_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 cluster_network_id: (optional) Filters the collection to
               instances with a `cluster_network.id` property matching the specified
               identifier.
        :param str cluster_network_crn: (optional) Filters the collection to
               instances with a `cluster_network.crn` property matching the specified CRN.
        :param str cluster_network_name: (optional) Filters the collection to
               resources with a `cluster_network.name` property matching the exact
               specified name.
        :param str dedicated_host_id: (optional) Filters the collection to
               resources with a `dedicated_host.id` property matching the specified
               identifier.
        :param str dedicated_host_crn: (optional) Filters the collection to
               resources with a `dedicated_host.crn` property matching the specified CRN.
        :param str dedicated_host_name: (optional) Filters the collection to
               resources with a `dedicated_host.name` property matching the exact
               specified name.
        :param str placement_group_id: (optional) Filters the collection to
               resources with a `placement_target.id` property matching the specified
               placement group identifier.
        :param str placement_group_crn: (optional) Filters the collection to
               resources with a `placement_target.crn` property matching the specified
               placement group CRN.
        :param str placement_group_name: (optional) Filters the collection to
               resources with a `placement_target.name` property matching the exact
               specified placement group name.
        :param str reservation_id: (optional) Filters the collection to resources
               with a `reservation.id` property matching the specified identifier.
        :param str reservation_crn: (optional) Filters the collection to resources
               with a `reservation.crn` property matching the specified identifier.
        :param str reservation_name: (optional) Filters the collection to resources
               with a `reservation.name` 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._name = name
        self._cluster_network_id = cluster_network_id
        self._cluster_network_crn = cluster_network_crn
        self._cluster_network_name = cluster_network_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
        self._reservation_id = reservation_id
        self._reservation_crn = reservation_crn
        self._reservation_name = reservation_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 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,
            cluster_network_id=self._cluster_network_id,
            cluster_network_crn=self._cluster_network_crn,
            cluster_network_name=self._cluster_network_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,
            reservation_id=self._reservation_id,
            reservation_crn=self._reservation_crn,
            reservation_name=self._reservation_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('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 InstanceClusterNetworkAttachmentsPager:
    """
    InstanceClusterNetworkAttachmentsPager can be used to simplify the use of the "list_instance_cluster_network_attachments" method.
    """

    def __init__(
        self,
        *,
        client: VpcV1,
        instance_id: str,
        limit: int = None,
    ) -> None:
        """
        Initialize a InstanceClusterNetworkAttachmentsPager object.
        :param str instance_id: The virtual server instance 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._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 InstanceClusterNetworkAttachment.
        :rtype: List[dict]
        """
        if not self.has_next():
            raise StopIteration(message='No more results available')

        result = self._client.list_instance_cluster_network_attachments(
            instance_id=self._instance_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('cluster_network_attachments')

    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 InstanceClusterNetworkAttachment.
        :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 ReservationsPager:
    """
    ReservationsPager can be used to simplify the use of the "list_reservations" method.
    """

    def __init__(
        self,
        *,
        client: VpcV1,
        limit: int = None,
        name: str = None,
        resource_group_id: str = None,
        zone_name: str = None,
    ) -> None:
        """
        Initialize a ReservationsPager 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 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.
        """
        self._has_next = True
        self._client = client
        self._page_context = {'next': None}
        self._limit = limit
        self._name = name
        self._resource_group_id = resource_group_id
        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 Reservation.
        :rtype: List[dict]
        """
        if not self.has_next():
            raise StopIteration(message='No more results available')

        result = self._client.list_reservations(
            limit=self._limit,
            name=self._name,
            resource_group_id=self._resource_group_id,
            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('reservations')

    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 Reservation.
        :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 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 BareMetalServerNetworkAttachmentsPager:
    """
    BareMetalServerNetworkAttachmentsPager can be used to simplify the use of the "list_bare_metal_server_network_attachments" method.
    """

    def __init__(
        self,
        *,
        client: VpcV1,
        bare_metal_server_id: str,
        limit: int = None,
    ) -> None:
        """
        Initialize a BareMetalServerNetworkAttachmentsPager 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 BareMetalServerNetworkAttachment.
        :rtype: List[dict]
        """
        if not self.has_next():
            raise StopIteration(message='No more results available')

        result = self._client.list_bare_metal_server_network_attachments(
            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_attachments')

    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 BareMetalServerNetworkAttachment.
        :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,
        tag: 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.
        :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._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
        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 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,
            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('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 SnapshotConsistencyGroupsPager:
    """
    SnapshotConsistencyGroupsPager can be used to simplify the use of the "list_snapshot_consistency_groups" method.
    """

    def __init__(
        self,
        *,
        client: VpcV1,
        limit: int = None,
        resource_group_id: str = None,
        name: str = None,
        sort: str = None,
        backup_policy_plan_id: str = None,
    ) -> None:
        """
        Initialize a SnapshotConsistencyGroupsPager 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 backup_policy_plan_id: (optional) Filters the collection to
               backup policy jobs with a `backup_policy_plan.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
        self._name = name
        self._sort = sort
        self._backup_policy_plan_id = backup_policy_plan_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 SnapshotConsistencyGroup.
        :rtype: List[dict]
        """
        if not self.has_next():
            raise StopIteration(message='No more results available')

        result = self._client.list_snapshot_consistency_groups(
            limit=self._limit,
            resource_group_id=self._resource_group_id,
            name=self._name,
            sort=self._sort,
            backup_policy_plan_id=self._backup_policy_plan_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('snapshot_consistency_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 SnapshotConsistencyGroup.
        :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,
        snapshot_consistency_group_id: str = None,
        snapshot_consistency_group_crn: 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.
        :param str snapshot_consistency_group_id: (optional) Filters the collection
               to resources with a `snapshot_consistency_group.id` property matching the
               specified identifier.
        :param str snapshot_consistency_group_crn: (optional) Filters the
               collection to resources with a `snapshot_consistency_group.crn` property
               matching the specified identifier.
        """
        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
        self._snapshot_consistency_group_id = snapshot_consistency_group_id
        self._snapshot_consistency_group_crn = snapshot_consistency_group_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 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,
            snapshot_consistency_group_id=self._snapshot_consistency_group_id,
            snapshot_consistency_group_crn=self._snapshot_consistency_group_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('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 ShareAccessorBindingsPager:
    """
    ShareAccessorBindingsPager can be used to simplify the use of the "list_share_accessor_bindings" method.
    """

    def __init__(
        self,
        *,
        client: VpcV1,
        id: str,
        limit: int = None,
    ) -> None:
        """
        Initialize a ShareAccessorBindingsPager object.
        :param str id: The file share 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._id = 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 ShareAccessorBinding.
        :rtype: List[dict]
        """
        if not self.has_next():
            raise StopIteration(message='No more results available')

        result = self._client.list_share_accessor_bindings(
            id=self._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('accessor_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 ShareAccessorBinding.
        :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 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 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 NetworkInterfaceFloatingIpsPager:
    """
    NetworkInterfaceFloatingIpsPager can be used to simplify the use of the "list_network_interface_floating_ips" method.
    """

    def __init__(
        self,
        *,
        client: VpcV1,
        virtual_network_interface_id: str,
        limit: int = None,
        sort: str = None,
    ) -> None:
        """
        Initialize a NetworkInterfaceFloatingIpsPager object.
        :param str virtual_network_interface_id: The virtual network interface
               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
               `-name` sorts the collection by the `name` 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._virtual_network_interface_id = virtual_network_interface_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 FloatingIPReference.
        :rtype: List[dict]
        """
        if not self.has_next():
            raise StopIteration(message='No more results available')

        result = self._client.list_network_interface_floating_ips(
            virtual_network_interface_id=self._virtual_network_interface_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('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 FloatingIPReference.
        :rtype: List[dict]
        """
        results = []
        while self.has_next():
            next_page = self.get_next()
            results.extend(next_page)
        return results


class VirtualNetworkInterfaceIpsPager:
    """
    VirtualNetworkInterfaceIpsPager can be used to simplify the use of the "list_virtual_network_interface_ips" method.
    """

    def __init__(
        self,
        *,
        client: VpcV1,
        virtual_network_interface_id: str,
        limit: int = None,
        sort: str = None,
    ) -> None:
        """
        Initialize a VirtualNetworkInterfaceIpsPager object.
        :param str virtual_network_interface_id: The virtual network interface
               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
               `-name` sorts the collection by the `name` 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._virtual_network_interface_id = virtual_network_interface_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 ReservedIPReference.
        :rtype: List[dict]
        """
        if not self.has_next():
            raise StopIteration(message='No more results available')

        result = self._client.list_virtual_network_interface_ips(
            virtual_network_interface_id=self._virtual_network_interface_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 ReservedIPReference.
        :rtype: List[dict]
        """
        results = []
        while self.has_next():
            next_page = self.get_next()
            results.extend(next_page)
        return results


class ClusterNetworkProfilesPager:
    """
    ClusterNetworkProfilesPager can be used to simplify the use of the "list_cluster_network_profiles" method.
    """

    def __init__(
        self,
        *,
        client: VpcV1,
        limit: int = None,
    ) -> None:
        """
        Initialize a ClusterNetworkProfilesPager 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 ClusterNetworkProfile.
        :rtype: List[dict]
        """
        if not self.has_next():
            raise StopIteration(message='No more results available')

        result = self._client.list_cluster_network_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 ClusterNetworkProfile.
        :rtype: List[dict]
        """
        results = []
        while self.has_next():
            next_page = self.get_next()
            results.extend(next_page)
        return results


class ClusterNetworksPager:
    """
    ClusterNetworksPager can be used to simplify the use of the "list_cluster_networks" method.
    """

    def __init__(
        self,
        *,
        client: VpcV1,
        limit: int = None,
        resource_group_id: str = None,
        name: str = None,
        sort: str = None,
        vpc_id: str = None,
        vpc_crn: str = None,
        vpc_name: str = None,
    ) -> None:
        """
        Initialize a ClusterNetworksPager 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 vpc_id: (optional) Filters the collection to cluster networks
               with a `vpc.id` property matching the specified id.
        :param str vpc_crn: (optional) Filters the collection to cluster networks
               with a `vpc.crn` property matching the specified CRN.
        :param str vpc_name: (optional) Filters the collection to cluster networks
               with a `vpc.name` property matching the 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._sort = sort
        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 ClusterNetwork.
        :rtype: List[dict]
        """
        if not self.has_next():
            raise StopIteration(message='No more results available')

        result = self._client.list_cluster_networks(
            limit=self._limit,
            resource_group_id=self._resource_group_id,
            name=self._name,
            sort=self._sort,
            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('cluster_networks')

    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 ClusterNetwork.
        :rtype: List[dict]
        """
        results = []
        while self.has_next():
            next_page = self.get_next()
            results.extend(next_page)
        return results


class ClusterNetworkInterfacesPager:
    """
    ClusterNetworkInterfacesPager can be used to simplify the use of the "list_cluster_network_interfaces" method.
    """

    def __init__(
        self,
        *,
        client: VpcV1,
        cluster_network_id: str,
        limit: int = None,
        name: str = None,
        sort: str = None,
    ) -> None:
        """
        Initialize a ClusterNetworkInterfacesPager object.
        :param str cluster_network_id: The cluster network identifier.
        :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 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._cluster_network_id = cluster_network_id
        self._limit = limit
        self._name = name
        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 ClusterNetworkInterface.
        :rtype: List[dict]
        """
        if not self.has_next():
            raise StopIteration(message='No more results available')

        result = self._client.list_cluster_network_interfaces(
            cluster_network_id=self._cluster_network_id,
            limit=self._limit,
            name=self._name,
            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('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 ClusterNetworkInterface.
        :rtype: List[dict]
        """
        results = []
        while self.has_next():
            next_page = self.get_next()
            results.extend(next_page)
        return results


class ClusterNetworkSubnetsPager:
    """
    ClusterNetworkSubnetsPager can be used to simplify the use of the "list_cluster_network_subnets" method.
    """

    def __init__(
        self,
        *,
        client: VpcV1,
        cluster_network_id: str,
        limit: int = None,
        name: str = None,
        sort: str = None,
    ) -> None:
        """
        Initialize a ClusterNetworkSubnetsPager object.
        :param str cluster_network_id: The cluster network identifier.
        :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 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._cluster_network_id = cluster_network_id
        self._limit = limit
        self._name = name
        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 ClusterNetworkSubnet.
        :rtype: List[dict]
        """
        if not self.has_next():
            raise StopIteration(message='No more results available')

        result = self._client.list_cluster_network_subnets(
            cluster_network_id=self._cluster_network_id,
            limit=self._limit,
            name=self._name,
            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('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 ClusterNetworkSubnet.
        :rtype: List[dict]
        """
        results = []
        while self.has_next():
            next_page = self.get_next()
            results.extend(next_page)
        return results


class ClusterNetworkSubnetReservedIpsPager:
    """
    ClusterNetworkSubnetReservedIpsPager can be used to simplify the use of the "list_cluster_network_subnet_reserved_ips" method.
    """

    def __init__(
        self,
        *,
        client: VpcV1,
        cluster_network_id: str,
        cluster_network_subnet_id: str,
        limit: int = None,
        name: str = None,
        sort: str = None,
    ) -> None:
        """
        Initialize a ClusterNetworkSubnetReservedIpsPager object.
        :param str cluster_network_id: The cluster network identifier.
        :param str cluster_network_subnet_id: The cluster network subnet
               identifier.
        :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 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._cluster_network_id = cluster_network_id
        self._cluster_network_subnet_id = cluster_network_subnet_id
        self._limit = limit
        self._name = name
        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 ClusterNetworkSubnetReservedIP.
        :rtype: List[dict]
        """
        if not self.has_next():
            raise StopIteration(message='No more results available')

        result = self._client.list_cluster_network_subnet_reserved_ips(
            cluster_network_id=self._cluster_network_id,
            cluster_network_subnet_id=self._cluster_network_subnet_id,
            limit=self._limit,
            name=self._name,
            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 ClusterNetworkSubnetReservedIP.
        :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,
        target_id: str = None,
        target_crn: str = None,
        target_name: str = None,
        target_resource_type: 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.
        :param str target_id: (optional) Filters the collection to resources with a
               `target.id` property matching the specified identifier.
        :param str target_crn: (optional) Filters the collection to resources with
               a `target.crn` property matching the specified CRN.
        :param str target_name: (optional) Filters the collection to resources with
               a `target.name` property matching the exact specified name.
        :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._sort = sort
        self._target_id = target_id
        self._target_crn = target_crn
        self._target_name = target_name
        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 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,
            target_id=self._target_id,
            target_crn=self._target_crn,
            target_name=self._target_name,
            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('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 IkePolicyConnectionsPager:
    """
    IkePolicyConnectionsPager can be used to simplify the use of the "list_ike_policy_connections" method.
    """

    def __init__(
        self,
        *,
        client: VpcV1,
        id: str,
        limit: int = None,
    ) -> None:
        """
        Initialize a IkePolicyConnectionsPager object.
        :param str id: The IKE policy 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._id = 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 VPNGatewayConnection.
        :rtype: List[dict]
        """
        if not self.has_next():
            raise StopIteration(message='No more results available')

        result = self._client.list_ike_policy_connections(
            id=self._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('connections')

    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 VPNGatewayConnection.
        :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 IpsecPolicyConnectionsPager:
    """
    IpsecPolicyConnectionsPager can be used to simplify the use of the "list_ipsec_policy_connections" method.
    """

    def __init__(
        self,
        *,
        client: VpcV1,
        id: str,
        limit: int = None,
    ) -> None:
        """
        Initialize a IpsecPolicyConnectionsPager object.
        :param str id: The IPsec policy 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._id = 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 VPNGatewayConnection.
        :rtype: List[dict]
        """
        if not self.has_next():
            raise StopIteration(message='No more results available')

        result = self._client.list_ipsec_policy_connections(
            id=self._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('connections')

    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 VPNGatewayConnection.
        :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 VpnGatewayConnectionsPager:
    """
    VpnGatewayConnectionsPager can be used to simplify the use of the "list_vpn_gateway_connections" method.
    """

    def __init__(
        self,
        *,
        client: VpcV1,
        vpn_gateway_id: str,
        limit: int = None,
        status: str = None,
    ) -> None:
        """
        Initialize a VpnGatewayConnectionsPager object.
        :param str vpn_gateway_id: The VPN gateway identifier.
        :param int limit: (optional) The number of resources to return on a page.
        :param str status: (optional) Filters the collection to VPN gateway
               connections with a `status` property matching the specified value.
        """
        self._has_next = True
        self._client = client
        self._page_context = {'next': None}
        self._vpn_gateway_id = vpn_gateway_id
        self._limit = limit
        self._status = status

    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 VPNGatewayConnection.
        :rtype: List[dict]
        """
        if not self.has_next():
            raise StopIteration(message='No more results available')

        result = self._client.list_vpn_gateway_connections(
            vpn_gateway_id=self._vpn_gateway_id,
            limit=self._limit,
            status=self._status,
            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('connections')

    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 VPNGatewayConnection.
        :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,
        lifecycle_state: List[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 List[str] lifecycle_state: (optional) Filters the collection to
               resources with a `lifecycle_state` property matching one of the specified
               comma-separated values.
        :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._lifecycle_state = lifecycle_state
        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,
            lifecycle_state=self._lifecycle_state,
            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


class PrivatePathServiceGatewaysPager:
    """
    PrivatePathServiceGatewaysPager can be used to simplify the use of the "list_private_path_service_gateways" method.
    """

    def __init__(
        self,
        *,
        client: VpcV1,
        limit: int = None,
        resource_group_id: str = None,
    ) -> None:
        """
        Initialize a PrivatePathServiceGatewaysPager 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 PrivatePathServiceGateway.
        :rtype: List[dict]
        """
        if not self.has_next():
            raise StopIteration(message='No more results available')

        result = self._client.list_private_path_service_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('private_path_service_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 PrivatePathServiceGateway.
        :rtype: List[dict]
        """
        results = []
        while self.has_next():
            next_page = self.get_next()
            results.extend(next_page)
        return results


class PrivatePathServiceGatewayAccountPoliciesPager:
    """
    PrivatePathServiceGatewayAccountPoliciesPager can be used to simplify the use of the "list_private_path_service_gateway_account_policies" method.
    """

    def __init__(
        self,
        *,
        client: VpcV1,
        private_path_service_gateway_id: str,
        limit: int = None,
        account_id: str = None,
    ) -> None:
        """
        Initialize a PrivatePathServiceGatewayAccountPoliciesPager object.
        :param str private_path_service_gateway_id: The private path service
               gateway identifier.
        :param int limit: (optional) The number of resources to return on a page.
        :param str account_id: (optional) Filters the collection to resources with
               an `account.id` property matching the specified identifier.
        """
        self._has_next = True
        self._client = client
        self._page_context = {'next': None}
        self._private_path_service_gateway_id = private_path_service_gateway_id
        self._limit = limit
        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 PrivatePathServiceGatewayAccountPolicy.
        :rtype: List[dict]
        """
        if not self.has_next():
            raise StopIteration(message='No more results available')

        result = self._client.list_private_path_service_gateway_account_policies(
            private_path_service_gateway_id=self._private_path_service_gateway_id,
            limit=self._limit,
            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('account_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 PrivatePathServiceGatewayAccountPolicy.
        :rtype: List[dict]
        """
        results = []
        while self.has_next():
            next_page = self.get_next()
            results.extend(next_page)
        return results


class PrivatePathServiceGatewayEndpointGatewayBindingsPager:
    """
    PrivatePathServiceGatewayEndpointGatewayBindingsPager can be used to simplify the use of the "list_private_path_service_gateway_endpoint_gateway_bindings" method.
    """

    def __init__(
        self,
        *,
        client: VpcV1,
        private_path_service_gateway_id: str,
        limit: int = None,
        status: str = None,
        account_id: str = None,
    ) -> None:
        """
        Initialize a PrivatePathServiceGatewayEndpointGatewayBindingsPager object.
        :param str private_path_service_gateway_id: The private path service
               gateway identifier.
        :param int limit: (optional) The number of resources to return on a page.
        :param str status: (optional) Filters the collection to endpoint gateway
               bindings with a `status` property matching the specified value.
        :param str account_id: (optional) Filters the collection to resources with
               an `account.id` property matching the specified identifier.
        """
        self._has_next = True
        self._client = client
        self._page_context = {'next': None}
        self._private_path_service_gateway_id = private_path_service_gateway_id
        self._limit = limit
        self._status = status
        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 PrivatePathServiceGatewayEndpointGatewayBinding.
        :rtype: List[dict]
        """
        if not self.has_next():
            raise StopIteration(message='No more results available')

        result = self._client.list_private_path_service_gateway_endpoint_gateway_bindings(
            private_path_service_gateway_id=self._private_path_service_gateway_id,
            limit=self._limit,
            status=self._status,
            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('endpoint_gateway_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 PrivatePathServiceGatewayEndpointGatewayBinding.
        :rtype: List[dict]
        """
        results = []
        while self.has_next():
            next_page = self.get_next()
            results.extend(next_page)
        return results
