# coding: utf-8

# (C) Copyright IBM Corp. 2021.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# IBM OpenAPI SDK Code Generator Version: 3.43.0-49eab5c7-20211117-152138
 
"""
No description provided (generated by Openapi Generator
https://github.com/openapitools/openapi-generator)

API Version: __VERSION__
"""

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

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

from .common import get_sdk_headers

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

class DirectLinkProviderV2(BaseService):
    """The Direct Link Provider V2 service."""

    DEFAULT_SERVICE_URL = 'https://directlink.cloud.ibm.com/provider/v2'
    DEFAULT_SERVICE_NAME = 'direct_link_provider'

    @classmethod
    def new_instance(cls,
                     version: str,
                     service_name: str = DEFAULT_SERVICE_NAME,
                    ) -> 'DirectLinkProviderV2':
        """
        Return a new client for the Direct Link Provider service using the
               specified parameters and external configuration.

        :param str version: Requests the version of the API as a date in the format
               `YYYY-MM-DD`. Any date from 2020-04-28 up to the current date may be
               provided. Specify the current date to request the latest version.
        """
        if version is None:
            raise ValueError('version must be provided')

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

    def __init__(self,
                 version: str,
                 authenticator: Authenticator = None,
                ) -> None:
        """
        Construct a new client for the Direct Link Provider service.

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

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


    #########################
    # providerAPIs
    #########################


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

        List all Direct Link Connect gateways created by this provider.

        :param str start: (optional) A server-supplied token determining which
               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 `ProviderGatewayCollection` object
        """

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

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

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

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

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


    def create_provider_gateway(self,
        bgp_asn: int,
        customer_account_id: str,
        name: str,
        port: 'ProviderGatewayPortIdentity',
        speed_mbps: int,
        *,
        bgp_cer_cidr: str = None,
        bgp_ibm_cidr: str = None,
        vlan: int = None,
        check_only: str = None,
        **kwargs
    ) -> DetailedResponse:
        """
        Create gateway.

        Create a Direct Link Connect gateway based on the supplied template in the
        specified customer account.
        The gateway will be 'provider_api_managed=true'.

        :param int bgp_asn: BGP ASN.
               For a 2-byte range, enter a value between 1-64495 or 64999. For a 2-byte or
               4-byte range, enter a value between 131072-4199999999. For a 4-byte range,
               enter a value between 4201000000-4201064511.
        :param str customer_account_id: Customer IBM Cloud account ID for the new
               gateway.  A gateway object containing the pending create request will
               become available in the specified account.
        :param str name: The unique user-defined name for this gateway.
        :param ProviderGatewayPortIdentity port: Select Port Label for the gateway.
        :param int speed_mbps: Gateway speed in megabits per second.
        :param str bgp_cer_cidr: (optional) BGP customer edge router CIDR.
               For auto IP assignment, omit bgp_cer_cidr and bgp_ibm_cidr.  IBM will
               automatically select values for bgp_cer_cidr and bgp_ibm_cidr.
               For manual IP assignment set a valid bgp_cer_cidr and bgp_ibm_cidr CIDR,
               the value must reside in one of "10.254.0.0/16", "172.16.0.0/12",
               "192.168.0.0/16", "169.254.0.0/16" or an owned public CIDR.  bgp_cer_cidr
               and bgp_ibm_cidr must have matching network and subnet mask values.
        :param str bgp_ibm_cidr: (optional) BGP IBM CIDR.
               For auto IP assignment, omit bgp_cer_cidr and bgp_ibm_cidr.  IBM will
               automatically select values for bgp_cer_cidr and bgp_ibm_cidr.
               For manual IP assignment set a valid bgp_cer_cidr and bgp_ibm_cidr CIDR,
               the value must reside in one of "10.254.0.0/16", "172.16.0.0/12",
               "192.168.0.0/16", "169.254.0.0/16" or an owned public CIDR.  bgp_cer_cidr
               and bgp_ibm_cidr must have matching network and subnet mask values.
        :param int vlan: (optional) VLAN requested for this gateway.
               VLAN provided should be in the range 1 to 4094.
        :param str check_only: (optional) When true, perform request validation
               only and do not create a 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 `ProviderGateway` object
        """

        if bgp_asn is None:
            raise ValueError('bgp_asn must be provided')
        if customer_account_id is None:
            raise ValueError('customer_account_id must be provided')
        if name is None:
            raise ValueError('name must be provided')
        if port is None:
            raise ValueError('port must be provided')
        if speed_mbps is None:
            raise ValueError('speed_mbps must be provided')
        port = convert_model(port)
        headers = {}
        sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
                                      service_version='V2',
                                      operation_id='create_provider_gateway')
        headers.update(sdk_headers)

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

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

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

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

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


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

        Delete a Direct Link Connect provider managed gateway.

        :param str id: Direct Link Connect 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 `ProviderGateway` object
        """

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

        params = {
            'version': self.version
        }

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

        path_param_keys = ['id']
        path_param_values = self.encode_path_vars(id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/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_provider_gateway(self,
        id: str,
        **kwargs
    ) -> DetailedResponse:
        """
        Get gateway.

        Get a Direct Link Connect gateway.
             Gateways with either `provider_api_managed=true` or
        `provider_api_managed=false` can be retrieved.

        :param str id: Direct Link Connect 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 `ProviderGateway` object
        """

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

        params = {
            'version': self.version
        }

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

        path_param_keys = ['id']
        path_param_values = self.encode_path_vars(id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/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_provider_gateway(self,
        id: str,
        *,
        bgp_asn: int = None,
        bgp_cer_cidr: str = None,
        bgp_ibm_cidr: str = None,
        name: str = None,
        speed_mbps: int = None,
        vlan: int = None,
        **kwargs
    ) -> DetailedResponse:
        """
        Update gateway.

        Update a Direct Link Connect provider managed gateway.
        Name changes are applied immediately, other changes result in a gateway
        change_request and require approval from the client.

        :param str id: Direct Link Connect gateway identifier.
        :param int bgp_asn: (optional) The autonomous system number (ASN) of Border
               Gateway Protocol (BGP) configuration for the IBM side of the DL 2.0
               gateway.
        :param str bgp_cer_cidr: (optional) BGP customer edge router CIDR is the
               new CIDR (Classless Inter-Domain Routing) value to be updated on customer
               edge router for the DL 2.0 gateway. Customer edge IP and IBM IP should be
               in the same network. Updating customer edge router CIDR should be
               accompanied with IBM CIDR in the request. Update customer edge router IP to
               a valid bgp_cer_cidr and bgp_ibm_cidr CIDR, the value must reside in one of
               "10.254.0.0/16", "172.16.0.0/12", "192.168.0.0/16", "169.254.0.0/16" or an
               owned public CIDR.  bgp_cer_cidr and bgp_ibm_cidr must have matching
               network and subnet mask values.
        :param str bgp_ibm_cidr: (optional) BGP IBM CIDR is the new CIDR (Classless
               Inter-Domain Routing) value to be updated on IBM edge router for the DL 2.0
               gateway. IBM IP and customer edge IP should be in the same network.
               Updating IBM CIDR should be accompanied with customer edge router CIDR in
               the request. Update IBM CIDR to a valid bgp_cer_cidr and bgp_ibm_cidr CIDR,
               the value must reside in one of "10.254.0.0/16", "172.16.0.0/12",
               "192.168.0.0/16", "169.254.0.0/16" or an owned public CIDR.  bgp_cer_cidr
               and bgp_ibm_cidr must have matching network and subnet mask values.
        :param str name: (optional) The unique user-defined name for this gateway.
        :param int speed_mbps: (optional) Gateway speed in megabits per second.
        :param int vlan: (optional) VLAN to be modified for this gateway.
               VLAN provided should be in the range 1 to 4094.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `ProviderGateway` object
        """

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

        params = {
            'version': self.version
        }

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

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

        path_param_keys = ['id']
        path_param_values = self.encode_path_vars(id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/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_provider_ports(self,
        *,
        start: str = None,
        limit: int = None,
        **kwargs
    ) -> DetailedResponse:
        """
        List ports.

        List all provider ports (associated with the caller).

        :param str start: (optional) A server-supplied token determining which
               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 `ProviderPortCollection` object
        """

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

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

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

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

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


    def get_provider_port(self,
        id: str,
        **kwargs
    ) -> DetailedResponse:
        """
        Get port.

        Get provider port information.

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

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

        params = {
            'version': self.version
        }

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

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

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


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


class ProviderGateway():
    """
    gateway.

    :attr int bgp_asn: BGP ASN.
          For a 2-byte ASN values between 1-64495 or 64999. For a 2-byte or 4-byte range
          ASN values between 131072-4199999999. For a 4-byte ASN values
          4201000000-4201064511.
    :attr str bgp_cer_cidr: (optional) BGP customer edge router CIDR.
    :attr int bgp_ibm_asn: IBM BGP ASN.
    :attr str bgp_ibm_cidr: (optional) BGP IBM CIDR.
    :attr str bgp_status: (optional) Gateway BGP status.
          The list of enumerated values for this property may expand in the future. Code
          and processes using this field must tolerate unexpected values.
    :attr ProviderGatewayChangeRequest change_request: (optional)
    :attr datetime created_at: The date and time resource was created.
    :attr str crn: (optional) The CRN (Cloud Resource Name) of this gateway.
    :attr str customer_account_id: Customer IBM Cloud account ID.
    :attr str id: The unique identifier of this gateway.
    :attr str name: The unique user-defined name for this gateway.
    :attr str operational_status: Gateway operational status.
          The list of enumerated values for this property may expand in the future. Code
          and processes using this field must tolerate unexpected values.
    :attr ProviderGatewayPortReference port: Port identifier for the gateway.
    :attr bool provider_api_managed: Set to `true` for gateways created through the
          Direct Link Provider APIs.
          Most Direct Link Provider APIs cannot interact with `provider_api_managed=false`
          gateways.
    :attr int speed_mbps: Gateway speed in megabits per second.
    :attr str type: Gateway type.
    :attr int vlan: (optional) VLAN for this gateway.
    """

    def __init__(self,
                 bgp_asn: int,
                 bgp_ibm_asn: int,
                 created_at: datetime,
                 customer_account_id: str,
                 id: str,
                 name: str,
                 operational_status: str,
                 port: 'ProviderGatewayPortReference',
                 provider_api_managed: bool,
                 speed_mbps: int,
                 type: str,
                 *,
                 bgp_cer_cidr: str = None,
                 bgp_ibm_cidr: str = None,
                 bgp_status: str = None,
                 change_request: 'ProviderGatewayChangeRequest' = None,
                 crn: str = None,
                 vlan: int = None) -> None:
        """
        Initialize a ProviderGateway object.

        :param int bgp_asn: BGP ASN.
               For a 2-byte ASN values between 1-64495 or 64999. For a 2-byte or 4-byte
               range ASN values between 131072-4199999999. For a 4-byte ASN values
               4201000000-4201064511.
        :param int bgp_ibm_asn: IBM BGP ASN.
        :param datetime created_at: The date and time resource was created.
        :param str customer_account_id: Customer IBM Cloud account ID.
        :param str id: The unique identifier of this gateway.
        :param str name: The unique user-defined name for this gateway.
        :param str operational_status: Gateway operational status.
               The list of enumerated values for this property may expand in the future.
               Code and processes using this field must tolerate unexpected values.
        :param ProviderGatewayPortReference port: Port identifier for the gateway.
        :param bool provider_api_managed: Set to `true` for gateways created
               through the Direct Link Provider APIs.
               Most Direct Link Provider APIs cannot interact with
               `provider_api_managed=false` gateways.
        :param int speed_mbps: Gateway speed in megabits per second.
        :param str type: Gateway type.
        :param str bgp_cer_cidr: (optional) BGP customer edge router CIDR.
        :param str bgp_ibm_cidr: (optional) BGP IBM CIDR.
        :param str bgp_status: (optional) Gateway BGP status.
               The list of enumerated values for this property may expand in the future.
               Code and processes using this field must tolerate unexpected values.
        :param ProviderGatewayChangeRequest change_request: (optional)
        :param str crn: (optional) The CRN (Cloud Resource Name) of this gateway.
        :param int vlan: (optional) VLAN for this gateway.
        """
        self.bgp_asn = bgp_asn
        self.bgp_cer_cidr = bgp_cer_cidr
        self.bgp_ibm_asn = bgp_ibm_asn
        self.bgp_ibm_cidr = bgp_ibm_cidr
        self.bgp_status = bgp_status
        self.change_request = change_request
        self.created_at = created_at
        self.crn = crn
        self.customer_account_id = customer_account_id
        self.id = id
        self.name = name
        self.operational_status = operational_status
        self.port = port
        self.provider_api_managed = provider_api_managed
        self.speed_mbps = speed_mbps
        self.type = type
        self.vlan = vlan

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'ProviderGateway':
        """Initialize a ProviderGateway object from a json dictionary."""
        args = {}
        if 'bgp_asn' in _dict:
            args['bgp_asn'] = _dict.get('bgp_asn')
        else:
            raise ValueError('Required property \'bgp_asn\' not present in ProviderGateway JSON')
        if 'bgp_cer_cidr' in _dict:
            args['bgp_cer_cidr'] = _dict.get('bgp_cer_cidr')
        if 'bgp_ibm_asn' in _dict:
            args['bgp_ibm_asn'] = _dict.get('bgp_ibm_asn')
        else:
            raise ValueError('Required property \'bgp_ibm_asn\' not present in ProviderGateway JSON')
        if 'bgp_ibm_cidr' in _dict:
            args['bgp_ibm_cidr'] = _dict.get('bgp_ibm_cidr')
        if 'bgp_status' in _dict:
            args['bgp_status'] = _dict.get('bgp_status')
        if 'change_request' in _dict:
            args['change_request'] = _dict.get('change_request')
        if 'created_at' in _dict:
            args['created_at'] = string_to_datetime(_dict.get('created_at'))
        else:
            raise ValueError('Required property \'created_at\' not present in ProviderGateway JSON')
        if 'crn' in _dict:
            args['crn'] = _dict.get('crn')
        if 'customer_account_id' in _dict:
            args['customer_account_id'] = _dict.get('customer_account_id')
        else:
            raise ValueError('Required property \'customer_account_id\' not present in ProviderGateway JSON')
        if 'id' in _dict:
            args['id'] = _dict.get('id')
        else:
            raise ValueError('Required property \'id\' not present in ProviderGateway JSON')
        if 'name' in _dict:
            args['name'] = _dict.get('name')
        else:
            raise ValueError('Required property \'name\' not present in ProviderGateway JSON')
        if 'operational_status' in _dict:
            args['operational_status'] = _dict.get('operational_status')
        else:
            raise ValueError('Required property \'operational_status\' not present in ProviderGateway JSON')
        if 'port' in _dict:
            args['port'] = ProviderGatewayPortReference.from_dict(_dict.get('port'))
        else:
            raise ValueError('Required property \'port\' not present in ProviderGateway JSON')
        if 'provider_api_managed' in _dict:
            args['provider_api_managed'] = _dict.get('provider_api_managed')
        else:
            raise ValueError('Required property \'provider_api_managed\' not present in ProviderGateway JSON')
        if 'speed_mbps' in _dict:
            args['speed_mbps'] = _dict.get('speed_mbps')
        else:
            raise ValueError('Required property \'speed_mbps\' not present in ProviderGateway JSON')
        if 'type' in _dict:
            args['type'] = _dict.get('type')
        else:
            raise ValueError('Required property \'type\' not present in ProviderGateway JSON')
        if 'vlan' in _dict:
            args['vlan'] = _dict.get('vlan')
        return cls(**args)

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

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'bgp_asn') and self.bgp_asn is not None:
            _dict['bgp_asn'] = self.bgp_asn
        if hasattr(self, 'bgp_cer_cidr') and self.bgp_cer_cidr is not None:
            _dict['bgp_cer_cidr'] = self.bgp_cer_cidr
        if hasattr(self, 'bgp_ibm_asn') and self.bgp_ibm_asn is not None:
            _dict['bgp_ibm_asn'] = self.bgp_ibm_asn
        if hasattr(self, 'bgp_ibm_cidr') and self.bgp_ibm_cidr is not None:
            _dict['bgp_ibm_cidr'] = self.bgp_ibm_cidr
        if hasattr(self, 'bgp_status') and self.bgp_status is not None:
            _dict['bgp_status'] = self.bgp_status
        if hasattr(self, 'change_request') and self.change_request is not None:
            if isinstance(self.change_request, dict):
                _dict['change_request'] = self.change_request
            else:
                _dict['change_request'] = self.change_request.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, 'customer_account_id') and self.customer_account_id is not None:
            _dict['customer_account_id'] = self.customer_account_id
        if hasattr(self, 'id') 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, 'operational_status') and self.operational_status is not None:
            _dict['operational_status'] = self.operational_status
        if hasattr(self, 'port') and self.port is not None:
            _dict['port'] = self.port.to_dict()
        if hasattr(self, 'provider_api_managed') and self.provider_api_managed is not None:
            _dict['provider_api_managed'] = self.provider_api_managed
        if hasattr(self, 'speed_mbps') and self.speed_mbps is not None:
            _dict['speed_mbps'] = self.speed_mbps
        if hasattr(self, 'type') and self.type is not None:
            _dict['type'] = self.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 ProviderGateway object."""
        return json.dumps(self.to_dict(), indent=2)

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

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

    class BgpStatusEnum(str, Enum):
        """
        Gateway BGP status.
        The list of enumerated values for this property may expand in the future. Code and
        processes using this field must tolerate unexpected values.
        """
        ACTIVE = 'active'
        CONNECT = 'connect'
        ESTABLISHED = 'established'
        IDLE = 'idle'


    class OperationalStatusEnum(str, Enum):
        """
        Gateway operational status.
        The list of enumerated values for this property may expand in the future. Code and
        processes using this field must tolerate unexpected values.
        """
        CONFIGURING = 'configuring'
        CREATE_PENDING = 'create_pending'
        CREATE_REJECTED = 'create_rejected'
        DELETE_PENDING = 'delete_pending'
        PROVISIONED = 'provisioned'


class ProviderGatewayChangeRequest():
    """
    ProviderGatewayChangeRequest.

    """

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

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

class ProviderGatewayCollection():
    """
    A paginated collection of resources.

    :attr ProviderGatewayCollectionFirst first: A reference to the first page of
          resources.
    :attr int limit: The maximum number of resources can be returned by the request.
    :attr ProviderGatewayCollectionNext next: (optional) A reference to the next
          page of resources; this reference is included for all pages except the last
          page.
    :attr int total_count: The total number of resources across all pages.
    :attr List[ProviderGateway] gateways: Collection of Direct Link gateways.
    """

    def __init__(self,
                 first: 'ProviderGatewayCollectionFirst',
                 limit: int,
                 total_count: int,
                 gateways: List['ProviderGateway'],
                 *,
                 next: 'ProviderGatewayCollectionNext' = None) -> None:
        """
        Initialize a ProviderGatewayCollection object.

        :param ProviderGatewayCollectionFirst first: A reference to the first page
               of resources.
        :param int limit: The maximum number of resources can be returned by the
               request.
        :param int total_count: The total number of resources across all pages.
        :param List[ProviderGateway] gateways: Collection of Direct Link gateways.
        :param ProviderGatewayCollectionNext next: (optional) A reference to the
               next page of resources; this reference is included for all pages except the
               last page.
        """
        self.first = first
        self.limit = limit
        self.next = next
        self.total_count = total_count
        self.gateways = gateways

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

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

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

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

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

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

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

class ProviderGatewayCollectionFirst():
    """
    A reference to the first page of resources.

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

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

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

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

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

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

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

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

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

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

class ProviderGatewayCollectionNext():
    """
    A reference to the next page of resources; this reference is included for all pages
    except the last page.

    :attr str href: The URL for the next page of resources.
    :attr str start: start token for the next page of resources.
    """

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

        :param str href: The URL for the next page of resources.
        :param str start: start token for the next page of resources.
        """
        self.href = href
        self.start = start

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

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

    def to_dict(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, 'start') and self.start is not None:
            _dict['start'] = self.start
        return _dict

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

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

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

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

class ProviderGatewayPortIdentity():
    """
    Select Port Label for the gateway.

    :attr str id: Port identifier.
    """

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

        :param str id: Port identifier.
        """
        self.id = id

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

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

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

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

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

class ProviderGatewayPortReference():
    """
    Port identifier for the gateway.

    :attr str id: Port identifier.
    """

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

        :param str id: Port identifier.
        """
        self.id = id

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

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

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

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

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

class ProviderGatewayUpdateAttributesUpdatesItem():
    """
    ProviderGatewayUpdateAttributesUpdatesItem.

    """

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

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

class ProviderPort():
    """
    Provider port details.

    :attr str id: Port identifier.
    :attr str label: Port Label.
    :attr str location_display_name: Port location long name.
    :attr str location_name: Port location name identifier.
    :attr str provider_name: Port provider name.
    :attr List[int] supported_link_speeds: Port's supported speeds in megabits per
          second.
    """

    def __init__(self,
                 id: str,
                 label: str,
                 location_display_name: str,
                 location_name: str,
                 provider_name: str,
                 supported_link_speeds: List[int]) -> None:
        """
        Initialize a ProviderPort object.

        :param str id: Port identifier.
        :param str label: Port Label.
        :param str location_display_name: Port location long name.
        :param str location_name: Port location name identifier.
        :param str provider_name: Port provider name.
        :param List[int] supported_link_speeds: Port's supported speeds in megabits
               per second.
        """
        self.id = id
        self.label = label
        self.location_display_name = location_display_name
        self.location_name = location_name
        self.provider_name = provider_name
        self.supported_link_speeds = supported_link_speeds

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

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

    def to_dict(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, 'label') and self.label is not None:
            _dict['label'] = self.label
        if hasattr(self, 'location_display_name') and self.location_display_name is not None:
            _dict['location_display_name'] = self.location_display_name
        if hasattr(self, 'location_name') and self.location_name is not None:
            _dict['location_name'] = self.location_name
        if hasattr(self, 'provider_name') and self.provider_name is not None:
            _dict['provider_name'] = self.provider_name
        if hasattr(self, 'supported_link_speeds') and self.supported_link_speeds is not None:
            _dict['supported_link_speeds'] = self.supported_link_speeds
        return _dict

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

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

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

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

class ProviderPortCollection():
    """
    List of port label details.

    :attr ProviderPortCollectionFirst first: A reference to the first page of
          resources.
    :attr int limit: The maximum number of resources can be returned by the request.
    :attr ProviderPortCollectionNext next: (optional) A reference to the next page
          of resources; this reference is included for all pages except the last page.
    :attr int total_count: The total number of resources across all pages.
    :attr List[ProviderPort] ports: (optional) Array of ports.
    """

    def __init__(self,
                 first: 'ProviderPortCollectionFirst',
                 limit: int,
                 total_count: int,
                 *,
                 next: 'ProviderPortCollectionNext' = None,
                 ports: List['ProviderPort'] = None) -> None:
        """
        Initialize a ProviderPortCollection object.

        :param ProviderPortCollectionFirst first: A reference to the first page of
               resources.
        :param int limit: The maximum number of resources can be returned by the
               request.
        :param int total_count: The total number of resources across all pages.
        :param ProviderPortCollectionNext next: (optional) A reference to the next
               page of resources; this reference is included for all pages except the last
               page.
        :param List[ProviderPort] ports: (optional) Array of ports.
        """
        self.first = first
        self.limit = limit
        self.next = next
        self.total_count = total_count
        self.ports = ports

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

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

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

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

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

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

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

class ProviderPortCollectionFirst():
    """
    A reference to the first page of resources.

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

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

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

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

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

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

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

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

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

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

class ProviderPortCollectionNext():
    """
    A reference to the next page of resources; this reference is included for all pages
    except the last page.

    :attr str href: URL for the next page of resources.
    :attr str start: start token for the next page of resources.
    """

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

        :param str href: URL for the next page of resources.
        :param str start: start token for the next page of resources.
        """
        self.href = href
        self.start = start

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

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

    def to_dict(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, 'start') and self.start is not None:
            _dict['start'] = self.start
        return _dict

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

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

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

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

class ProviderGatewayChangeRequestProviderGatewayCreate(ProviderGatewayChangeRequest):
    """
    gateway create.

    :attr str type: type of gateway change request.
    """

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

        :param str type: type of gateway change request.
        """
        # pylint: disable=super-init-not-called
        self.type = type

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

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

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

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

    class TypeEnum(str, Enum):
        """
        type of gateway change request.
        """
        CREATE_GATEWAY = 'create_gateway'


class ProviderGatewayChangeRequestProviderGatewayDelete(ProviderGatewayChangeRequest):
    """
    gateway delete.

    :attr str type: type of gateway change request.
    """

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

        :param str type: type of gateway change request.
        """
        # pylint: disable=super-init-not-called
        self.type = type

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

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

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

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

    class TypeEnum(str, Enum):
        """
        type of gateway change request.
        """
        DELETE_GATEWAY = 'delete_gateway'


class ProviderGatewayChangeRequestProviderGatewayUpdateAttributes(ProviderGatewayChangeRequest):
    """
    gateway attributes update.

    :attr str type: type of gateway change request.
    :attr List[ProviderGatewayUpdateAttributesUpdatesItem] updates: array of pending
          updates.
    """

    def __init__(self,
                 type: str,
                 updates: List['ProviderGatewayUpdateAttributesUpdatesItem']) -> None:
        """
        Initialize a ProviderGatewayChangeRequestProviderGatewayUpdateAttributes object.

        :param str type: type of gateway change request.
        :param List[ProviderGatewayUpdateAttributesUpdatesItem] updates: array of
               pending updates.
        """
        # pylint: disable=super-init-not-called
        self.type = type
        self.updates = updates

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

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

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

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

    class TypeEnum(str, Enum):
        """
        type of gateway change request.
        """
        UPDATE_ATTRIBUTES = 'update_attributes'


class ProviderGatewayUpdateAttributesUpdatesItemProviderGatewayBGPASNUpdate(ProviderGatewayUpdateAttributesUpdatesItem):
    """
    The autonomous system number (ASN) of Border Gateway Protocol
    (BGP) configuration for the IBM side of the DL 2.0 gateway.

    :attr int bgp_asn: (optional) New gateway BGP ASN.
    """

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

        :param int bgp_asn: (optional) New gateway BGP ASN.
        """
        # pylint: disable=super-init-not-called
        self.bgp_asn = bgp_asn

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

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

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

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

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

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

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

class ProviderGatewayUpdateAttributesUpdatesItemProviderGatewayBGPIPUpdate(ProviderGatewayUpdateAttributesUpdatesItem):
    """
    Update BGP customer and IBM CIDR.

    :attr str bgp_cer_cidr: (optional) BGP customer edge router CIDR is the new CIDR
          (Classless Inter-Domain Routing) value to be updated on customer edge router for
          the DL 2.0 gateway.
          Customer edge IP and IBM IP should be in the same network. Updating customer
          edge router CIDR should be accompanied with IBM CIDR in the request. Update
          customer edge router IP to a valid bgp_cer_cidr and bgp_ibm_cidr CIDR, the value
          must reside in one of "10.254.0.0/16", "172.16.0.0/12", "192.168.0.0/16",
          "169.254.0.0/16" or an owned public CIDR.  bgp_cer_cidr and bgp_ibm_cidr must
          have matching network and subnet mask values.
    :attr str bgp_ibm_cidr: (optional) BGP IBM CIDR is the new CIDR (Classless
          Inter-Domain Routing) value to be updated on IBM edge router for the DL 2.0
          gateway.
          IBM IP and customer edge IP should be in the same network. Updating IBM CIDR
          should be accompanied with customer edge router CIDR in the request. Update IBM
          CIDR to a valid bgp_cer_cidr and bgp_ibm_cidr CIDR, the value must reside in one
          of "10.254.0.0/16", "172.16.0.0/12", "192.168.0.0/16", "169.254.0.0/16" or an
          owned public CIDR.  bgp_cer_cidr and bgp_ibm_cidr must have matching network and
          subnet mask values.
    """

    def __init__(self,
                 *,
                 bgp_cer_cidr: str = None,
                 bgp_ibm_cidr: str = None) -> None:
        """
        Initialize a ProviderGatewayUpdateAttributesUpdatesItemProviderGatewayBGPIPUpdate object.

        :param str bgp_cer_cidr: (optional) BGP customer edge router CIDR is the
               new CIDR (Classless Inter-Domain Routing) value to be updated on customer
               edge router for the DL 2.0 gateway.
               Customer edge IP and IBM IP should be in the same network. Updating
               customer edge router CIDR should be accompanied with IBM CIDR in the
               request. Update customer edge router IP to a valid bgp_cer_cidr and
               bgp_ibm_cidr CIDR, the value must reside in one of "10.254.0.0/16",
               "172.16.0.0/12", "192.168.0.0/16",
               "169.254.0.0/16" or an owned public CIDR.  bgp_cer_cidr and bgp_ibm_cidr
               must have matching network and subnet mask values.
        :param str bgp_ibm_cidr: (optional) BGP IBM CIDR is the new CIDR (Classless
               Inter-Domain Routing) value to be updated on IBM edge router for the DL 2.0
               gateway.
               IBM IP and customer edge IP should be in the same network. Updating IBM
               CIDR should be accompanied with customer edge router CIDR in the request.
               Update IBM CIDR to a valid bgp_cer_cidr and bgp_ibm_cidr CIDR, the value
               must reside in one of "10.254.0.0/16", "172.16.0.0/12", "192.168.0.0/16",
               "169.254.0.0/16" or an owned public CIDR.  bgp_cer_cidr and bgp_ibm_cidr
               must have matching network and subnet mask values.
        """
        # pylint: disable=super-init-not-called
        self.bgp_cer_cidr = bgp_cer_cidr
        self.bgp_ibm_cidr = bgp_ibm_cidr

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

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

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

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

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

class ProviderGatewayUpdateAttributesUpdatesItemProviderGatewaySpeedUpdate(ProviderGatewayUpdateAttributesUpdatesItem):
    """
    gateway speed change.

    :attr int speed_mbps: (optional) New gateway speed in megabits per second.
    """

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

        :param int speed_mbps: (optional) New gateway speed in megabits per second.
        """
        # pylint: disable=super-init-not-called
        self.speed_mbps = speed_mbps

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

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

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

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

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

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

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

class ProviderGatewayUpdateAttributesUpdatesItemProviderGatewayVLAN(ProviderGatewayUpdateAttributesUpdatesItem):
    """
    Update VLAN for this gateway.
    VLAN provided should be in the range 1 to 4094.

    :attr int vlan: (optional) VLAN to be updated for this gateway.
          VLAN provided should be in the range 1 to 4094.
    """

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

        :param int vlan: (optional) VLAN to be updated for this gateway.
               VLAN provided should be in the range 1 to 4094.
        """
        # pylint: disable=super-init-not-called
        self.vlan = vlan

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

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

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        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 ProviderGatewayUpdateAttributesUpdatesItemProviderGatewayVLAN object."""
        return json.dumps(self.to_dict(), indent=2)

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

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